Discussion in "8051 Discussion Forum" started by    DavesGarage    Nov 14, 2009.
Sat Nov 14 2009, 04:39 AM
#1
A system tick is a regular event, much like a heart beat, that can be used for a variety of things like delays, reading and writing I/O at regular intervals, checking for error conditions, etc.

More advanced uses might include things like a cooperative scheduler in a multitasking environment.

Getting your first piece of code running on a new target system is always a challenge, and even the simplest program (flashing an LED) requires a delay function.
Sat Nov 14 2009, 05:07 AM
#2
So, where to start?

Firstly, we make a couple of assumptions about our target system:

The crystal frequency will be 12Mhz, and the processor will be a 12-clock/instruction processor.

so, here is the first part of the software:
//=====================================================================
// simple example software for testing system ticker...                
//=====================================================================
#include "AT89X51.H"


We include a header that has our special function registers defined for us. I'm using the Keil development environment, and this header came with it...

Next, we make a few definitions:
// get high order byte from word
#define High(X) ((unsigned char)((X&0xFF00)>
>
8))
 
// get low order byte from word
#define Low(X)  ((unsigned char)(X&0x00FF))        

// 1 millisecond
#define Msec1   64536
                         
// counter for T1 interrupt
volatile unsigned long Ticker;                  


The first two ( High() and Low() ) are macros. High() returns the uppermost 8-bits from a 16-bit value, and Low() returns the lowermost 8-bits from a 16-bit value.

The next value is Msec1, which stands for the timer value that will result in "1 millisecond" interrupts.

Remember, our clock frequency is 12Mhz, and it takes 12 clocks for a single instruction ( as well as a single timer count to occur ), so this means the timer will increment at a rate of 1Mhz, or every microsecond. Since the timer is a 16-bit timer, it can only count up to 65535 ( 0xFFFF in hexadecimal). The next increment (65536) will roll the count over back to zero. So, 1 millisecond worth of timer counts (1000) subtracted from the roll over amount (65536) is 64536.


Finally, we declare our global ticker value, "Ticker"
Sat Nov 14 2009, 05:13 AM
#3
Next, we define a function to initialize our system ticker interrupt...

//=====================================================================
// init routine for ISR handler...                                    
//=====================================================================
void InitISR()
   {
   Ticker      = 0;
   EA          = 0;
   TH1         = High(Msec1);
   TL1         = Low(Msec1);   // load initial values for timer
   TMOD        = (TMOD & 0x0F) | 0X10; // sets timer1 to Mode 1, a 16-bit non-reload
   ET1         = 1;                    // enable timer 1 interrupt
   TR1         = 1;                    // turns on timer 1
   EA          = 1;                    // enable interrupts
   }


We initialize Ticker to zero, disable interrupts, load the hi order register and low order register of timer 1 with our "1 millisecond" value, and set the mode for the timer as a16-bit non-auto-reload timer. Then we enable the timer, turn on the timer, and re-enable the interrupts.



[ Edited Sat Nov 14 2009, 08:26 PM ]
Sat Nov 14 2009, 05:17 AM
#4
Now we need to define the actual interrupt service routine...

//=====================================================================
// Programmable Timer 1 Interrupt Service Routine                      
//=====================================================================
void ProgrammableTimer1_ISR() interrupt 3 using 1
   {
   TH1 = High(Msec1);  // Reset the clock for next interrupt
   TL1 = Low(Msec1);
   Ticker++;                  // bump ticker count...
   }


Since this routine is being executed EVERY millisecond, all it needs to do is reload the timer, and increment the Ticker value...

The routine is identified as"interrupt 3", which is the proper interrupt for timer 1, and is defined as using register set 1. For more information on register sets, you can read the "8052 bible" documents, listed at the end of this thread.


[ Edited Sat Nov 14 2009, 08:27 PM ]
Sat Nov 14 2009, 05:20 AM
#5
We're almost done now...

We need a delay function...

//=====================================================================
// delay routine...                                                    
//=====================================================================
void Delay( unsigned int NumMillisecs )
   {
   unsigned long DelayTickValue;

   DelayTickValue = Ticker + NumMillisecs;
   while( Ticker < DelayTickValue );
   }


