Learn 51 MCU timer from scratch

Publisher:VelvetSoulLatest update time:2013-01-16 Source: 21IC Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

The schematic diagram of the timer circuit based on the microcontroller is shown below:

The first thing we learned when we studied microcontrollers was how to make LEDs flash, which was done using a delay program. Looking back now, this was not very appropriate. Why? Our main program made the light flash, so we couldn't do anything else. Does the microcontroller only work this way? Of course not, we can use a timer to make the light flash.

Example 1: Query method

ORG 0000H

AJMP START

ORG 30H

START:

MOV P1,#0FFH ; Turn off the light

MOV TMOD,#00000001B ;Timer/Counter 0 works in mode 1

MOV TH0,#15H

MOV TL0,#0A0H; the number is 5536

SETB TR0 ;Timer/Counter 0 starts running

LOOP:JBC TF0,NEXT; If TF0 is equal to 1, clear TF0 and go to NEXT

AJMP LOOP; otherwise jump to LOOP and execute

NEXT:CPL P1.0

MOV TH0,#15H

MOV TL0,#9FH; reset the initial value of the timer/counter

AJMP LOOP

END AJMP LOOP

END

Type the program, what do you see? The light is flashing, this is done by the timer, it is no longer the main program loop. Let's analyze the program briefly, why use JBC? TF0 is the overflow flag of timer/counter 0. When the timer overflows, this bit changes from 0 to 1, so by checking this bit, you can know whether the time has expired. After this bit is 1, the flag bit must be cleared to 0 by software, so that the bit will change from 0 to 1 when the next timer expires. Therefore, the JBC instruction is used. This instruction clears the bit to 0 while judging 1 to transfer.

The above program can make the light flash, but the main program can't do anything else except flashing the light! No, that's not right. We can insert some instructions between LOOP:... and AJMP LOOP to do other things, as long as the execution time of these instructions is less than the timing time. Then when we use the software delay program, can't we also use some instructions to replace DJNZ? Yes, but that requires you to accurately calculate the time of the instructions used, and then subtract the corresponding number of DJNZ cycles, which is very inconvenient. Now we only require that the time of the instructions used is less than the timing time, which is obviously too low. Of course, this method is still not good, so we often use the following method to achieve it. [page]

Program 2: Implemented using interrupts

ORG 0000H

AJMP START

ORG 000BH ;Interrupt vector address of timer 0

AJMP TIME0; Jump to the real timer program

ORG 30H

START:

MOV P1,#0FFH ; Turn off the light

MOV TMOD,#00000001B ;Timer/Counter 0 works in mode 1

MOV TH0,#15H

MOV TL0,#0A0H; the number is 5536

SETB EA ; Enable general interrupt

SETB ET0 ; Enable timer/counter 0

SETB TR0 ;Timer/Counter 0 starts running

LOOP: AJMP LOOP; When actually working, you can write any program here

TIME0: ; Timer 0 interrupt handler

PUSH ACC

PUSH PSW; Push PSW and ACC into stack protection

CPL P1.0

MOV TH0,#15H

MOV TL0,#0A0H ; reset timing constant

POP PSW

POP ACC

RETI

END

In the above routine, when the timer time is reached, TF0 changes from 0 to 1, which will trigger an interrupt. The CPU will automatically go to 000B to find the program and execute it. Since there are only 8 bytes of space left for the timer interrupt, it is obviously not enough to write all the interrupt handlers. Therefore, a jump instruction is arranged at 000B to jump to the program that actually handles the interrupt. In this way, the interrupt program can be written anywhere and can be of any length. After entering the timer interrupt, the current status must be saved first. The program only demonstrates the saving of ACC and PSW. In actual work, the values ​​of the units that may change should be pushed into the stack for protection as needed (in this program, no value actually needs to be saved, it is just a demonstration here).

After running the two MCU programs above, we found that the flashing of the light was very fast and could not be distinguished at all. We just felt that the light was shaking visually. Why? We can calculate that the preset number in the timer is 5536, so every 60,000 pulses is the timing time. How long is the time of these 60,000 pulses? Our crystal oscillator is 12M, so it is 60,000 microseconds, that is, 60 milliseconds, so the speed is very fast. If I want to achieve a 1S timing, what should I do? Under the crystal oscillator frequency, the longest timing is 65.536 milliseconds! A routine is given above.

ORG 0000H

AJMP START

ORG 000BH ;Interrupt vector address of timer 0

AJMP TIME0; Jump to the real timer program

ORG 30H

START:

MOV P1,#0FFH ; Turn off the light

MOV 30H,#00H ; software counter pre-clear 0

