DIGITAL CLOCK WITH 7 SEGMENT DISPLAY USING PIC18F45K22

(instructions, reset, WDT, specifications...) PIC17Cxx, PIC18Fxxx

DIGITAL CLOCK WITH 7 SEGMENT DISPLAY USING PIC18F45K22

Postby Ntampata » Fri Jun 28, 2019 11:42 pm

Hi guys, could someone please help me?
I wrote the code bellow, to run a digital clock, but when i simulate in proteus the led only blink and the display only show 00:00, and it never count. I used timer 0 and timer 1 to generate 1 sec of delay

ANy suggestion??
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include <stdbool.h>
#include <xc.h>


/*MAPEAMENTO DE HARDWARE*/
#define digito_unidade PORTBbits.RB0
#define digito_dezenas PORTBbits.RB1
#define digito_centenas PORTBbits.RB2
#define digito_milhares PORTBbits.RB3
#define butt_minutos PORTBbits.RB4
#define butt_horas PORTBbits.RB5


/*PROTOTIPO DAS FUNCOES AUXILIARES*/
int display(int num);
int clock_PIC();

/*VARIAVEIS GLOBAIS*/
char controlador = 0x01;
int unidade, dezenas, centenas, milhares;

char  segundos   = 0x00;
char  minutos    = 0x00;
char  horas      = 0x00;
char  clck_cont  = 0x00;

char flags_min = 0x00;
char flags_hor = 0x00;


void interrupt interrupcao ()
{
   
    if(INTCONbits.TMR0IF)
        {           
            if(!digito_milhares && controlador == 1)
            {
                controlador    = 0x02;
                digito_unidade = 0x00;
                digito_dezenas  = 0x00;
                digito_centenas = 0x00;
                PORTC = 0x00;
                milhares = (horas%100)/10;
                digito_milhares = 0x01;
                PORTC = display(milhares);
            }//end if digito milhares
           
           
            else if(!digito_centenas && controlador == 2)
            {
                controlador    = 0x03;
                digito_unidade = 0x00;
                digito_dezenas  = 0x00;
                digito_milhares = 0x00;
                PORTC = 0x00;
                centenas = horas%10;
                digito_centenas = 0x01;
                PORTC = display(centenas);
            }//end if digito centenas
           
           
            else if(!digito_dezenas && controlador == 3)
            {
                controlador    = 0x04;
                digito_unidade = 0x00;
                digito_centenas = 0x00;
                digito_milhares = 0x00;
                PORTC = 0x00;
                dezenas = (minutos%100)/10;
                digito_dezenas = 0x01;
                PORTC = display(dezenas);
            }//end if digito dezenas
           
           
            else if(!digito_unidade && controlador == 4)
            {
                controlador    = 0x01;
                digito_dezenas  = 0x00;
                digito_centenas = 0x00;
                digito_milhares = 0x00;
                PORTC = 0x00;
                unidade = minutos%10;
                digito_unidade = 0x01;
                PORTC = display(unidade);
            }//end if digito unidade
           
            // clear the TMR0 interrupt flag
            INTCONbits.TMR0IF = 0x00;

        }//end if TMR0IF
   
    if(PIR1bits.TMR1IF)
    {
        LATBbits.LATB7 = ~ LATBbits.LATB7;
       
        clck_cont ++;
       
        if(clck_cont == 0x02)
        {
            clck_cont = 0x00;
            segundos++;
           
        }//end clck_cont
       
        // clear the TMR1 interrupt flag
        PIR1bits.TMR1IF = 0x00;
       
        //TMR1H 11;
        TMR1H = 0x0B;

        //TMR1L 220;
        TMR1L = 0xDC;
       
    }//end TMR1IF
 
}//end interrupcao


