O software começa com as definições necessários para o compilador utilizado (PIC C) e as definições dos pinos aos quais estão conectados os sinais que nos interessam:
- #include <16F676.h>
- #device adc=8
- #use delay(clock=4000000)
- #fuses NOWDT, NOCPD, NOPROTECT
- #fuses INTRC_IO, PUT, BROWNOUT, MCLR
- #define DLY_SR 10 // delay p/ shift register
- #define TAXA_DISP 3 // taxa de varredura dos displays
- #define TAXA_ATL 100 // taxa de atualização dos valores nos displays
- #define TEMPO_LED 600 // tempo que o LED fica aceso
- // Pinos de E/S
- #define SENSOR PIN_A5
- #define LED PIN_A4
- #define SHIFT_DS PIN_A2
- #define SHIFT_ST PIN_C0
- #define SHIFT_SH PIN_C1
- #define SEL_1 PIN_C5
- #define SEL_2 PIN_C4
- #define SEL_3 PIN_C3
- #define SEL_4 PIN_C2
- // Controle do LED
- volatile int16 cntLed;
- // Contador de passagens do imã
- volatile unsigned int16 cntIma = 0;
Uma variável passo controlará a atualização do display:
- 0 indica que o display deve ser refrescado com o valor em segto
- 1 indica que um novo valor deve ser montado em newsegto
- 2 indica que newsegto tem um novo valor que deve ser copiado para segto
- // Controle dos segmentos do display
- // Um byte para cada segmento
- // Bit 7 = segto G, Bit 6 = segto F, .. Bit 1 = segto A
- unsigned int8 segto [4];
- unsigned int8 newsegto [4];
- unsigned int8 passo = 0;
- // Segmentos a serem acesos para cada dígito
- const unsigned int8 digitos[10] =
- {
- 0b01111110, 0b00001100, 0b10110110, 0b10011110, 0b11001100,
- 0b11011010, 0b11111010, 0b00001110, 0b11111110, 0b11011110
- };
- // P R O G R A M A P R I N C I P A L
- void main()
- {
- unsigned int16 aux;
- // Iniciações do hardware
- set_tris_a (0xEB); // A4 e A2 output
- #use fast_io(A)
- set_tris_c (0xC0); // C0 a C5 output
- #use fast_io(C)
- setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
- setup_timer_1(T1_DISABLED);
- setup_comparator(NC_NC);
- setup_vref(FALSE);
- setup_adc(ADC_OFF);
- output_low (LED);
- output_low (SEL_1);
- output_low (SEL_2);
- output_low (SEL_3);
- output_low (SEL_4);
- enable_interrupts(INT_RA5);
- enable_interrupts(INT_RTCC);
- enable_interrupts(GLOBAL);
- for (;;)
- {
- if (passo == 1)
- {
- disable_interrupts(GLOBAL);
- aux = cntIma;
- enable_interrupts(GLOBAL);
- newsegto[0] = digitos [aux / (unsigned int16) 1000];
- newsegto[1] = digitos [(aux/100) % 10];
- newsegto[2] = digitos [(aux/10) % 10];
- newsegto[3] = digitos [aux % 10];
- passo = 2;
- }
- }
- }
- // S E N S O R
- //////////////////////////////////////////////
- // Interrupcao de mudança do sinal
- // Ocorre qdo sensor detecta imã
- //////////////////////////////////////////////
- #int_ra
- void Sensor_ISR ()
- {
- output_high (LED);
- input_a();
- clear_interrupt (INT_RA5);
- cntLed = TEMPO_LED;
- cntIma++;
- if (cntIma > 9999)
- cntIma = 0;
- }
- // T E M P O
- //////////////////////////////////////////////
- // Interrupcao de tempo real
- // Ocorre a cada 256 uSeg
- //////////////////////////////////////////////
- #int_RTCC
- void RTCC_isr()
- {
- static unsigned int8 cont_disp = TAXA_DISP;
- static unsigned int8 cont_atl = TAXA_ATL;
- // Tratamento do LED
- if (cntLed)
- {
- if (--cntLed == 0)
- output_low (LED);
- }
- // Atualização do Display
- if (--cont_atl == 0)
- {
- passo = 1;
- cont_atl = TAXA_ATL;
- }
- if (passo == 2)
- AtlDisp ();
- if (--cont_disp == 0)
- {
- VarreDisp ();
- cont_disp = TAXA_DISP;
- }
- }
- // D I S P L A Y
- static void AtlDisp (void)
- {
- segto[0] = newsegto[0];
- segto[1] = newsegto[1];
- segto[2] = newsegto[2];
- segto[3] = newsegto[3];
- passo = 0;
- }
- static void VarreDisp (void)
- {
- static unsigned int8 disp = 0;
- unsigned int8 i, mask;
- // coloca os valores dos segmentos no registrador
- for (i = 0, mask = 0x80; i < 8; i++)
- {
- if (segto[disp] & mask)
- output_low (SHIFT_DS);
- else
- output_high (SHIFT_DS);
- delay_us (DLY_SR);
- output_high (SHIFT_SH);
- delay_us (DLY_SR);
- output_low (SHIFT_SH);
- delay_us (DLY_SR);
- mask = mask >> 1;
- }
- // seleciona o display atual
- if (disp == 0)
- {
- output_low (SEL_4);
- output_high (SEL_1);
- }
- else if (disp == 1)
- {
- output_low (SEL_1);
- output_high (SEL_2);
- }
- else if (disp == 2)
- {
- output_low (SEL_2);
- output_high (SEL_3);
- }
- else
- {
- output_low (SEL_3);
- output_high (SEL_4);
- }
- // acende os segmentos
- output_high (SHIFT_ST);
- delay_us (DLY_SR);
- output_low (SHIFT_ST);
- // passa para o dígito seguinte
- disp = (disp + 1) & 3;
- }
Vamos fechar esta série no próximo post, adaptando o código para apresentar no display o número de rotações por minuto e usar os outros dois tipos de sensores.
Nenhum comentário:
Postar um comentário