segunda-feira, agosto 31, 2015

Timer para Apresentações - Testes

Montagem concluída, é hora de ver se funciona.

O primeiro teste foi desligar os conectores KK (pois o display compartilha pinos com o conector de programação), conectar um programador e confirmar que o avrdude consegue conversar com o ATtiny.

Nesta foto os conectores KK estão conectado, o display não influi muito no programador

O segundo teste usa um software que aciona os LEDs e buzzer conforme o pressionamento dos botões. No display é apresentado 12:34. O display deu um pouco de trabalho, pois parti do código que eu fiz para o MSP430 e não percebi que lá eu estava enviando primeiro o bit menos significativo e no ATtiny a única opção é enviar primeiro o mais significativo. Percebido isto, foi só inverter os valores enviados ao display. O software ficou assim:
  1. #include <inttypes.h>  
  2. #include <avr/io.h>  
  3. #include <util/delay.h>  
  4.   
  5. // Bits correspondentes aos pinos de E/S  
  6. #define TEC1    _BV(PB0)  
  7. #define TEC2    _BV(PB1)  
  8. #define LED1    _BV(PA0)  
  9. #define LED2    _BV(PA1)  
  10. #define LED3    _BV(PA2)  
  11. #define LED4    _BV(PA3)  
  12. #define BUZZER  _BV(PA7)  
  13.   
  14. // Pinos para comunicação I2C  
  15. #define DDR_USI             DDRA  
  16. #define PORT_USI            PORTA  
  17. #define PIN_USI             PINA  
  18. #define PORT_USI_SDA        PORTA6  
  19. #define PORT_USI_SCL        PORTA4  
  20. #define PIN_USI_SDA         PINA6  
  21. #define PIN_USI_SCL         PINA4  
  22.   
  23. // Endereços dos registradores do TM1637  
  24. #define TM1637_I2C_COMM1    0x02 //0x40  
  25. #define TM1637_I2C_COMM2    0x03 //0xC0  
  26. #define TM1637_I2C_COMM3    0x01 //0x80  
  27.   
  28. // Rotinas para comunicação I2C  
  29. void    I2C_Init        (void);  
  30. void    I2C_Start       (void);  
  31. uint8_t I2C_Write       (uint8_t b);  
  32. void    I2C_Stop        (void);  
  33.   
  34. // Programa Principal  
  35. int main (void)  
  36. {  
  37.     int passo1 = 0;  
  38.     int passo2 = 0;  
  39.       
  40.     // Configura o port A  
  41.     DDRA |= LED1 | LED2 | LED3 | LED4 | BUZZER;  
  42.     PORTA = 0;  
  43.       
  44.     // Configura o port B  
  45.     DDRB &= ~(TEC1 | TEC2);  
  46.     PORTB = TEC1 | TEC2;  
  47.   
  48.     // Inicia I2C  
  49.     I2C_Init();  
  50.       
  51.     // Inicia o TM1637  
  52.     I2C_Start ();  
  53.     I2C_Write (TM1637_I2C_COMM1);  
  54.     I2C_Stop ();  
  55.       
  56.     I2C_Start ();  
  57.     I2C_Write (TM1637_I2C_COMM2);  
  58.     I2C_Write (0x60);  
  59.     I2C_Write (0xDB);  
  60.     I2C_Write (0xF2);  
  61.     I2C_Write (0x66);  
  62.     I2C_Stop ();  
  63.       
  64.     I2C_Start ();  
  65.     I2C_Write (TM1637_I2C_COMM3 | 0xF0);  
  66.     I2C_Stop ();  
  67.       
  68.       
  69.     // Loop infinito  
  70.     for (;;)  
  71.     {  
  72.         if ((PINB & TEC1) == 0)  
  73.         {  
  74.             // Apertou botão 1  
  75.             switch (passo1)  
  76.             {  
  77.                 case 0:     // Acende LED1  
  78.                     PORTA |= LED1;  
  79.                     passo1 = 1;  
  80.                     break;  
  81.                 case 1:     // Apaga LED1, acende LED3  
  82.                     PORTA &= ~LED1;  
  83.                     PORTA |= LED3;  
  84.                     passo1 = 2;  
  85.                     break;  
  86.                 case 2:     // Apaga LED3  
  87.                     PORTA &= ~LED3;  
  88.                     passo1 = 0;  
  89.                     break;  
  90.             }  
  91.             // Dá um bip  
  92.             PORTA |= BUZZER;  
  93.             _delay_ms (300);  
  94.             PORTA &= ~BUZZER;  
  95.             // Espera soltar a tecla  
  96.             while ((PINB & TEC1) == 0)  
  97.                 ;  
  98.             _delay_ms (100);    // debounce  
  99.         }  
  100.         if ((PINB & TEC2) == 0)  
  101.         {  
  102.             // Apertou botão 2  
  103.             switch (passo2)  
  104.             {  
  105.                 case 0:     // Acende LED2  
  106.                     PORTA |= LED2;  
  107.                     passo2 = 1;  
  108.                     break;  
  109.                 case 1:     // Apaga LED2, acende LED4  
  110.                     PORTA &= ~LED2;  
  111.                     PORTA |= LED4;  
  112.                     passo2 = 2;  
  113.                     break;  
  114.                 case 2:     // Apaga LED4  
  115.                     PORTA &= ~LED4;  
  116.                     passo2 = 0;  
  117.                     break;  
  118.             }  
  119.             // Dá um bip  
  120.             PORTA |= BUZZER;  
  121.             _delay_ms (300);  
  122.             PORTA &= ~BUZZER;  
  123.             // Espera soltar a tecla  
  124.             while ((PINB & TEC2) == 0)  
  125.                 ;  
  126.             _delay_ms (100);    // debounce  
  127.         }  
  128.     }  
  129. }  
  130.   
  131. // Inicia a USI no modo I2C  
  132. void I2C_Init ()  
  133. {  
  134.     USIDR =  0xFF;  
  135.     USICR =  _BV(USIWM1) | _BV(USICS1) | _BV(USICLK);   // Sem interrupções  
  136.                                                         // Modo TWI  
  137.     USISR = _BV(USISIF) | _BV(USIOIF) |                 // Limpa flags e zera contador  
  138.             _BV(USIPF) | _BV(USIDC);  
  139.     DDR_USI  |= _BV(PIN_USI_SDA) | _BV(PIN_USI_SCL);    // colocar como saída  
  140.     PORT_USI |= _BV(PIN_USI_SDA) | _BV(PIN_USI_SCL);    // repouso = high (solto)  
  141. }  
  142.   
  143. // Sinaliza Start  
  144. void I2C_Start ()  
  145. {  
  146.     PORT_USI |= _BV(PIN_USI_SCL);               // Solta SCL  
  147.     while ((PIN_USI & _BV(PIN_USI_SCL)) == 0)   // Espera SCL alto  
  148.         ;  
  149.     _delay_us (4);  
  150.     PORT_USI &= ~_BV(PIN_USI_SDA);          // Baixa SDA  
  151.     _delay_us (4);  
  152.     PORT_USI &= ~_BV(PIN_USI_SCL);          // Baixa SCL  
  153.     PORT_USI |= _BV(PIN_USI_SDA);           // Solta SDA  
  154. }  
  155.   
  156. // Envia um uint8_t e lê o ACK ou NAK  
  157. uint8_t I2C_Write (uint8_t b)  
  158. {  
  159.     uint8_t temp;  
  160.       
  161.     PORT_USI &= ~_BV(PIN_USI_SCL);          // Baixa SCL  
  162.     USIDR = b;                              // Coloca dado no shift register  
  163.     USISR = _BV(USISIF) | _BV(USIOIF) |     // Limpa flags e zera contador  
  164.             _BV(USIPF) | _BV(USIDC);  
  165.     do  
  166.     {  
  167.         _delay_us (4);  
  168.         USICR |= _BV(USICLK) | _BV(USITC);          // Pulsa clock p/ cima  
  169.         while ((PIN_USI & _BV(PIN_USI_SCL)) == 0)   // Espera SCL subir  
  170.             ;  
  171.         _delay_us (4);                
  172.         USICR |= _BV(USICLK) | _BV(USITC);          // Pulsa clock p/ baixo  
  173.     } while ((USISR & _BV(USIOIF)) == 0);       // Repete para todos os bits  
  174.   
  175.     _delay_us (4);                  
  176.     USIDR = 0xFF;                            // Solta SDA  
  177.     DDR_USI &= ~_BV(PIN_USI_SDA);            // SDA passa a ser entrada  
  178.     USISR = _BV(USISIF) | _BV(USIOIF) |      // Limpa flags e inicia contador  
  179.             _BV(USIPF) | _BV(USIDC) |        //   para ler 1 bit  
  180.             (0xE<<USICNT0);  
  181.     do  
  182.     {  
  183.         _delay_us (4);  
  184.         USICR |= _BV(USICLK) | _BV(USITC);          // Pulsa clock p/ cima  
  185.         while ((PIN_USI & _BV(PIN_USI_SCL)) == 0)   // Espera SCL subir  
  186.             ;  
  187.         _delay_us(4);                
  188.         USICR |= _BV(USICLK) | _BV(USITC);          // Pulsa clock p/ baixo  
  189.     } while ((USISR & _BV(USIOIF)) == 0);    // Repete para todos os bits  
  190.     temp  = USIDR;                           // Lê a resposta  
  191.     USIDR = 0xFF;                            // Solta SDA  
  192.     DDR_USI |= _BV(PIN_USI_SDA);             // SDA passa a ser saída  
  193.     return temp;  
  194. }  
  195.   
  196. // Sinaliza Stop  
  197. void I2C_Stop ()  
  198. {  
  199.     PORT_USI &= ~_BV(PIN_USI_SDA);          // Baixa SDA  
  200.     PORT_USI |= _BV(PIN_USI_SCL);           // Solta SCL  
  201.     while ((PIN_USI & _BV(PIN_USI_SCL)) == 0)   // Espera SCL alto  
  202.         ;  
  203.     _delay_us (4);  
  204.     PORT_USI |= _BV(PIN_USI_SDA);           // Solta SDA  
  205.     _delay_us (4);  
  206. }  
O vídeo abaixo mostra o teste em uso, sofri um pouco com os botões.

 
Finalizada a montagem e os testes, é hora de fazer o software definitivo. Isto fica para o próximo post.

Nenhum comentário: