Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic 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.

Register Log in

Timer0 disaster with 16F877A

Status
Not open for further replies.

mym786

Newbie level 3
Joined
Oct 1, 2010
Messages
4
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,300
Hey,

I am using PIC16F877A and MicroC compiler.

I am facing a problem with timer0. The code works fine in the simulation (ISIS proteus). However, when i programmed the microcontroller the timer0 doesn't work.

The code is for Traffic Light Control System.

Code:
int time=1;
int i=0;
sbit Lane1 at PORTB.B7;
sbit Lane2 at PORTB.B6;
sbit Lane3 at PORTB.B5;
sbit Lane4 at PORTB.B4;
sbit clock at PORTB.B3;
sbit Timer_Led at PORTB.B2;


sbit L1_Cong at PORTD.B5;
sbit L2_Cong at PORTD.B4;
sbit L3_Cong at PORTD.B3;
sbit L4_Cong at PORTD.B2;



void Rise();

void main() {
TRISB = 0x00;
PORTB = 0x00;
TRISD.B7 = 0;
TRISD.B6 = 0;
TRISD.B5 = 1;
TRISD.B4 = 1;
TRISD.B3 = 1;
TRISD.B2 = 1;
PORTD.B7 = 0;
PORTD.B6 = 0;
// Timer0 Registers:
// Prescaler=1:256; TMR0 Preset=60; Freq=39.85969Hz; Period=0.025088 s
OPTION_REG.T0CS = 0;// bit 5 TMR0 Clock Source Select bit:0=Internal Clock (CLKO) / 1=Transition on T0CKI pin
OPTION_REG.T0SE = 0;// bit 4 TMR0 Source Edge Select bit: 0=low/high / 1=high/low
OPTION_REG.PSA  = 0;// bit 3 Prescaler Assignment bit: 0=Prescaler is assigned to the Timer0
OPTION_REG.PS2  = 1;// bits 2-0  PS2:PS0: Prescaler Rate Select bits
OPTION_REG.PS1  = 1;
OPTION_REG.PS0  = 1;
TMR0 = 60;  
INTCON.GIE = 1;         // preset for timer register
INTCON.TMR0IE = 1;
INTCON.TMR0IF = 0;
Timer_Led = 0;
clock =0;
Lane1 = 1;
Lane3 = 1;
Lane2 = 0;
Lane4 = 0;
Rise();


while(1)
{

 if(time == 400)
 {
  Lane1=~Lane1;
  Lane2=~Lane2;
  Lane3=~Lane3;
  Lane4=~Lane4;
  Rise();
 }


 }
}

void interrupt()
{
     if(INTCON.TMR0IF)
     {
       INTCON.TMR0IF = 0;
       Timer_Led = !Timer_Led;
       if(++time == 401) time = 1;
       TMR0 = 60;
     }

}

void Rise()
{
     for(i=0; i<5; ++i)
     {
     clock = 1;
     delay_ms(50);
     clock = 0;
     delay_ms(50);
     }
}
 

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
14,372
Helped
4,727
Reputation
9,469
Reaction score
4,496
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
122,633
I have not simulated it but I would guess the problem is that you check for the value 400 in a sequence which is continually rolling from 1 to 400, when you see 400 you jump into a routine that delays for 500mS before returning so the chances are that you will miss the next time 400 is reached. A better method would be to set a flag when you reset the count in the interrupt routine then read it in the 'while' loop. When the flag is found to be set, clear it and then do the Lane stuff.

Brian.
 

Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top