Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 6th July 2009, 02:00 PM   #1
Default Real-time clock in PIC18F4520 and PIC2Plus Demo Board

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

}
noobC is offline  
Old 6th July 2009, 04:23 PM   #2
Default

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)
3v0 is online now  
Old 6th July 2009, 04:35 PM   #3
Default

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.
Wp100 is offline  
Old 7th July 2009, 10:30 AM   #4
Default

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
	}
Another example from that page, it's the same code but only needs a int variable, not a long;
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
	}
Mr RB is offline  
Reply

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



All times are GMT. The time now is 09:06 PM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker