Nerdegutta's logo

nerdegutta.no

PIC16F690 - LCD counter - The software

20.05.24

Embedded

New updated version of the Engine Timer



This is a work in progress, and the code is not finished. It need some comments

The code has been slightly change. Now we're counting minutes in total and not divinding them into days:hours:minutes.

#include < xc.h > // CONFIGURATION BITS #pragma config FOSC = INTRCIO // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = ON // MCLR Pin Function Select bit (MCLR pin function is MCLR) #pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled) #pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled) #pragma config BOREN = OFF // Brown-out Reset Selection bits (BOR enabled) #pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode is enabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled) #define _XTAL_FREQ 8000000 // Compiler frequency #define Counter_LED RC4 // Led toggles every second #define LED RC5 // Power on LED #define LCD_RS RA2 // RS PIN for LCD #define LCD_EN RA1 // Enable PIN for LCD #define LCD_DATA PORTC // LCD Port volatile char counter, buffer[3]; // This variables has to be volatile to be changed in the interrup routine // Function to configure Oscillation void osc_init(void) { OSCCONbits.IRCF = 0b111; // 8MHz OSCCONbits.OSTS = 1; // Running from Fosc in config/External clock OSCCONbits.HTS = 1; // Stable OSCCONbits.SCS = 0; // Clock source defined by Fosc return; } // Function to strobe the LCD, "ping" the En-pin int lcd_strobe(void) { LCD_EN = 1; __delay_us(1); LCD_EN = 0; } // Function to write on the LCD void lcd_write(unsigned char c) { __delay_ms(1); LCD_DATA = ((c >>4) & 0x0f); lcd_strobe(); LCD_DATA = (c & 0x0f); lcd_strobe(); } // Function to reset/ clear the LCD void lcd_clear(void) { LCD_RS = 0; lcd_write(0x1); __delay_ms(1); } // Function to write a string to the LCD void lcd_puts(const char *s) { LCD_RS = 1; while(*s) lcd_write(*s++); } // Function to place the cursor on the LCD void lcd_goto(unsigned char pos) { LCD_RS = 0; lcd_write(0x80+pos); } // Function to initialize the LCD void lcd_init(void) { char init_value; init_value = 0x3; LCD_RS = 0; LCD_EN = 0; __delay_ms(15); LCD_DATA = init_value; lcd_strobe(); __delay_ms(10); lcd_strobe(); __delay_ms(10); LCD_DATA = 2; lcd_strobe(); lcd_write(0x0e); // Display on, cursor on, blink off } void short_welcome(void) { lcd_clear(); lcd_goto(0); lcd_puts(" HOUR COUNTER"); lcd_goto(0x29); lcd_puts(" VER 0.1"); __delay_ms(3000); lcd_clear(); } // Function to initialize the timer void timer_init() { TMR1H = TMR1L = 0; // Clear TMR1H & TMR1L T1CONbits.T1CKPS1 = 0; // Prescaler 1:1 T1CONbits.T1CKPS0 = 0; // Prescaler 1:1 PIE1bits.TMR1IE = 1; // TMR1 overflow interrup enable bit T1CONbits.TMR1ON = 1; // Timer 1 on INTCONbits.PEIE = 1; // Enable perepheral interrupt INTCONbits.GIE = 1; // Enable global interrupt } // Function to handle timer1 interrupts // Counter = Fosc/instruction cycle * prescaler * timer1 resolution // Counter = 8Mhz / (4 instructions pr cycle * 1 prescaler value * 2^16 resolution) // Counter = 8000000 / (4 * 1 * (2^16)) // Counter = 30.51 void __interrupt() ISR() { if (PIR1bits.TMR1IF == 1) { // Timer1 overflow interrupt flag counter++; if (counter == 30) { // Check if TMR1 has overflown Counter_LED ^= 1; // Toggle LED // update_time(); // show_time(); // show_total_time(); counter = 0; } PIR1bits.TMR1IF = 0; // Clear the overflow flag } } void main(void) { TRISA = 0b00000000; // TRISA output TRISB = 0b0000; // TRISB output TRISC = 0b00000000; // TRISC output PORTA = 0b00000000; // PORTA low PORTB = 0b0000; // PORTB low PORTC = 0b00000000; // PORTC low ANSEL = 0; // Disable input buffer on ANSEL ANSELH = 0; // Disable input buffer on ANSELH CM1CON0 = 0; // Comparator C1 control register 0, disabled CM2CON0 = 0; // Comparator C2 control register 0, disabled osc_init(); // Initialize the oscillator lcd_init(); // Initialize the LCD lcd_clear(); // Clear the LCD short_welcome(); // Display welcome message LED = 1; // Turn LED on => Power LED timer_init(); // Initialize the timer while (1) { // Nothing to do here... } }


You'll find the circuit here: Link