Wednesday, May 27, 2020

Using timer 0 and PortB interrupt on change to make a digital clock

We have already about digital input output, and timer 0 with their interrupt capabilities. Now we combine those stuffs together making a real time adjustable digital clock.

I use PortB interrupt on change to adjust minutes and hours. Timer 0 overflow interrupt makes a precise timing ticks. It create a one millisecond counting and schedule the SSD. SSD made up of four digits. Each digit turns on for 10 milli second period. The overall time of SSD takes about 40 milli seconds.

Using timer 0 and PortB interrupt on change to make a digital clock
Schematic diagram. PortB create an interrupt on change to adjust minutes and hours.
PortC and PortD displays the timing to SSD. The SSD is common anode. We can use
common cathode data with inverting. 

Source code is here.

#include "xc.h"
// PIC16F887 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = OFF
// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF
unsigned int cnt_0=0;
unsigned int cnt_1=0;
unsigned int cnt_minute=0;
unsigned int oneSecond=0;
unsigned int milliCount=0;
unsigned int _minutes=0;
unsigned int _hours=0;
void ssdOut(void){
 static unsigned char dot=0;
 unsigned char ssd[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
 0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
 if(milliCount>=1000){
        oneSecond+=1;
        milliCount=0;
        dot^=0x80;      
 }
 if(oneSecond>=60){
     oneSecond=0;
     _minutes+=1;
 }
 if(_minutes>=60){
     _minutes=0;
     _hours+=1;
     if(_hours>=24) _hours=0;
 }
 switch (cnt_1){
     //Digit 4 1000's
     case 1:
        PORTD=0x00;
        PORTC=~ssd[_hours/10]^dot;
        PORTD=0x08;
        break;
     //Digit 3 100's
     case 2:
         PORTD=0x00;
         PORTC=~ssd[_hours%10]^dot;
         PORTD=0x04;
         break;
     //Digit 2 10's
     case 3:
         PORTD=0x00;
         PORTC=~ssd[_minutes/10]^dot;
         PORTD=0x02;
         break;
     //Digit 1 1's
     case 4:
         PORTD=0x00;
         PORTC=~ssd[_minutes%10]^dot;
         PORTD=0x01;
         break;
     case 5:
         cnt_1=0;
         break;
 }
}
void portSetUp(void){
    /*SSD display port setup*/
    PORTC=0x00;
    PORTD=0x00;
    TRISC=0x00;
    TRISD=0x00;
    /*PortB digital I/O and
     interrupt setup*/
    PORTB=0x00;
    TRISB=0x0F;
    ANSELH=0x00;
    nRBPU=0;
    WPUB=0x0F;
    IOCB=0x0F;
    RBIE=1;
    RBIF=0;
}
void timerSetup(void){
    T0CS=0;
    PSA=0;
    OPTION_REGbits.PS=0x01;
    T0IE=1;
    GIE=1;
    T0IF=0;
    TMR0=0;
}
void main(){
    portSetUp();
    timerSetup();
    
    while(1){
        ssdOut();
    }
}
void interrupt ISR(void){
    /*Timer 0 Flag*/
    if(T0IF){
        cnt_0+=1;
        /*one milli second tick*/
        milliCount+=1;
        T0IF=0;
    }
    /*IOCB flag*/
    if(RBIF){
        if(RB0==0){
            if(_minutes>0) _minutes-=1;
        }
        if(RB1==0){
            if(_minutes<60) _minutes+=1;
        }
        if(RB2==0){
            if(_hours>0) _hours-=1;
        }
        if(RB3==0){
            if(_hours<24) _hours+=1;
        }
        RBIF=0;
    }
    /*SSD timing*/
    if(cnt_0>10){
        cnt_1+=1;
        cnt_0=0;
    }
}

Simulation screen shot is here.
Using timer 0 and PortB interrupt on change to make a digital clock
A simulation screen shot, displaying an adjusted time while the counter tick is running.

Back to main tutorials page.


No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)