![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
Hi frens, I am trying to set up an alarm clock using PIC18F4520 and PICDEM 2 Plus Demo Board. I have to display the time(hhmmss) in LCD and enable interrupt when the alarm sound or when the user pressed the button. I like to ask how do I go about doing it? I had tried to use software delays in looping but I have trouble displaying the time in real-time and it affect the interrupt where interrupt does not response when I pressed the button. I started by counting every second, then show the number in display but the number is never on display and it will lag the whole system and interrupt will not work also. Second question is that I had included a high priority interrupt using RB0, I like to ask if I am doing the right way of setting interrupt because I think the way I used is not a interrupt. I had include part of my program and will apprepriate any help. Thanks in advance. #include <p18F4520.h> #include <delays.h> #include <stdlib.h> #define RB0 PORTBbits.RB0 //define, in my opinion can do without also #define INT0IF INTCONbits.INT0IF //define, in my opinion can do without also #define Lcd_VEE LATDbits.LATD7 //VEE - LCD Contrast #define Lcd_EN LATDbits.LATD6 //Enable Signal #define Lcd_RW LATDbits.LATD5 //read - write signal #define Lcd_RS LATDbits.LATD4 //register select signal void Lcd_Title (void); void Lcd_Micro (void); void Button (void); void Write_Lcd (unsigned char ,unsigned char ); void DelayFor18TCY (void); void Lcd_Time (void); void Time_sec (void); void init(void); void high_ISR(void); #pragma code high_vector = 0x08 void high_interrupt(void) { _asm goto high_ISR _endasm } unsigned char count; #pragma code #pragma interrupt high_ISR void high_ISR(void) //interrupt subrountine to display LCD and //toggle LED { if (INT0IF==1) { // Check INT0 flag PORTBbits.RB2=1; Lcd_Micro (); Delay10KTCYx(50); PORTBbits.RB2=0; Delay10KTCYx(50); PORTBbits.RB2=1; Delay10KTCYx(50); PORTBbits.RB2=0; INT0IF = 0; // Clear interrupt flag } } void init(void) { //qns 1 ADCON1=0x0F; RCONbits.IPEN=1; TRISB=0b00000001; //only bit 0 and 1 is input the rest all output PORTB=0x01; INTCON2bits.INTEDG0 = 0; INT0IF=0; INTCONbits.INT0IE=1; INTCONbits.GIEH = 1; /* configure LCD pin */ TRISDbits.TRISD7 = 0; // VEE // PICDEM2 PLUS GREEN BOARD TRISDbits.TRISD6 = 0; // EN TRISDbits.TRISD5 = 0; // RW TRISDbits.TRISD4 = 0; // RS TRISDbits.TRISD0 = 0; // DB4 TRISDbits.TRISD1 = 0; // DB5 TRISDbits.TRISD2 = 0; // DB6 TRISDbits.TRISD3 = 0; // DB7 Lcd_VEE = 1; Delay10KTCYx(15); Write_Lcd (0x20,0); //B0010 0000 Write_Lcd (0x28,0); //B0010 1000 Write_Lcd (0x0c,0); //B0000 1100 Write_Lcd (0x01,0); //B0000 0001 Write_Lcd (0x02,0); //B0000 0010 if (!RB0) { //is by setting this a interrupt?? INT0IF=1; } } void main (void) { init(); while(1) { Lcd_Time(); if (!RB0) { INT0IF=1; } } } void Write_Lcd (unsigned char dat,unsigned char opn) { unsigned int delay,tempdata = 0,value =1; tempdata = dat; dat = dat >> 4; LATD = (LATD & 0xF0) | (dat & 0x0F); Lcd_RS = opn; // set RS Lcd_RW = 0; // clear RW - write mode DelayFor18TCY(); Lcd_EN = 1; // set Enable bit DelayFor18TCY(); Lcd_EN = 0; // clear Enable bit LATD = (LATD & 0xF0) | (tempdata & 0x0F); DelayFor18TCY(); Lcd_EN = 1; // set Enable bit DelayFor18TCY(); Lcd_EN = 0; // clear Enable bit Delay1KTCYx(24); // alternate to check busy flag.. if lcd doesnt work properly, inc/dec this delay return; } //end of Write_Lcd void Lcd_Title (void) { unsigned char a[13] = "abcdefghijklm", b[9] = "abcdefghi"; Write_Lcd (0x82,0); for (count = 0; count < 13; count ++) Write_Lcd(a[count],1); Write_Lcd (0xC4,0); for (count = 0; count < 9; count ++) Write_Lcd(b[count],1); return; } //end of Lcd_PPMI_Title /* write ford menu */ void Lcd_Micro (void) { unsigned char a[15] = "abcdefghijklmno", b[6] = "abcdef"; Write_Lcd (0x01,0); Write_Lcd (0x81,0); for (count = 0; count < 14; count ++) Write_Lcd(a[count],1); Write_Lcd (0xC5,0); for (count = 0; count < 5; count ++) Write_Lcd(b[count],1); return; } //end of Lcd_FordMenu /* delay routine */ void DelayFor18TCY(void) { Delay10TCYx(0x2); //delays 20 cycles return; } void Lcd_Time (void) { unsigned int sec,sec1; unsigned char c; unsigned char b[9] = "abcdefghi"; Write_Lcd (0x01,0); Write_Lcd (0x81,0); //pointer to write for (sec=0; sec<59; sec ++) { Delay10KTCYx(0x500); Time_sec (); } Write_Lcd (0xC5,0); //set pointer to 2nd line for (count = 0; count < 8; count ++) Write_Lcd(b[count],1); return; } void Time_sec (void) { unsigned char a[12] = "Time now is "; unsigned char b[4] = " "; unsigned int sec; Write_Lcd (0x01,0); Write_Lcd (0x81,0); //pointer to write for (count = 0; count < 11; count ++) { Write_Lcd (a[count],1); } Write_Lcd (0xC3,0); for (count = 0; count < 6; count ++) { itoa(sec,b); Write_Lcd(b[count],1); } } | |
| |
| | #2 |
|
Use one of the onchip hardware timer to count instead of loops.
__________________ Please post questions to the forums. PM's are for personal communication. BCHS/3v0's Tutorials Junebug USB PIC programmer kit., USB Bit Whacker, The 15 Minute Printed Circuit Board! (+drill time) | |
| |
| | #3 |
|
You can also use a little 32k watch xtal with timer 1. Full details of hardware and software in the timer 1 section of the 4520 datasheet. | |
| |
| | #4 |
|
There is heaps of C source code examples here for generating 1 second periods from any xtal; Zero-error 1 second timing algorithm It's very simple. For example, with a PIC and 4MHz xtal; Code: // C code for a 1 second period with a 1MHz timer (4MHz xtal);
// uses 1 variable; unsigned long bres
// gets here every TMR0 int (every 256 ticks)
bres += 256; // add 256 ticks to bresenham total
if(bres >= 1000000) // if reached 1 second!
{
bres -= 1000000; // subtract 1 second, retain error
do_1sec_event(); // update clock, etc
}
Code: // Optimised C code for a 1 second period with a 1MHz timer (4MHz xtal);
// uses 1 variable; unsigned int bres
// gets here every TMR0 int (every 256 ticks)
bres += 16; // add (256/16) ticks to bresenham total
if(bres >= 62500) // if reached (1000000/16) 1 second!
{
bres -= 62500; // subtract 1 second, retain error
do_1sec_event(); // update clock, etc
}
| |
| |
|
| Tags |
| board, clock, demo, pic, pic2plus, realtime |
| Thread Tools | |
| Display Modes | |
| |
Similar | ||||
| Title | Starter | Forum | Replies | Latest |
| Real Time Clock | premkumar9 | Micro Controllers | 9 | 5th April 2009 12:57 PM |
| Looking for Real Time Clock Pic board to schedule events | crocu | Electronic Projects Design/Ideas/Reviews | 14 | 23rd March 2009 12:11 PM |
| Real Time Clock on LPT | l30 | Electronic Projects Design/Ideas/Reviews | 1 | 5th May 2004 07:50 AM |
| real time clock | finst | Micro Controllers | 4 | 17th January 2004 01:11 AM |
| list of Real Time Clock | thendo | Micro Controllers | 2 | 8th November 2003 06:41 PM |