void main(void)
{
        /**
    LATx registers
    */

    PORTB = 0x4F;
    PORTC = 0x3F;

    /**
    TRISx registers
    */

    TRISB = 0x70;
    TRISC = 0x80;
    /**
    ANSELx registers
    */
 
    ANSELC = 0x00;
    ANSELB = 0x00;
   
    // SCS FOSC; IRCF 4MHz_HFINTOSC/4; IDLEN disabled;
    OSCCON = 0x50;
    // PRISD enabled; SOSCGO disabled; MFIOSEL disabled;
    OSCCON2 = 0x04;
    // INTSRC disabled; PLLEN disabled; TUN 0;
    OSCTUNE = 0x00;
   
   
    // TMR0H 0;
    TMR0H = 0x00;
    // TMR0L 6;
    TMR0L = 0x06;
    // T0PS 1:16; T08BIT 8-bit; T0SE Increment_hi_lo; T0CS FOSC/4; TMR0ON enabled; PSA assigned;
    T0CON = 0xD3;
 
   
    //T1GSS T1G_pin; TMR1GE disabled; T1GTM disabled; T1GPOL low; T1GGO done; T1GSPM disabled;
    T1GCON = 0x00;

    //TMR1H 11;
    TMR1H = 0x0B;

    //TMR1L 220;
    TMR1L = 0xDC;
   
    // Clearing IF flag before enabling the interrupt.
//    PIR1bits.TMR1IF = 0;
   
    // T1CKPS 1:8; T1OSCEN disabled; T1SYNC do_not_synchronize; TMR1CS FOSC/4; TMR1ON enabled; T1RD16 enabled;
    T1CON = 0x37;
   
    INTCONbits.GIE = 1;     //Habilita a interrupcao global
    PIE1bits.TMR1IE = 1;    //Habilita a interrupcao do timer 1
    INTCONbits.TMR0IE = 1;  //Habilita a interrupcao do timer 0 
    INTCON2bits.nRBPU = 0;  //Habilita o pull up interno do port B

   
    // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
    // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global and Peripheral Interrupts
    // Use the following macros to:

    // Enable the Global Interrupts
    // INTERRUPT_GlobalInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Enable the Peripheral Interrupts
    // INTERRUPT_PeripheralInterruptEnable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();
   
    while (1)
    { 
        clock_PIC();
    }//end while
}//end void




int clock_PIC()
{

    if (segundos > 59)
    {
        segundos = 0x00;
        minutos++;
       
        if(minutos > 59)
        {
            minutos = 0x00;
            horas++;
                                       
                    if (horas > 23)
                    {
                        horas = 0x00;
                   
                    }//end horas
           
        }//end minutos
       
    }//end segundos
   
    if(!butt_minutos) flags_min = 0x01;
    if(!butt_horas) flags_hor = 0x01;
   
    if(butt_minutos && flags_min)
    {
        flags_min = 0x00;
        minutos++;
        if(minutos > 59) minutos = 0x00;
    }
   
    if(butt_horas && flags_hor)
    {
        flags_hor = 0x00;
        horas++;
        if(horas > 23) horas = 0x00;
    }
       
}//end clock_PIC

int display(int num)
{
    int cathode;                               //armazena código BCD

// -- Vetor para o código BCD --
    int SEGMENTO[10] = {0x3F,                  //BCD zero   '0'
                        0x06,                  //BCD um     '1'
                        0x5B,                  //BCD dois   '2'
                        0x4F,                  //BCD três   '3'
                        0x66,                  //BCD quatro '4'
                        0x6D,                  //BCD cinco  '5'
                        0x7D,                  //BCD seis   '6'
                        0x07,                  //BCD sete   '7'
                        0x7F,                  //BCD oito   '8'
                        0x67};                 //BCD nove   '9'

    cathode = SEGMENTO[num];                   //para retornar o cathode

    return(cathode);                           //retorna o número BCD

} //end display
Last edited by ric on Tue Jul 02, 2019 7:46 am, edited 2 times in total.
Reason: Added "code" tags around the code, and moved topic to "16 bit core" forum.
Ntampata
 
Posts: 1
Joined: Thu Jun 27, 2019 7:18 pm

Re: DIGITAL CLOCK WITH 7 SEGMENT DISPLAY USING PIC18F45K22

Postby AussieSusan » Mon Jul 01, 2019 3:42 am

Not sure if I really understand your code (e.g. there are places where you write to PORTC, execute a couple of lines of code and then wrote to PORTC again - all within a few uSec!) but any variable that is updated inside an ISR must be declared 'volatile' so that the compiler will know that the value can be changed at any time.
While writing to a PORT as a whole is not wrong (in this case), the general rule is to read from the PORT, write to the LAT.
If you are only trying this on a simulator then remember that any simulator may have bug of its own. It is normally best to use a real device where possible.
Susan
AussieSusan
Verified identity
 
Posts: 115
Joined: Mon Jun 16, 2014 4:45 am
PIC experience: Experienced Hobbyist

Re: DIGITAL CLOCK WITH 7 SEGMENT DISPLAY USING PIC18F45K22

Postby ric » Tue Jul 02, 2019 7:47 am

and don't use "int" (= signed 16 bit) variables when 8 bits would do (unsigned char). That is horribly inefficient on an 8-bit processor.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 525
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products


Return to 16-Bit Core

Who is online

Users browsing this forum: No registered users and 0 guests