MOV TMOD,#00000001B ;Timer/Counter 0 works in mode 1

MOV TH0,#3CH

MOV TL0,#0B0H; the number is 15536

SETB EA ; Enable general interrupt

SETB ET0 ; Enable timer/counter 0

SETB TR0 ;Timer/Counter 0 starts running

LOOP: AJMP LOOP; When actually working, you can write any program here

TIME0: ; Timer 0 interrupt handler

PUSH ACC

PUSH PSW; Push PSW and ACC into stack protection

INC 30H

MOV A,30H[page]

CJNE A,#20,T_RET ;Has the value in cell 30H reached 20?

T_L1: CPL P1.0; arrived, invert P10

MOV 30H,#0 ; Clear software counter

T_RET:

MOV TH0,#15H

MOV TL0,#9FH ; Reset timing constant

POP PSW

POP ACC

RETI

END

Let's analyze it by ourselves first to see how it is implemented? The concept of software counter is used here. The idea is to use timer/counter 0 to make a 50 millisecond timer. When the timer is up, P10 is not negated immediately, but the value in the software counter is added by 1. If the software counter reaches 20, P10 is negated and the value in the software counter is cleared. Otherwise, it returns directly. In this way, P10 is negated once every 20 timer interrupts, so the timing time is extended to 20*50, that is, 1000 milliseconds.

This idea is very useful in engineering. Sometimes we need several timers, but there are only 2 in 51. What should we do? In fact, as long as the time of these timers has a certain common divisor, we can use software timer to implement it. For example, I want to realize that the light connected to P10 port presses 1S each time, and the light connected to P11 port flashes every 2S. How to achieve it? Yes, we use two counters. When it counts to 20, it negates P10 and clears it to zero, as shown above. When the other counts to 40, it negates P11 and then clears it to 0. Isn't that enough? The program for this part is as follows

ORG 0000H

AJMP START

ORG 000BH ;Interrupt vector address of timer 0

AJMP TIME0; Jump to the real timer program

ORG 30H

START:

MOV P1,#0FFH ; Turn off the light

MOV 30H,#00H ; software counter pre-clear 0

MOV TMOD,#00000001B ;Timer/Counter 0 works in mode 1

MOV TH0,#3CH

MOV TL0,#0B0H; the number is 15536

SETB EA ; Enable general interrupt

SETB ET0 ; Enable timer/counter 0

SETB TR0 ;Timer/Counter 0 starts running

LOOP: AJMP LOOP; When actually working, you can write any program here

TIME0: ; Timer 0 interrupt handler

PUSH ACC

PUSH PSW; Push PSW and ACC into stack protection

INC 30H

INC 31H ;both counters increase by 1

MOV A,30H

CJNE A,#20,T_NEXT ;Has the value in cell 30H reached 20?

T_L1: CPL P1.0; arrived, invert P10

MOV 30H,#0 ; Clear software counter

T_NEXT:

MOV A,31H

CJNE A,#40,T_RET ;Has the value in cell 31h reached 40?

T_L2:

CPL P1.1

MOV 31H,#0; Arrived, invert P11, clear the counter, return

T_RET:

MOV TH0,#15H

MOV TL0,#9FH ; Reset timing constant

POP PSW

POP ACC

RETI

END

Reference address:Learn 51 MCU timer from scratch

Previous article:AT89S51 watchdog program example
Next article:Causes of 51 MCU serial communication errors

Recommended ReadingLatest update time:2024-11-16 21:54

tiny6410 bare metal programming-----Timer (1)
Clock initialization is a rather tedious process, with a long process, involving a large number of port operations, and a lot of basic knowledge to understand. This article first analyzes the principle of clock initialization, and then explains how to implement the process programmatically. 1. What & Why M
[Microcontroller]
tiny6410 bare metal programming-----Timer (1)
S3C2440 bare metal experiment timer
S3c2440 has 5 16-bit timers. Timers 0, 1, 2, and 3 have pulse width modulation (PWM) functions. Timer 4 has an internal timer without an output pin. Timer 0 has a dead zone generator for high-current devices.   Timers 0 and 1 share an 8-bit prescaler (prescaler), and timers 2, 3, and 4 share another 8-bit prescaler .
[Microcontroller]
NodeMCU Learning (V)--Timer
1. Understand timer-related APIs 2. Case code (1) Application of tmr.alarm() if not tmr.create():alarm(5000, tmr.ALARM_SINGLE, function()   print("hey there") end) then   print("whoopsie") end pin=4 -- 4 is D4, GPIO2 flag=1   timer1 = tmr.create()   gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH)    functi
[Microcontroller]
NodeMCU Learning (V)--Timer
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号