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);
}
}
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);
}
}