Microcontroller Tutorial 9 Timer Experiment 1

Publisher:BlissfulSunriseLatest update time:2018-01-03 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Use the timer to achieve the flashing of the light.
When we were learning the microcontroller , the first example we learned was the flashing of the light. That was done with a delay program. Now looking back, this is not very appropriate. Why? Our main program has made the light flash, so we can't do other things. Is the microcontroller only able to work in this way? Of course not. We can use the timer to achieve the flashing function of the light.
  Example 1: Query mode
   ORG 0000H
   AJMP START
   ORG 30H
   START:
   MOV P1,#0FFH ; Turn off all lights
   MOV TMOD,#00000001B ; Timer/Counter 0 works in mode 1
   MOV TH0,#15H
   MOV TL0,#0A0H ; That is, the number 5536
   SETB TR0 ; Timer/Counter 0 starts running
   LOOP:JBC TF0,NEXT ; If TF0 is equal to 1, clear TF0 and jump to NEXT
   AJMP LOOP ; Otherwise jump to LOOP and run
   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 loop of the main program. Simply analyze the program, why use JBC? TF0 is the overflow flag of timer/counter 0. When the timer overflows, the flag changes from 0 to 1. So by checking the flag, you can know whether the time has expired. When the flag is 1, the flag should be cleared to 0 by software, so that the flag will change from 0 to 1 when the next timer expires. So the JBC instruction is used. The flag is cleared to 0 when the flag is judged as 1 and transferred.
  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 instructions 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 it only requires 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.
  Program 2: Use interrupt to implement
   ORG 0000H
   AJMP START
   ORG 000BH ; Timer 0 interrupt vector address
   AJMP TIME0 ; Jump to the real timer program
   ORG 30H
   START:
   MOV P1,#0FFH ; Turn off all lights
   MOV TMOD,#00000001B ; Timer/Counter 0 works in mode 1
   MOV TH0,#15H
   MOV TL0,#0A0H ; That is, the number 5536
   SETB EA ; Turn on the general interrupt enable
   SETB ET0 ; Turn on the timer/counter 0 enable
   SETB TR0 ; Timer/Counter 0 starts running
   LOOP: AJMP LOOP ; When it really works, you can write any program here
   TIME0: ; Timer 0 interrupt handler
   PUSH A CC
   PUSH PSW ; Push PSW and ACC into the stack protection
   CPL P1.0
   MOV TH0,#15H
   MOV TL0,#0A0H ; Reset the timing constant
   POP PSW
   POP ACC
   RETI
   END
  In the above example, when the timing 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 timing interrupt, we must first save some of the current states. 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, there is actually no need to save any value, just a demonstration here).
  After running the above two programs, we found that the flashing of the light is very fast and it is impossible to distinguish it. It is just that the light is 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 60000 microseconds, or 60 milliseconds, so the speed is very fast. If I want to achieve a 1S timing, what should I do? At this crystal oscillator frequency, the longest timing is 65.536 milliseconds! An example 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 all lights
   MOV 30H,#00H ;Software counter pre-clears 0
   MOV TMOD,#00000001B ;Timer/Counter 0 works in mode 1
   MOV TH0,#3CH
   MOV TL0,#0B0H ;The number is 15536
   ​​SETB EA ;Open general interrupt enable
   SETB ET0 ;Open timer/counter 0 enable
   SETB TR0 ;Timer/Counter 0 starts running
   LOOP: AJMP LOOP ;When it is really working, you can write any program here
   TIME0: ;Interrupt handler of timer 0
   PUSH ACC
   PUSH PSW ;Push PSW and ACC into the stack to protect
   INC 30H
   MOV A,30H
   CJNE A,#20,T_RET ;Has the value in unit 30H reached 20?
   T_L1: CPL P1.0 ;If it has, 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
  Analyze it yourself first to see how it is implemented? The concept of software counter is adopted here. The idea is to use timer/counter 0 to make a 50 millisecond timer. When the timer is reached, P10 is not negated immediately, but the value in the software counter is added by 1. If the software counter counts to 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 these timing times have a certain common divisor, we can use software timers to implement them. For example, I want to realize that the light connected to the P10 port flashes for 1S each time, and the light connected to the P11 port flashes for 2S each time. How to achieve it? By the way, we use two counters. When it counts to 20, P10 is negated and cleared, as shown above. The other counter counts to 40, P11 is negated, and then cleared to 0. Isn't it OK? This part of the program is as follows:
   ORG 0000H
   AJMP START
   ORG 000BH ;Timer 0 interrupt vector address
   AJMP TIME0 ;Jump to the real timer program
   ORG 30H
   START:
   MOV P1,#0FFH ;Turn off all lights
   MOV 30H,#00H ;Software counter pre-clear 0
   MOV TMOD,#00000001B ;Timer/Counter 0 works in mode 1
   MOV TH0,#3CH
   MOV TL0,#0B0H ;That is, the number 15536
   ​​SETB EA ;Turn on the general interrupt enable
   SETB ET0 ;Turn on the timer/counter 0 enable
   SETB TR0 ;Timer/Counter 0 starts running
   LOOP: AJMP LOOP ;When it really works, you can write any program here
   TIME0: ;Timer 0 interrupt handler
   PUSH ACC
   PUSH PSW ;Push PSW and ACC into the stack to protect
   INC 30H
   INC 31H ;Add 1 to both counters
   MOV A,30H
   CJNE A,#20,T_NEXT ;Has the value in 30H reached 20?
   T_L1: CPL P1.0 ;If it has, invert P10
   MOV 30H,#0 ;Clear software counter
   T_NEXT:
   MOV A,31H
   CJNE A,#40,T_RET ;Has the value in 31h reached 40?
   T_L2:
   CPL P1.1
   MOV 31H,#0 ;If it has, invert P11, clear counter, return
   T_RET:
   MOV TH0,#15H
   MOV TL0,#9FH ;Reset timing constant
   POP PSW
   POP ACC
   RETI
   END
  Can you use the timer method to implement the running light mentioned earlier? Try it.

Reference address:Microcontroller Tutorial 9 Timer Experiment 1

Previous article:Microcontroller tutorial 1 Timer experiment 2
Next article:Microcontroller Tutorial 7 Serial Application Programming Example

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号