Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* ATmega128: T3 - Utilização de temporizador / contador e respectiva interrupções */
- /* 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. */
- // clock de 16MHz
- // lógica de entradas e saídas é negativa
- // compilação: optmizacao: -O0
- #include <avr/interrupt.h>
- unsigned char the_pointer = 1; // dado: var que contem o valor do dado (1 a 6)
- double the_div = 0; // divisor: var que guarda o valor de seleccao do divisor
- double the_div_old = 0; // divisor_old: var que guarda o valor anterior de seleccao
- double the_div_clone = 0; // copia_divisor: var de trabalho que e decrementada
- // vector que contem a codificacao do display de 7 segmentos
- unsigned char the_display[10] = {0x0C,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
- // rotina de interrupt do CT0
- ISR(TIMER0_COMP_vect) {
- if (the_div == 0) { // se the_div = 0: parado
- the_div_clone++; // incrementa the_div_clone para evitar que na linha seguinte
- } // o valor faça overflow devido a decrementar 0
- the_div_clone--; // decrementa the_div_clone
- if (the_div_clone == 0) { // se the_div_clone = 0
- the_div_clone = the_div; // inicializa o valor do the_div_clone
- the_pointer++; // incrementa o valor do the_pointer
- if (the_pointer > 6) { // verifica se o valor do the_pointer maior que 6
- the_pointer = 1; // se sim: forca the_pointer = 1
- }
- }
- }
- // rotina de inicializacao
- void inic() {
- DDRA = 0xC0; // == 0b11000000 PORTA A, bit 0 a 5 definidos como entradas
- // bits 6 e 7 definidos como saidas, para seleccao do digito 7 seg
- PORTA = 0xC0; // == 0b11000000 desactiva pull-ups nas entradas da porta A e coloca bits 6 e 7 a ON
- DDRC = 0xFF; // == 0b11111111 configura PC como saidas (segmentos do display)
- PORTC = 0xFF; // == 0b11111111 coloca as saidas a 1 (logica negativa)
- TCCR0 = 0x0F; // == 0b00001111 TC0 em modo 2, prescaler = 1024
- // prescaler (bit 0, 1 e 2 - ON)
- // modo 2 (bit 3 - ON, bit 6 - OFF)
- // OC0 disconected (bit 4 e 5 a OFF)
- // resultaado: freq = 200,3205Hz (+/- 5ms)
- OCR0=77; // N = 77 (freq = 200,3205Hz, +/- 5ms)
- TIMSK=0x02|TIMSK; // == 0b00000010 enable da interrupcao de output compare
- // (le var e acresecenta um 1 no bit de output compare)
- SREG=SREG|0x80; // == 0b10000000 activa interrupt geral
- // (le var e acresecenta um "1" no bit 7)
- }
- // rotina principal
- int main(void) {
- inic(); // rotina de inicializacao
- while(1) {
- // freq = 50Hz
- if(PINA == 0xFE) { // == 0b11111110 se switch 1 activo (freq = 50Hz)
- the_div = 4; // se sim: divisor = 4
- }
- // freq = 10Hz
- if(PINA == 0xFD) { // == 0b11111101 se switch 2 activo (freq = 10Hz)
- the_div = 20; // se sim: divisor = 20
- }
- // freq = 0.5Hz
- if(PINA == 0xFB) { // == 0b11111011 se switch 3 activo (freq = 0,5Hz)
- the_div = 400; // se sim: divisor = 400
- }
- // stop
- if(PINA == 0xDF) { // == 0b11011111 se switch 6 (stop) activo
- the_div = 0; // se sim: divisor = 0
- }
- // controlo: verifica alteracao do the_div
- if (the_div != the_div_old) {
- the_div_old = the_div; // se sim: the_div_old = the_div
- the_div_clone = the_div; // se sim: copia valor de the_div para reg de trabalho
- }
- if(the_div != 0) { // se the_div diferente de "parado"
- PORTC = the_display[the_pointer]; // em função do valor do the_pointer, afixa valor do vector respectivo no display
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement