Menu

728x90

468x60

Navbar

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

336x280

Search This Blog

Labels

23K256 (1) 24C16B (2) 25AA010A (2) 8051 (7) 93AA46B (1) ADC (34) Analog Comparator (1) Arduino (16) ARM (13) AT89C52 (7) ATMega32 (58) ATMega644P (27) AVR (87) AVR PCB (2) Bootloader (1) CCS PICC (31) Change Notify Interrupt (CNI) (2) DAC (2) DHT11 (4) Display (133) Distance Sensor (3) ds1307 (10) DS18B20 (5) ds3231 (1) ds3232 (2) dsPIC (5) dsPIC30F1010 (3) dsPIC30F2010 (5) EEPROM (5) Environment Sensor (5) ESP32 (1) esp8266 (1) Graphical LCD (2) I2C (38) ILI9341 (1) Input/Output (76) Interrupt (22) IoT PCB (1) Keil (5) Keypad (16) KS0108 (2) LCD (75) LM35 (3) Master/Slave (2) MAX7221 (1) MCP23017 (8) MCP23S17 (7) MCP4921 (1) MCP4922 (2) Meter (3) MikroC (2) Module PCB (1) Motor (15) MPLABX (73) Nokia 5110 LCD (4) OLED (2) One-Wire (7) Oscillator (8) PCB (10) PCD8544 (3) PCF8574 (10) PIC (108) PIC12F (3) PIC16 (105) PIC16F628A (3) PIC16F630 (2) PIC16F716 (4) PIC16F818 (11) PIC16F818/819 (3) PIC16F84A (16) PIC16F876A (2) PIC16F877A (9) PIC16F88 (2) PIC16F887 (60) PIC18 (19) PIC18F1220 (5) PIC18F2550 (5) PIC18F4550 (12) PICKit2 (1) PICMicro PCB (4) Pin Change Interrupt (1) PWM (12) RTC (12) SBN0064G (1) Sensor (13) SH1106 (3) Shift Register (13) Shift Registers (10) Software TWI (2) SPI (39) ST7735 (1) STM32 (11) STM32 Black Pill (1) STM32 Blue Pill (12) STM32 HAL (5) STM32CubeIDE (13) STM32F103C8T6 (9) STM32F401CCU6 (1) SysTick (4) temperature sensor (13) TFT (1) TG12864A (1) Thermometer (22) Timer/Counter (32) TM1637 (2) twi (10) UART (8) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (96)