All this routine does is take the passed argument (which is how many milliseconds you want to delay), add it to the system ticker value, and then wait for the ticker to increment it's way past the target value. Since the ticker increments every millisecond, all we have to do is wait for it...
Sat Nov 14 2009, 05:26 AM
#6
Finally, we need the main() function. I've written a simple main() that will utilize our initialization function and our delay function, and it will toggle a bit. If this bit happened to be connected to an LED drive circuit, the LED would blink ON and OFF twice per second...

//=====================================================================
// main function to test ISR above...                                  
//=====================================================================
void main()
   {
   InitISR();

   while(1)
      {
      P3_0 = 1;
      Delay(250);   // wait for 250 milliseconds
      P3_0 = 0;
      Delay(250);   // wait for 250 milliseconds
      }
   }


This concludes my cursory example of how to implement a system ticker on a typical 8052...

I hope this helps
Sat Nov 14 2009, 05:37 AM
#7
Here are the links to the "8052 bible":

http://www.nxp.com/acrobat_download/various/80C51_FAM_ARCH_1.pdf
http://www.nxp.com/acrobat_download/various/80C51_FAM_PROG_GUIDE_1.pdf
http://www.nxp.com/acrobat_download/various/80C51_FAM_HARDWARE_1.pdf
Fri Nov 20 2009, 07:17 AM
#8
I added a simple function to wait for the next tick, and consolidated all of the above into one file. Here it is:

//=====================================================================
// simple example software for testing system ticker...                
//=====================================================================
#include "AT89X51.H"

typedef unsigned long ULONG;
typedef unsigned int  WORD;
typedef unsigned char BYTE;

// get high order byte from word
#define High(X) ((BYTE)((X&0xFF00)>
>
8))
 
// get low order byte from word
#define Low(X)  ((BYTE)(X&0x00FF))        

// 1 millisecond
#define Msec1   64536
                         
// counter for T1 interrupt
volatile ULONG Ticker;                  

//=====================================================================
// init routine for ISR handler...                                    
//=====================================================================
void InitISR()
   {
   Ticker      = 0;
   EA          = 0;
   TH1         = High(Msec1);
   TL1         = Low(Msec1);   // load initial values for timer
   TMOD        = (TMOD & 0x0F) | 0X10; // sets timer1 to Mode 1, a 16-bit non-reload
   ET1         = 1;                    // enable timer 1 interrupt
   TR1         = 1;                    // turns on timer 1
   EA          = 1;                    // enable interrupts
   }

//=====================================================================
// Programmable Timer 1 Interrupt Service Routine                      
//=====================================================================
void ProgrammableTimer1_ISR() interrupt 3 using 1
   {
   TH1 = High(Msec1);  // Reset the clock for next interrupt
   TL1 = Low(Msec1);
   Ticker++;                  // bump ticker count...
   }


//=====================================================================
// wait for the ticker to increment...                                 
//=====================================================================
void WaitForTicker()
   {
   volatile ULONG DelayTickValue;

   DelayTickValue = Ticker;
   while( Ticker == DelayTickValue );
   }

//=====================================================================
// delay routine...                                                    
//=====================================================================
void Delay( unsigned int NumMillisecs )
   {
   volatile ULONG DelayTickValue;

   DelayTickValue = Ticker + NumMillisecs;
   while( Ticker < DelayTickValue )
      WaitForTicker();
   }

//=====================================================================
// main function to test ISR above...                                  
//=====================================================================
void main()
   {
   InitISR();

   while(1)
      {
      P3_0 = 1;
      Delay(250);   // wait for 250 milliseconds
      P3_0 = 0;
      Delay(250);   // wait for 250 milliseconds
      }
   }


Here is the output from the logic analyzer in Keil's debugger:



 kennedyugo like this.
Thu Dec 24 2009, 02:56 PM
#9
hello sir... i went thr this thread ...its right as u got the proper output...bt can i ask u ma doubt here???????In isr routine why u hav nt used TF=0? Bcz as per ma knowelged when u dnt clear TF then u block any new interrupt since the pin status indicate that interupt is still being serviced.....we hv RETI instruction in assembly to do d same job...i refered c programs from mazidi also,there also i found that they hvnt cleared timer flag.
Why it is so?? i m nt getting it....
Thu Dec 24 2009, 06:38 PM
#10
The TF flag is automatically reset when an interrupt service routine is enabled, and used to respond to the flag. When there is no ISR, the flag must be manually reset.

