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

DragonDad
Wed May 29 2019, 12:17 PM
Hi. Who is online?
Tue May 21 2019, 09:53 PM
Jayson Contreras
Hello
Xkalebar
Mon May 06 2019, 06:21 AM
Please provide me the code for gsm based sms controlled notice board
ExperimenterUK
Mon Apr 22 2019, 08:07 PM
@hassan malik post your problem in the "General help Guidance and Discussion" forum
Mon Apr 22 2019, 02:21 PM
RAJESH MAPARi
please send me code to interface atmega32 with 24c1024 serial eeprom
Mon Apr 22 2019, 10:48 AM
hassan malik
hello sir i installed proteus 7.8 professional on window 7 ultimate and window 10 but there would be same errors onn both windows. the error is bad license key.please any one help me
Mon Apr 22 2019, 10:47 AM
hassan malik
hello sir i installed proteus 7.8 professional on window 7 ultimate and window 10 but there would be same errors onn both windows. the error is bad license key.
ExperimenterUK
Sun Apr 14 2019, 03:14 PM
@deshrar. Please post your question in 8051 forum
Sun Apr 14 2019, 04:58 AM
deshraj
hallo mam.. i have downloded gsm notice board code its running fine on lcd but how so send msg to the module . i mean format of password and msg.. thank you
kevinharsha
Thu Apr 11 2019, 01:53 PM
Can i see the circuit diagram for the music tone library 8051 project?

Downloads

Comments

DragonDad
Tue May 21 2019, 02:50 PM
dhiyamtech
Thu May 09 2019, 10:20 AM
harsha.reddy
Fri May 03 2019, 09:02 AM
soumen1963
Fri May 03 2019, 06:01 AM
Vasily
Mon Apr 29 2019, 04:03 AM
Xkalebar
Sun Apr 28 2019, 08:59 AM
obibikwe
Fri Apr 19 2019, 05:55 PM
gigyani
Thu Apr 18 2019, 01:43 AM

Online

Guests: 49, Members: 0 ...

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

Members: 38066
Newest member: DragonDad
Forum Activity
Ansh12 Avatar
Posted By Ansh12
Sun Apr 28 2019, 02:15 PM
I made a minor change, it works in Proteus.Try the...
ExperimenterUK Avatar
Posted By ExperimenterUK
Thu Apr 25 2019, 08:20 PM
I made a minor change, it works in Proteus.Try the...
gigyani Avatar
Posted By gigyani
Thu Apr 25 2019, 01:17 AM
when i add cufirst.hex its not working.after 2-3 s...
ExperimenterUK Avatar
Posted By ExperimenterUK
Wed Apr 24 2019, 12:29 AM
http://www.8051projects.net/download-d205-electron...
gigyani Avatar
Posted By gigyani
Tue Apr 23 2019, 09:22 PM
How to enter the electronic voting machine into vo...
Ansh12 Avatar
Posted By Ansh12
Mon Apr 22 2019, 09:12 AM
Then flash the led when you get any input on B0.Le...
ExperimenterUK Avatar
Posted By ExperimenterUK
Fri Apr 19 2019, 05:35 PM
The full error is control_unit.asm(1294): error A4...
gigyani Avatar
Posted By gigyani
Thu Apr 18 2019, 10:09 PM
I'm using keil uvision5. attached is the rar file ...
ExperimenterUK Avatar
Posted By ExperimenterUK
Thu Apr 18 2019, 04:58 PM
Please zip your full code and post it.Which assemb...
gigyani Avatar
Posted By gigyani
Thu Apr 18 2019, 02:01 AM
STATREAD:MOV A, #WTCMD ;LOAD WRITE CO...