Advertisement
Guest User

AVR Temp über RGB LED

a guest
Apr 19th, 2012
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.98 KB | None | 0 0
  1. #define     F_CPU       3686400
  2. #include <avr/io.h>
  3. #include <avr/interrupt.h>
  4.  
  5. // Temperatursensor
  6. #define     TEMP_ADDR   0x10010001 // Adresse, A1 = A2 = A3 = 0, Lesemodus
  7.  
  8. // TWI
  9. #define     WAIT_TWI()  loop_until_bit_is_set(TWCR, TWINT);
  10. #define     F_SCL       100000
  11. #define     TWI_PRESC   1
  12. #define     TWBR_VAL    (F_CPU / F_SCL - 16) / (2 * TWI_PRESC)
  13.  
  14. #if TWBR_VAL > 0xff
  15. #   error "TWBR ist zu gross, bitte einen anderen TWI-Prescaler setzen"
  16. #elif TWBR_VAL < 0
  17. #   undef TWBRVAL
  18. #   define TWBR_VAL 0
  19. #endif
  20.  
  21. // Ausgänge
  22. #define     RED_ON()        PORTB |= (1 << 0);
  23. #define     GREEN_ON()  PORTB |= (1 << 1);
  24. #define     BLUE_ON()   PORTB |= (1 << 2);
  25. #define     RED_OFF()   PORTB &= ~(1 << 0);
  26. #define     GREEN_OFF() PORTB &= ~(1 << 1);
  27. #define     BLUE_OFF()  PORTB &= ~(1 << 2);
  28.  
  29. volatile uint8_t R = 1, G = 1, B = 1; // RGB-Farbraum global
  30.  
  31. // I2C Ansteuerung
  32. void twi_init (void)
  33. {
  34.     TWBR = TWBR_VAL;
  35. }
  36.  
  37. void twi_start (unsigned char adress)
  38. {
  39.     TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // Start
  40.     WAIT_TWI()
  41.     TWDR = adress;  // Adresse eingeben
  42.     TWCR = (1 << TWINT) | (1 << TWEN); // Senden
  43.     WAIT_TWI()
  44. }
  45.  
  46. void twi_stop (void)
  47. {
  48.     TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); // Stopp
  49. }
  50.  
  51. unsigned char twi_readAck (void) // Empfangen mit ACK
  52. {
  53.     unsigned char data;
  54.    
  55.     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); // Empfangen mit ACK
  56.     WAIT_TWI()
  57.     data = TWDR;
  58.     return data;
  59. }
  60.  
  61. unsigned char twi_readNak (void) // Empfangen mit NAK
  62. {
  63.     unsigned char data;
  64.    
  65.     TWCR = (1 << TWINT) | (1 << TWEN); // Empfangen mit NAK
  66.     WAIT_TWI()
  67.     data = TWDR;
  68.     return data;
  69. }
  70.  
  71. int16_t readLM75 (uint8_t adress)
  72. {
  73.     uint8_t ret, msg;
  74.    
  75.     twi_start(adress);
  76.     msg = twi_readAck();
  77.     ret = msg << 8;
  78.     msg = twi_readNak();
  79.     ret |= msg;
  80.     twi_stop();
  81.    
  82.     return ret;
  83. }
  84.  
  85. // Interrupt Timer 0 (PWM)
  86. ISR (TIMER0_OVF_vect)
  87. {
  88.     static uint8_t pwm;
  89.  
  90.     if (R == pwm)
  91.         RED_OFF()
  92.    
  93.     if (G == pwm)
  94.         GREEN_OFF()
  95.        
  96.     if (B == pwm)
  97.         BLUE_OFF()
  98.    
  99.     pwm++;
  100.     if (pwm == 255) {
  101.         pwm = 0;
  102.         RED_ON()
  103.         GREEN_ON()
  104.         BLUE_ON()
  105.     }
  106. }
  107.  
  108. // Interrupt Timer 1 (Temperatur holen und RGB berechnen)
  109. ISR (TIMER1_OVF_vect)
  110. {
  111.     int16_t lm75_temp;
  112.     int8_t temp = 1;
  113.     uint16_t hue, sat, bri, red_val, green_val, blue_val;
  114.    
  115.     // Temperatur holen
  116.     lm75_temp = readLM75(TEMP_ADDR);
  117.     temp = lm75_temp >> 8;
  118.     lm75_temp >>= 7;
  119.    
  120.     // Temperatur umrechnen in gewünschten Farbwert
  121.     hue = temp * 25;
  122.     sat = 255;
  123.     bri = 255;
  124.    
  125.     // Umrechnung HSB zu RGB
  126.     while (hue > 1529) hue -= 1530;
  127.     while (hue < 0) hue += 1530;
  128.    
  129.     if (hue < 255) {
  130.        red_val = 255;
  131.        green_val = (65280 - sat * (255 - hue)) >> 8;
  132.        blue_val = 255 - sat;
  133.     }
  134.     else if (hue < 510) {
  135.        red_val = (65280 - sat * (hue - 255)) >> 8;
  136.        green_val = 255;
  137.        blue_val = 255 - sat;
  138.     }
  139.     else if (hue < 765) {
  140.        red_val = 255 - sat;
  141.        green_val = 255;
  142.        blue_val = (65280 - sat * (765 - hue)) >> 8;
  143.     }
  144.     else if (hue < 1020) {
  145.        red_val = 255 - sat;
  146.        green_val = (65280 - sat * (hue - 765)) >> 8;
  147.        blue_val = 255;
  148.     }
  149.     else if (hue < 1275) {
  150.        red_val = (65280 - sat * (1275 - hue)) >> 8;
  151.        green_val = 255 - sat;
  152.        blue_val = 255;
  153.     }
  154.     else {
  155.        red_val = 255;
  156.        green_val = 255 - sat;
  157.        blue_val = (65280 - sat * (hue - 1275)) >> 8;
  158.     }
  159.    
  160.     R = ((bri + 1) * red_val) >> 8;
  161.     G = ((bri + 1) * green_val) >> 8;
  162.     B = ((bri + 1) * blue_val) >> 8;
  163. }
  164.  
  165. // Hauptfunktion
  166. int main (void)
  167. {
  168.     // Ausgänge bestimmen
  169.     DDRB = (1 << 0) | (1 << 1) | (1 << 2);
  170.     DDRC = (1 << 3) | (1 << 4); // Two Wire Interface
  171.    
  172.     // 8 bit Timer
  173.     TCCR0 = (1 << CS00); // Prescaler aus
  174.     TIMSK |= (1 << TOIE0); // Overflow Interrupt erlauben
  175.    
  176.     // 16 bit Timer
  177.     TCCR1A &= ~((1 << COM1A1) | (1 << COM1A0)); // Output-Pin nicht ansteuern
  178.     TCCR1A &= ~((1 << WGM10) | (1 << WGM11)); // PWM Modus aus
  179.     TCCR1B |= (1 << CS12) | (1 << CS10); // Prescaler 1024
  180.     TIMSK |= (1 << TOIE1); // Overflow Interrupt erlauben
  181.    
  182.     // TWI Initialisieren
  183.     twi_init();
  184.    
  185.     // Global Interrupts erlauben
  186.     sei();
  187.    
  188.     while (1) {
  189.         // Nichts tun
  190.     }
  191.    
  192.     return 0;
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement