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] have little problem with timr0 in pic 18f458

Status
Not open for further replies.

amrshata

Member level 1
Joined
Aug 9, 2011
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,501
i try to make aprograme that count's 20k pulses using timr0 module
but tmr0h doesn't read any thing just tmr0l read untill 256


void main() {
CMCON = 0x07; // Disable comparators
ADCON1 = 0x0F; // Disable Analog functions
TRISB = 0b00000000; // PORTB All Outputs
TRISA = 0b00010000;
TRISC = 0b00000001;
T0CON = 0b10111000; // TMR1 as 16-bit counter
PWM1_Init(4000);
PWM1_Set_Duty(127);
do{
T0CON.TMR0ON = 1;
TMR0H = 0; //reset the timer
TMR0L = 0;

pwm1_start();
delay_ms(500); //delay 0.5 sec to produce 20k pulses
pwm1_stop(); // stop the pwm
T0CON.TMR0ON = 0;
x=tmr0h*256+tmr0l; //calc. the recevied pulses
}
while(1);
}


and i connected RC2 (pwm source ) with RA4 but TMR0H read nothing any help plzz ?
 

i try to make aprograme that count's 20k pulses using timr0 module
but tmr0h doesn't read any thing just tmr0l read untill 256


Code:
void main() 
{
     CMCON = 0x07;   // Disable comparators
     ADCON1 = 0x0F; // Disable Analog functions
     TRISB = 0b00000000; // PORTB All Outputs
     TRISA = 0b00010000;
     TRISC = 0b00000001;
     T0CON = 0b10111000; // TMR1 as 16-bit counter

     PWM1_Init(4000);
     PWM1_Set_Duty(127);

    do
    {
       T0CON.TMR0ON = 1;
       TMR0H = 0;  //reset the timer
       TMR0L = 0;

       pwm1_start();
       delay_ms(500); //delay 0.5 sec to produce 20k pulses
       pwm1_stop();  // stop the pwm
       T0CON.TMR0ON = 0;
       x=tmr0h*256+tmr0l;  //calc. the recevied pulses

    }while(1);

}

and i connected RC2 (pwm source ) with RA4 but TMR0H read nothing any help plzz ?

I believe your problem is the following:

Reference PIC18FXX8 Data Sheet, pg. 111, Section 11.4 16-Bit Mode Timer Reads and Writes

PIC18FXX8 Data Sheet

11.4 16-Bit Mode Timer Reads and Writes

Timer0 can be set in 16-bit mode by clearing the
T08BIT in T0CON. Registers TMR0H and TMR0L are
used to access the 16-bit timer value.

TMR0H is not the high byte of the timer/counter in
16-bit mode, but is actually a buffered version of the
high byte of Timer0 (refer to Figure 11-1). The high byte
of the Timer0 timer/counter is not directly readable nor
writable. TMR0H is updated with the contents of the
high byte of Timer0 during a read of TMR0L.
This
provides the ability to read all 16 bits of Timer0 without
having to verify that the read of the high and low byte
were valid, due to a rollover between successive reads
of the high and low byte.

A write to the high byte of Timer0 must also take place
through the TMR0H Buffer register. Timer0 high byte is
updated with the contents of the buffered value of
TMR0H when a write occurs to TMR0L. This allows all
16 bits of Timer0 to be updated at once.

I would suggest creating two shadow register variables, say sTMR0H and sTMR0L and read the contents of the actual TMR0H and TMR0L into these registers in the following order:

Code:
sTMR0L = TMR0L;
sTMR0H = TMR0H;

Then use the shadow register variables to calculate your total PWM pulses.

You may also want to initialize the TMR0 with the following:

Code:
T0CON = 0b[COLOR="#FF0000"]0[/COLOR]0111000;

As you later enable the timer with this statement:

Code:
T0CON.TMR0ON = 1;

One other issue is I do not see the variable "x" declared, make sure it is declared as a unsigned 16-bit type, such as unsigned int.

Hope the suggestion help, if you have any further problems post them here.

BigDog
 
mmm that's doesnt work too

from the datasheet it say's
(A write to the high byte of Timer0 must also take place
through the TMR0H Buffer register.)
and they didn't say how to read the content of the high register of tmr0

and i ask if there is another way to replace the tmr0 if that's didn't work
 

Actually, the datasheet states quite clearly you need to read the contents of the TMR0L first and then TMR0H is updated with the high byte of TIMER0.

TMR0H is not the high byte of the timer/counter in
16-bit mode, but is actually a buffered version of the
high byte of Timer0 (refer to Figure 11-1). The high byte
of the Timer0 timer/counter is not directly readable nor
writable. TMR0H is updated with the contents of the
high byte of Timer0 during a read of TMR0L.

However, if you tried me suggestion then obviously that is not the issue.

Tell me, how do you know TMR0H is not increment? As you state,

...but tmr0h doesn't read any thing just tmr0l read untill 256.

Are you checking the contents during debugging or by the result of the following equation:

x=tmr0h*256+tmr0l; //calc. the recevied pulses

How is "x" declared, its declaration is not present in the code you provided?

Is it declared as an UNSIGNED INT? Also you should initialize "x = 0;" at the start of the "do while" loop.

You might try this sequence instead:

x += sTMR0H << 8; or x += (int)sTMR0H << 8;
x += sTMR0L;

Perhaps the compiler is not implicitly casting the byte TMR0H as an integer.

If none of these suggestion solve the problem, please post the current version of your code.

BigDog
 
Last edited:
when i get the code here i get it copy paste but i config x as

unsigned int x,z;

and i know that there is nothing according to

display_NUM(x);
where
char txt[14];
void Display_NUM(double AMR) {
Lcd_Cmd(_LCD_CLEAR);
lcd_out(1,1,"NUMBER= ");
floattostr(AMR,txt);
lcd_out(2,1,txt);
lcd_out(2,11,"K");
delay_ms(1000);
}


and i tried
x += TMR0H << 8;
x += TMR0L;


now and nothing yet thx in advance
 

Are you using a MikroE development board or a circuit of your own design?

I may try and recreate the problem here.

Can you post a current copy of your code in its entirety?

BigDog
 

i saw now a atopic in microchipe talking about this problem and one reply
(( The TMR0H register only becomes available for read after you have read TMR0L. This is so that a 16-bit read occurs without accidental change between the reads. So read TMR0L, the hardware makes TMR0H available for read, then read TMR0H. All should be well. )


so i tried your code
x += TMR0H << 8;
x += TMR0L;

but but tmrol first and it worked :D
now it read the value of pwm the first value is correct then it's keep rising i dont know why
 
Last edited:

Try replacing your section of code with the following:

Before:
PWM1_Init(40000);
PWM1_Set_Duty(127);
x=0;
do{
x=0;
T0CON.TMR0ON = 1;
TMR0L = 0;
TMR0H = 0; //reset the timer
pwm1_start();

After:
PWM1_Init(40000);
PWM1_Set_Duty(127);
// delete x=0; not needed
do{
x=0;
TMR0L = 0;
TMR0H = 0; //reset the timer
T0CON.TMR0ON = 1;
pwm1_start();


Let me know if this solves the problem.

BigDog
 
  • Like
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
:D i solved it finallly :D :D

when trying to write i should write to tmr0h first then tmr0l


like
TMR0H = 0; //reset the timer
TMR0L = 0;


thx for your help
 

Hi guys ,
i want a code of i second delay with PIC18f458
i need c code

- - - Updated - - -

Hi guys ,
i want a code of i second delay with PIC18f458
i need c code
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top