Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] PIC16F877 RTC Not working

Status
Not open for further replies.

WStevens_sa

Member level 2
Joined
Jan 5, 2011
Messages
47
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
South Africa
Activity points
1,695
Hi all

I wrote the code at the bottom to create a rtc using f877. The inturrupt triggers and sets the seconds minutes and hours. I have outputs RA0 and RA1.
After 60 seconds I want RA0 = 1 and after 2 minutes I want RA1 = 1 however as soon as I simulate using real pic simulator both RA0 and RA1 go on immediately. Can someone please tell me where I have gone wrong.


unsigned int counter = 0 ;
unsigned char seconds = 0, minutes = 0, hours = 0 ;

void interrupt(void) {

if(T0IF_bit == 1) // Check for interrupt flag
{
T0IF_bit=0;
counter++ ;
if(counter > 15625){ // 1 sec 16 Mhz crystal = 16000000 / 4 / 256
counter = 0 ;
seconds++ ;
if(seconds == 60){
seconds = 0 ;
minutes++ ;
if(minutes == 60){
minutes = 0 ;
hours++ ;
if(hours == 24){
hours = 0 ;
}
}
}
}
}
}
void main()
{
TMR0 = 0; //Clear timer 0
T0CS_bit = 0; //use internal clock
T0SE_bit = 0; // on rising edge
PSA_bit = 1; // use prescaler
PS1_bit = 1; // prescaler divides in 256
PS2_bit = 1;

PORTA = 0; /*set RA0-RA5 low */
TRISA = 0; /*set PORTA to output*/
PORTD = 0; /*set RA0-RA5 low */
TRISD = 0; /*set PORTA to output*/

ADCON1 = 7; //Disable ADC
//CMCON = 7; - FOR 16F877A

while(1)
{

if (Seconds = 59) {
RA0_bit=1;
}

if (Minutes = 2) {
RA1_bit=1;
}

}
}


---------- Post added at 09:57 ---------- Previous post was at 09:18 ----------

Okay I found my first mistake

if (Seconds = 59) {
RA0_bit=1;

Must be.

if (Seconds == 59) {
RA0_bit=1;

Same with the minutes.

I am still not sure if this is working as a true RTC. I hope someone can answer me on this.
 

Hi WStevens, first of all I'm learning MCU programming so I could be wrong. Anyway, this is the ISR code I used with the same microprocessor (f877A) to simulate a clock, last year, with an external clock (Xtal=20MHz), prescaler=32, TMR0 (preload time) =100 (it should be 102 but, trying and retrying, I've seen that 100 was the best). It's not very precise but, for learning and simulating a RCT, it's ok. Well, I see that your code is a copy of mine, the one difference I note is I put TOIF=0 almost at code end. Pratically, I close routine (TOIF= 0) after all counting, not before. Try in this way... I'll be waiting for an answer.

void interrupt isr(void)
{

if (T0IF)
{

TMR0=100;

// CLOCK MANAGEMENT
counter++;
if (counter==1000)
{ counter=0;
seconds++;

if (seconds>59)
{ seconds=0;
minutes++;

if (minutes>59)
{ minutes=0;
hours++;

if (hours>23)
{ hours=0;

}

}

}

}



T0IF=0;
}
}
 
Hi I actually figured it out. Here is my code for creating a Real Time clock using PIC16F877 with a 2x16 character LCD using TMR0 with internal clock of 16MHZ. I used the wiring diagram from 4.12 EXAMPLE 10 **broken link removed** for a Pic16F887 wihch has the same pinouts as the PIC16F877.

I hope this helps somebody.

// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

// VARIABLES FOR LCD

char* txt1;
int count;
int shiftcount=0;
int tic = 0;
int msec=0;

// INTERRUPT VARIABLES
unsigned int counter = 0 ;
unsigned int seconds = 0, minutes = 0, hours = 0, days = 0;
char* weekdays[7] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};

// INTERRUPT
void interrupt(void) {

if(T0IF_bit == 1){ // Check for interrupt flag

T0IF_bit=0; //Reset flag
counter++ ;
if(counter > 15625){ // 1 sec 16 Mhz crystal = 16000000 / 4 / 256
counter = 0 ;
seconds++ ;
if(seconds == 60){
seconds = 0 ;
minutes++ ;
if(minutes == 60){
minutes = 0 ;
hours++ ;
if(hours == 24){
hours = 0 ;
days++;
if (days == 7){
days = 0;
}
}
}
}
}
}
}

void main(){
//LCD
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off

Lcd_out(1,7,":");
Lcd_out(1,10,":");

//TMR0
OPTION_REG = 8;
GIE_bit = 1; //Enable Global Interrupt
T0IF_bit = 0; //Clear interrupt flag
T0IE_bit = 1; //Enable TMR0 interrupt
PEIE_bit = 1; //Peripheral Interrupt Enable bit

PORTA = 0;
TRISA = 0;

// Lcd_Chr(1,1,48+9); // // Only from 0 to 9. Need to use shift registerto

while(1){
//SECONDS
Lcd_Chr(1,12,48+(seconds % 10)); // seconds counter LSB
Lcd_Chr(1,11,48+((seconds /10) % 10)); //Seconds counter MSB

//MINUTES
Lcd_Chr(1,9,48+(minutes % 10)); // minutes counter LSB
Lcd_Chr(1,8,48+((minutes /10) % 10)); //minutes counter MSB

//HOURS
Lcd_Chr(1,6,48+(hours % 10)); // hours counter LSB
Lcd_Chr(1,5,48+((hours /10) % 10)); // hours counter MSB

//DAYS
Lcd_out(1,1,weekdays[days]); // days of the week

}
}
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top