nerdegutta.no
PIC16F690 - LCD counter - The software
20.05.24
Embedded
#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... } }