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.

1 second Interrupt from 8051?

Status
Not open for further replies.

UroBoros

Advanced Member level 2
Joined
May 5, 2004
Messages
642
Helped
19
Reputation
38
Reaction score
8
Trophy points
1,298
Location
Cochin - India
Activity points
6,463
Hai
Which is the suitable and available crystal frequency and timer mode combination so that I can get an exact one second interupt on 89S51?
Thanks in advance
thanks IANP for the clue.
But in that case will I loose the accuracy?
With 12Mhz I cant count upto 1second using 16 bit timer directly.
But if i use that *1000 method the timing will not be precise no?
Picstudent
 

Look, I am not going to give you ready solution. If you are a student then the best way is to analize this problem is to find solution by yourself.
But, here are some hints:
Get yourself a data sheet on the 51-family base core.
There you will find info no Timer0, Timer1 and (52) Timer2.
Certain modes of these timers allow you to count clock devided by 12.
If you use 12MHz crystal ... input to the timer will be fed with this frequency.
Pre-load values can be selected to, say 1000, so the interrupt caused by this timer will occur every 1ms.
If you do it 1000 times and you have your 1s.
Easy or difficult?
 
  • Like
Reactions: bdatanu

    UroBoros

    Points: 2
    Helpful Answer Positive Rating

    bdatanu

    Points: 2
    Helpful Answer Positive Rating
Picstudent said:
Hai
Which is the suitable and available crystal frequency and timer mode combination so that I can get an exact one second interupt on 89S51?

If you wanna make real-time clock (right?), then any frequency divisible by 12 would be OK. But if you want timer interrupt to be invoked exactly every 1 sec, then you should select quite low-frequency (let say 12000 Hz, if you manage to find something like this), and take care about its precision in different temperature/voltage conditions.

I have attached small example on timer initialization and interrupt in C.
 

    UroBoros

    Points: 2
    Helpful Answer Positive Rating
Ianp is right. Try a 12mhz crystal, because the timer count 1 every 1 machine cycle(wich equals 12 crystal pulses ).
Also visit www.8052.com. There you can find in my opinion the best tutorial
on mc51 family microcontrollers for beginners. It was very helpful for me!
 

    UroBoros

    Points: 2
    Helpful Answer Positive Rating
I was not aware you have added more questions to your primary post.

Within 1s interval you will not loose anythig. Mocro will process data within several µs and will be waiting for new interrup for most of its time.
 

    UroBoros

    Points: 2
    Helpful Answer Positive Rating
In my opinion it takes some tricks to obtain a fixed interval of 1 sec.
Your timer counts up to 65536.OK? This means, at a freq of 12Mhz, 65535Us wich isn't enough.

To create a time window of 1sec use a register, decremented/increment(choose one) each time the counter overflows(655535->0). And prefed this register with a value that multiplied with 65536 equals roughly 1 sec.
You'll need 15.25 fed in this register.Decrement/Increment the reg 15 times and the last time prefed in the timer the 65536-0.25*65356-X.

X is the time (use a debugger to measure exactly) taken between the overflow of the
timer and the comparison of different routines used for jumps and comparison .It will be tens of Us .

If you do sometrhing else in your code(like flipping a led) set as high the priority for the timer interrupt.

You won't need any code for help. If you figure this on your own you will have
no more further problems with timers used to measure time.

I am open for comments!
 
hi, you can not have one second interrupt in your 8051, you should do some more to have an exact 1 second interrupt, you can load your timer in 16 bit mode the hex format of (-50000) and enable it's interrupt, then in every interrupt, you should increment a counter and when your counter recieves 20, you can be sure to have a 1 second timing, but it can nat be so so acurate, because when you recieve an interrupt, you have some push and pops, after that, checking your counter uses some microseconds, but i thing it can not affect your acuracy so much.
 

    UroBoros

    Points: 2
    Helpful Answer Positive Rating
rellutzu said:
To create a time window of 1sec use a register, decremented/increment(choose one) each time the counter overflows(655535->0). And prefed this register with a value that multiplied with 65536 equals roughly 1 sec.
You'll need 15.25 fed in this register.Decrement/Increment the reg 15 times and the last time prefed in the timer the 65536-0.25*65356-X.

X is the time (use a debugger to measure exactly) taken between the overflow of the
timer and the comparison of different routines used for jumps and comparison .It will be tens of Us .

Thanks for the suggessions dear friends.

can you little bit elaborate on loading that register with 15.25 and all.
Also how to count time elapsed during instructions in keil like stopwatch in MPLAB?
Picstudent
 

timer(0,1,2) counts up to 65535, then overflows, triggering it's interrupt.
with a 12mhz crystal that means that 65536 microseconds passed. Divide 1.000.000 microsec to 65536 and you'll get 15.25.
So you have to run the timer 15.25 times to obtain 1sec.
You cannot load this value in a register.

You have attached a sample of working code. The problem : it is assembler.
I did not have the time for C.

I used Franklin software for debugging, it is good. But for assembler only.

Read the attachement for clarifications.

If it gets to hard, drop the hole thing and find a easyer way in C.
Assembler is not fit for this. You need to be pacient and sometimes it's not worth the effort.
 

