SHARE
TWEET

LED necklace

Ocelot Mar 1st, 2012 474 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <avr/io.h>
  2. #include <avr/sleep.h>
  3. #include <avr/interrupt.h>
  4. #include <util/delay.h>
  5.  
  6. #define wdt_reset() __asm__ __volatile__ ("wdr")
  7.  
  8. #define _POWRPIN 0
  9. #define _PULLPIN 1
  10. #define _DATAPIN 2
  11. #define _DBUGPIN 3
  12. #define _RANDPIN 4
  13.  
  14. // Адреса ведомых устройств.
  15. // 0, 3, 4, 5 и 6 байты одинаковы для всех: 0x3A, 0x01, 0x00, 0x00, 0x00.
  16. // 1, 2 и 7 байты:
  17. const uint8_t IDs [] [3] __attribute__ ((progmem)) =
  18. {      
  19.         {0x11, 0xE7, 0xF7},
  20.         {0x8A, 0xE0, 0xEF},
  21.         {0x57, 0xEA, 0xDC},
  22.         {0x91, 0xDC, 0xE9},
  23.         {0x75, 0xE1, 0x74},
  24.         {0x56, 0xDE, 0x70},
  25.         {0x93, 0xE9, 0xD1},
  26.         {0x95, 0xDC, 0x35},
  27.         {0x48, 0xE6, 0x82},
  28.         {0xC3, 0xEC, 0x2D}
  29. };
  30.  
  31. void    blink           (uint8_t num, uint8_t color);
  32. void    onewire_reset (void);
  33. void    onewire_tx      (uint8_t data);
  34. // uint8_t onewire_rx   (void);
  35. uint8_t randomize       (void);
  36. uint8_t random          (uint8_t);
  37.  
  38. ISR (WDT_vect)  // Обработчик прерывания по WDT
  39. {;      // NOP
  40. }
  41.  
  42. void main(void) __attribute__((noreturn));
  43.  
  44. void main(void)
  45. {
  46.         uint8_t rand1, rand2, color;
  47.         register uint8_t seed, i;
  48.        
  49.         ACSR |= (1 << ACD);             // отключить аналоговый компаратор
  50.         seed = randomize ();    
  51.         if (!seed)                              // если seed=0, ГПСЧ не запустится
  52.         {
  53.                 seed = 0x42;            // почему 42? Ответ на Главный вопрос ;)
  54.         }
  55.         rand1 = random (seed); 
  56.         rand2 = random (0);
  57.         wdt_reset();
  58.         WDTCR |= (1<<WDCE) | (1<<WDE);
  59.         // Настройка WDT на генерацию прерывания, тактирование CKwd/256K (период ~2 sec)
  60.         WDTCR = (1<<WDTIE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
  61.         set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  62.         sei();
  63.                
  64.         for (;;)
  65.         {
  66.                 sleep_enable ();        // в спячку
  67.                 cli();                          // пробуждение по прерыванию
  68.                 color = rand1 >> 6;
  69.                 PORTB |= (1 << _PULLPIN);       // _PULLPIN - "1"
  70.                 DDRB  |= (1 << _PULLPIN);       // _PULLPIN - out              
  71.                 _delay_us (32);
  72.                 if (PINB & (1 << _DATAPIN))     // проверка на короткое замыкание шины
  73.                 {              
  74.                         switch (rand2 >> 4)     // выбор эффекта
  75.                         {
  76.                                 case 0x01:              // бегущий огонь слева направо ->
  77.                                         i = 0;
  78.                                         do
  79.                                         {
  80.                                                 blink (i, color);
  81.                                         } while (i++ < 9);
  82.                                 break;
  83.                                
  84.                                 case 0x02:              // бегущий огонь справа налево <-
  85.                                         i = 9;
  86.                                         do
  87.                                         {
  88.                                                 blink (i, color);
  89.                                         } while (--i);                                         
  90.                                 break;
  91.                                
  92.                                 case 0x03:              // 3 вспышки
  93.                                         blink ((rand2 & 0x07), color);
  94.                                 case 0x04:              // 2 вспышки
  95.                                         blink (((rand1>>3) & 0x07) + 0x01, color);
  96.                                 case 0x05:              // 1 вспышка
  97.                                         blink ((rand1 & 0x07) + 0x02, color);
  98.                                 break;                         
  99.                                        
  100.                                 default: ;              // отсутствие эффекта
  101.                         }              
  102.                 }
  103.                 DDRB  &= ~(1 << _PULLPIN);      // _PULLPIN - in
  104.                 PORTB &= ~(1 << _PULLPIN);      // _PULLPIN - z-state
  105.                 rand1 = random (0);
  106.                 rand2 = random (0);
  107.                 sei();
  108.         }
  109. }
  110.  
  111. void blink (uint8_t num, uint8_t color)
  112. {
  113.         uint8_t* ptr;
  114.         ptr = (uint8_t*) &(IDs [num][0]);
  115.         register uint8_t i=3;
  116.         onewire_reset ();
  117.         onewire_tx      (0x55);         // match ROM
  118.         onewire_tx      (0x3A);         // addr, byte 0
  119.         onewire_tx      (*ptr++);       // addr, byte 1
  120.         onewire_tx      (*ptr++);       // addr, byte 2
  121.         onewire_tx      (0x01);         // addr, byte 3
  122.         do
  123.         {
  124.                 onewire_tx      (0x00); // addr, byte 4, 5, 6
  125.         } while (--i);
  126.         onewire_tx      (*ptr);         // addr, byte 7
  127.         onewire_tx      (0x5A);         // PIO access write
  128.         onewire_tx      (color);        // switch on
  129.         onewire_tx      (~color);       // подтверждение
  130.        
  131.         PORTB |= (1 << _POWRPIN);       // _POWRPIN - "1"
  132.         DDRB  |= (1 << _POWRPIN);       // _POWRPIN - out (pull up)
  133.        
  134.         _delay_ms (100);
  135.        
  136.         DDRB  &= ~(1 << _POWRPIN);      // _POWRPIN - in
  137.         PORTB &= ~(1 << _POWRPIN);      // _POWRPIN - z-state
  138.  
  139.         onewire_reset ();
  140.         onewire_tx      (0xA5);         // Resume ROM
  141.         onewire_tx      (0x5A);         // PIO access write
  142.         onewire_tx      (0x00);         // switch off
  143.         onewire_tx      (0xFF);         // подтверждение ~0x00
  144. }
  145.  
  146. void onewire_reset (void)
  147. {
  148.         PORTB &= ~(1 << _DATAPIN);      // _DATAPIN - "0"
  149.         DDRB  |= (1 << _DATAPIN);       // _DATAPIN - out (pull down)
  150.         _delay_us (700);
  151.         DDRB  &= ~(1 << _DATAPIN);      // _DATAPIN - in (tri-state)
  152.         _delay_us (500);
  153. }
  154.  
  155. void onewire_tx (uint8_t data)
  156. {
  157.         register uint8_t i=8;
  158.         do
  159.         {
  160.                 if (data & 0x80)
  161.                 {               // one
  162.                         DDRB  |= (1 << _DATAPIN);       // _DATAPIN - pull down
  163.                         _delay_us (6);
  164.                         DDRB  &= ~(1 << _DATAPIN);      // _DATAPIN - tri-state
  165.                         _delay_us (64);
  166.                 }
  167.                 else
  168.                 {               // zero
  169.                         DDRB  |= (1 << _DATAPIN);       // _DATAPIN - pull down
  170.                         _delay_us (60);
  171.                         DDRB  &= ~(1 << _DATAPIN);      // _DATAPIN - tri-state
  172.                         _delay_us (10);
  173.                 }
  174.                 data <<= 1;
  175.         }
  176.         while (--i);
  177. }
  178.  
  179. /*
  180. uint8_t onewire_rx (void)
  181. {
  182.         uint8_t result = 0x00;
  183.         register uint8_t i=8;
  184.         do
  185.         {
  186.                 result <<= 1;
  187.                 DDRB  |= (1 << _DATAPIN);       // _DATAPIN - pull down
  188.                 _delay_us (6);
  189.                 DDRB  &= ~(1 << _DATAPIN);      // _DATAPIN - tri-state
  190.                 _delay_us (9);
  191.                 if (PINB & (1 << _DATAPIN))
  192.                 {
  193.                         result |= 0x01;
  194.                 }
  195.                 _delay_us (55);
  196.         }
  197.         while (--i);
  198.         return result;
  199. }
  200. */
  201.  
  202. uint8_t randomize       (void)
  203. {
  204.         cli();
  205.         TCCR0A = 0x00;
  206.         TCCR0B = (1 << CS00);   // запуск таймера T0, тактирование CK/1
  207.         wdt_reset();
  208.         WDTCR |= (1<<WDCE) | (1<<WDE);
  209.         WDTCR = (1<<WDTIE);             // настройка WDT на прерывание, тактирование CKwd/2K
  210.         set_sleep_mode (SLEEP_MODE_IDLE);
  211.         sei();
  212.         sleep_enable ();        // в спячку
  213.         cli();                          // пробуждение по прерыванию    
  214.         WDTCR |= (1<<WDCE) | (1<<WDE);
  215.         WDTCR = 0x00;
  216.         TCCR0B = 0x00;          // остановить таймер
  217.         return TCNT0;
  218. }
  219.  
  220.  
  221. uint8_t random  (uint8_t seed)
  222. {
  223.         // 15 bit linear feedback shift register
  224.         static uint16_t lfsr;
  225.         uint16_t bit;
  226.         uint8_t result = 0x00;
  227.         if (seed)
  228.         {       // инициализация
  229.                 lfsr = seed | ~(seed << 8);    
  230.         }
  231.         register uint8_t i=8;
  232.         do
  233.         {
  234.                 result <<= 1;
  235.                 // характеристический полином: x^15 + x^14 + 1
  236.                 bit  = ((lfsr >> 1) ^ (lfsr >> 2)) & 0x0001;
  237.                 lfsr =  (lfsr >> 1) | (bit << 14);
  238.                 result |= bit;
  239.         }
  240.         while (--i);   
  241.         return result;
  242. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top