If you read the sections on interrupt handling in the bible documents, you will discover this fact...

Use this bible: http://www.nxp.com/acrobat_download/various/80C51_FAM_HARDWARE_1.pdf

refer to page 7, and look at the description for the TCON register. Below it, you should read the definition for TF1 and TF0


I hope this helps,


[ Edited Thu Dec 24 2009, 07:53 PM ]

Get Social

Information

Powered by e107 Forum System

Conversation

Tue Jan 22 2019, 06:51 AM
chnlovelyo
writing
ExperimenterUK
Mon Jan 07 2019, 03:31 AM
@REVOCATUS please post in the AVR forum
Mon Dec 24 2018, 09:25 AM
REVOCATUS MATEMU
sorry I mean referee boards for player substitution
Mon Dec 24 2018, 09:24 AM
REVOCATUS MATEMU
hi am.looking how to build referee by using Atmega 328 and its codes
Sat Dec 15 2018, 01:45 PM
Arslan ayoub
Hii ,, can I get the simulation of numeric keypad lock on proteus
ExperimenterUK
Mon Dec 03 2018, 05:17 PM
Please post questions in the forum. The chat box is for chat
Mon Dec 03 2018, 06:43 AM
help!me!
help! I don't understand busy flag!
Sun Dec 02 2018, 08:01 PM
ile
hello
Mon Nov 12 2018, 05:58 AM
Pavan_user
i have seen your replica of I2C programming using AT89C51 but i am unable to understand the "ack_bit" variable usage ...looks like it is always 1...can you elaborate how acknowledgment is working....
bgk3678
Tue Nov 06 2018, 02:36 PM
kindly any one give solution for my problem

Downloads

Comments

garfield0929
Sun Jan 20 2019, 12:48 AM
servprov
Thu Jan 17 2019, 06:44 AM
marcomilazzo
Wed Jan 16 2019, 04:21 PM
sandhyashree
Wed Jan 16 2019, 04:04 PM
SONACHAI1234
Sun Jan 06 2019, 08:14 AM
manan.gulyaani
Tue Jan 01 2019, 07:58 AM
etech
Sun Dec 30 2018, 07:44 PM
NeilC
Sun Dec 23 2018, 07:39 PM

Online

Guests: 59, Members: 0 ...

most ever online: 182184
(Members: , Guests: 182184) on 06 Aug 2010: 05:37 AM

Members: 38039
Newest member: garfield0929
Forum Activity
ExperimenterUK Avatar
Posted By ExperimenterUK
Sun Jan 06 2019, 10:37 PM
Which 8051 chip are you using ?
SONACHAI1234 Avatar
Posted By SONACHAI1234
Sun Jan 06 2019, 08:21 AM
Hi,By mistakenly i burn rx program in my 8051 micr...
ExperimenterUK Avatar
Posted By ExperimenterUK
Wed Dec 19 2018, 06:27 PM
Nobody knows?sifirsekizThe problem is that you are...
sifirsekiz Avatar
Posted By sifirsekiz
Wed Dec 19 2018, 12:15 PM
sifirsekiz Avatar
Posted By sifirsekiz
Sun Dec 16 2018, 11:13 PM
Guys pleaseeeee :((
sifirsekiz Avatar
Posted By sifirsekiz
Sat Dec 15 2018, 07:09 PM
HiThe pulse-sensor-amped has an analogue output.Th...
ExperimenterUK Avatar
Posted By ExperimenterUK
Sat Dec 15 2018, 07:01 PM
HiThe pulse-sensor-amped has an analogue output.Th...
sifirsekiz Avatar
Posted By sifirsekiz
Sat Dec 15 2018, 09:02 AM
and ı have pulse sensor one out but anolog use 805...
sifirsekiz Avatar
Posted By sifirsekiz
Sat Dec 15 2018, 08:56 AM
HiMembers can supply code and diagrams if they wan...
ExperimenterUK Avatar
Posted By ExperimenterUK
Fri Dec 14 2018, 11:54 PM
HiMembers can supply code and diagrams if they wan...