Picstudent said:
Also how to count time elapsed during instructions in ke*il like stopwatch in MPLAB?

There are two fields in window Registers: states and sec.
Field states shows number of executed cycles (usual commands take 1 cycle;16-bits operations, like long jumps, calls, XDATA access gets 2 cycles) and sec is seconds.
 

    UroBoros

    Points: 2
    Helpful Answer Positive Rating
In this case is one problem. For reload of timer registers (TLx, THx) to do some time. This time will be produce of timming error duration of 1s interval.
Also to have a timming error depending on executing instruction.

Kuka.
 

Hi picstudent,

i guess by now, you would have so many ideas and wondering which is the best. I am not going to add to any of these. But i need to comment on this -

1. To get precise timing, use Assembly. you can still use C, but for the timer initialisation and timer interrupt routine, use assembly.

2. It's a bit difficult to get precise 1 sec, there are some tolerance associated with the crystal. If you intend to use the 1 sec and build up an RTC, then i suggest you let the thing run for let say 6 hours and you should see that it will be slower or faster by a few seconds... The longer you let it run, the more obvious the difference is. Get those RTC ic if RTC is your intention.

3. As for 1 sec in 8051, 12MHz is the way to go. Calculate on the operating cycle time, read up on those 16 bit timer, and use additional counters to count up to 1 sec.

For example, to make this easy, you could learn how to implement a 0.5 seconds interrupt or even 0.1 seconds. After successfully implementing these lower timing, you should get a fair idea of getting a 1 sec. To test the 0.1 sec, you could complement an output pin everytime the interrupt occurs. Use an oscilloscope to read the output pin, the output should be a square wave of a period of 0.2 seconds.

take it step by step.


Hope this helps.

chicken_feet
 

If you use pre-load value of 1000 (or 10000) the interrupt occures every 1ms (or 10ms). In micro world this is ages. Certain calculations cause certain deley, but every second, after counting to 1000 (or 100) the deley will be the same, so there is no error imposed on seconds. This 1ms interrupt times the whole operation: NO ERRORS HERE!!!

And why would you like to overflow timer with no pre-load value (65536)?
 

Ianp, correct me if I wongly understood :

You want to run the timer for 1000 Us(=1ms) preloading it. Ok?
Doing so you'll have to do this for 1000 times. Ok?
How are you going to count 1000, when you only have registers of 8 bits(counting up to 255)? Using DPTR register? Isn't it to much for a project of this amplitude?
 

hi all ;

the esiaest and accurate way is to use timer in MODE 2 .

means you would adjust timer0 to -250 and then run it in automatic load ,
it interrupts every 250uS ( if using 12MH crystal )
then you should use two counters like R0 and R1.

there is no need to use a 16 bit register to count !!!

this way is more accurate than running timer in mode 1.
because it loads the number in TH0 to TL0 automatically after each interrupt.

see this program:
ORG 040H
start :
MOV TMOD,#00000010B ;SETS TIMER0 IN MODE2
MOV IE,#10000010B ; enables timer0 interrupt
MOV TH0,#-250
SETB TR0 ; timer0 starts in free runing mode
AJMP $ ; wait for interrupt or you can add some ....


ORG 00BH
TIMER0 INTERRUPT :
INC R0
CJNE R0,#200,OUT ; 200*20*250uS = 1 second
MOV R0,#0
INC R1
CJNE R1,#20,OUT
MOV R1,#0
ACALL 1s ROUTIN
.
.
OUT:
RETI


this way you can do your display refresh ( if you have used multiplexed 7segments) each 250uS ....
 

hm_fa_da,

you came with a good alternative. But you do not take into consideration the time taken for executing the instruction in the routines. The timer may be automatic reloaded, but time is lost executing instr.

But I guess you provided the easyer way of counting 1 sec for common needs, unless Picstudent doesn't really want to build an atomic clock :)))
 

when instructions are executing , no time for timer IN MODE2 will be lost ,

because after interrupt occures , timer0 reloads with TH0 value ( -250 )
and it counts itself parallel to executing instructions ,

maybe you think that counting will restart after RETI instruction ?

after each interrupt , counting will restart without and dependency of executing instructions.
you can stop timer function , with executing CLR TR0 ,

regards.
 

250µs or 1ms or 10ms, ... any of these options is good, as long as you have enough time to performe other functions between two cosecutive interrupts..


How are you going to count 1000, when you only have registers of 8 bits(counting up to 255)?
Even if this is 8-bit processor, counting to almost as much as you want is not that complicated .. in 250µs the multiplication is 4000 and this can be done in less than 10 lines of code..
 

hm_fa_da,

You were right and I was wrong. Indeed you don't need to care about time lost on executind instructions in routines, as long as the timer stilll counts after entering the ISR. I forgot about that completly and headed in a much complicated procedure.

True is the fact that most of the time the best way is the easyer way!
Best regards!
 

If u need a 1 sec interrupt IanP's method is the best it takes less memory space . The other method suggested might work but why on earth would anyone want take a longer way out when there is a shorter one? unless you are doing many other things on the 89C51 and the registers are not free. Even then????why???
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top