Advertisement
paulogp

ATmega128: T3 - Utilização de temp / cont e respectiva inter

Jul 13th, 2011
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.73 KB | None | 0 0
  1. /* ATmega128: T3 - Utilização de temporizador / contador e respectiva interrupções */
  2.  
  3. /* Utilizando um dos displays de 7 segmentos, prentende-se simular o funcionamento de um dado. Sempre que é accionado um dos switches S1, S2 ou S3, os valor do dado (1 a 6) devem mudar sequencialmente. A activação do switch OFF deve fazer parar o dado ficando visível o último valor simulado. */
  4.  
  5.  
  6. // clock de 16MHz
  7. // lógica de entradas e saídas é negativa
  8. // compilação: optmizacao: -O0
  9.  
  10. #include <avr/interrupt.h>
  11.  
  12. unsigned char the_pointer = 1;      // dado: var que contem o valor do dado (1 a 6)
  13. double the_div = 0;                 // divisor: var que guarda o valor de seleccao do divisor
  14. double the_div_old = 0;             // divisor_old: var que guarda o valor anterior de seleccao
  15. double the_div_clone = 0;           // copia_divisor: var de trabalho que e decrementada
  16.  
  17. // vector que contem a codificacao do display de 7 segmentos
  18. unsigned char the_display[10] = {0x0C,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
  19.  
  20.  
  21.  
  22. // rotina de interrupt do CT0
  23. ISR(TIMER0_COMP_vect) {
  24.     if (the_div == 0) {             // se the_div = 0: parado
  25.         the_div_clone++;            // incrementa the_div_clone para evitar que na linha seguinte
  26.     }                               // o valor faça overflow devido a decrementar 0
  27.  
  28.     the_div_clone--;                // decrementa the_div_clone
  29.  
  30.     if (the_div_clone == 0) {       // se the_div_clone = 0
  31.         the_div_clone = the_div;    // inicializa o valor do the_div_clone   
  32.  
  33.         the_pointer++;              // incrementa o valor do the_pointer
  34.  
  35.         if (the_pointer > 6) {      // verifica se o valor do the_pointer maior que 6
  36.             the_pointer = 1;        // se sim: forca the_pointer = 1
  37.         }
  38.     }
  39. }
  40.  
  41. // rotina de inicializacao
  42. void inic() {  
  43.     DDRA = 0xC0;                    // == 0b11000000 PORTA A, bit 0 a 5 definidos como entradas
  44.                                     // bits 6 e 7 definidos como saidas, para seleccao do digito 7 seg
  45.     PORTA = 0xC0;                   // == 0b11000000 desactiva pull-ups nas entradas da porta A e coloca bits 6 e 7 a ON
  46.  
  47.     DDRC = 0xFF;                    // == 0b11111111 configura PC como saidas (segmentos do display)
  48.     PORTC = 0xFF;                   // == 0b11111111 coloca as saidas a 1 (logica negativa)
  49.  
  50.     TCCR0 = 0x0F;                   // == 0b00001111 TC0 em modo 2, prescaler = 1024
  51.                                     // prescaler (bit 0, 1 e 2 - ON)
  52.                                     // modo 2 (bit 3 - ON, bit 6 - OFF)
  53.                                     // OC0 disconected (bit 4 e 5 a OFF)   
  54.                                     // resultaado: freq = 200,3205Hz (+/- 5ms)
  55.  
  56.     OCR0=77;                        // N = 77 (freq = 200,3205Hz, +/- 5ms)
  57.  
  58.     TIMSK=0x02|TIMSK;               // == 0b00000010 enable da interrupcao de output compare
  59.                                     // (le var e acresecenta um 1 no bit de output compare)
  60.  
  61.     SREG=SREG|0x80;                 // == 0b10000000 activa interrupt geral
  62.                                     // (le var e acresecenta um "1" no bit 7)
  63. }
  64.  
  65. // rotina principal
  66. int main(void) {
  67.     inic();                         // rotina de inicializacao
  68.  
  69.     while(1) {
  70.         // freq = 50Hz
  71.         if(PINA == 0xFE) {          // == 0b11111110 se switch 1 activo (freq = 50Hz)
  72.             the_div = 4;            // se sim: divisor = 4
  73.         }
  74.  
  75.         // freq = 10Hz
  76.         if(PINA == 0xFD) {          // == 0b11111101 se switch 2 activo (freq = 10Hz)
  77.             the_div = 20;           // se sim: divisor = 20
  78.         }
  79.  
  80.         // freq = 0.5Hz
  81.         if(PINA == 0xFB) {          // == 0b11111011 se switch 3 activo (freq = 0,5Hz)
  82.             the_div = 400;          // se sim: divisor = 400
  83.         }
  84.  
  85.         // stop
  86.         if(PINA == 0xDF) {          // == 0b11011111 se switch 6 (stop) activo
  87.             the_div = 0;            // se sim: divisor = 0
  88.         }
  89.  
  90.         // controlo: verifica alteracao do the_div
  91.         if (the_div != the_div_old) {
  92.             the_div_old = the_div;      // se sim: the_div_old = the_div
  93.             the_div_clone = the_div;    // se sim: copia valor de the_div para reg de trabalho
  94.         }
  95.  
  96.         if(the_div != 0) {              // se the_div diferente de "parado"
  97.             PORTC = the_display[the_pointer]; // em função do valor do the_pointer, afixa valor do vector respectivo no display
  98.         }
  99.     }
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement