Common delay and interrupt problems and solutions for various microcontrollers
[Copy link]
Delay and interrupt errors are common problems encountered by MCU novices in the process of MCU development and application. This article summarizes the common delay and interrupt problems and solutions of various MCUs including MCS-51 series MCU, MSP430 MCU, C51 MCU, 8051F MCU, AVR MCU, STC89C52, PIC MCU, etc. Hope it will be helpful to MCU novices!
1. How to calculate the delay time of the microcontroller delay program?
Answer: If the loop is implemented with a loop statement, it cannot be calculated, but the specific time can be seen through software simulation, but generally accurate delay cannot be implemented with a loop statement.
If you want to delay accurately, you generally need to use a timer. The delay time is related to the crystal oscillator. The single-chip microcomputer system generally uses 11.059 2 MHz, 12 MHz or 6 MHz crystal oscillators. The first one is easier to generate various standard baud rates, and the machine cycles of the latter two are 1 μs and 2 μs respectively, which is convenient for accurate delay. This program assumes that a crystal oscillator with a frequency of 12 MHz is used. The longest delay time can reach 216=65 536 μs. If the timer works in mode 2, an extremely short time of accurate delay can be achieved; if other timing modes are used, the time to reload the initial value of the timing must be considered (reloading the initial value of the timer takes 2 machine cycles).
2. I want a single-chip 89S51 12M crystal oscillator with a timer to delay for 10 minutes and control 1 light.
Answer: You can set an interrupt every 50ms, with the initial timing value of TH0=0x3c and TL0=0xb0. 20 interrupts equal 1S, so if it takes 10 minutes, 12,000 interrupts are required. After counting 12,000 times, give a low level to an IO port (if the power is not enough, you can expand it), and you can control the light.
It also depends on what language you use to calculate. The assembly delay is accurate, and you can calculate it by knowing the working cycle and number of cycles of the microcontroller, but it is not portable. Assembly is not universal among different types of microcontrollers. If you use C, since the execution efficiency of various software is different, it will not be too accurate. Usually, a timer is used for delay or an inaccurate delay is made. If the delay is short, use assembly nop to make a delay in C.
3. 51 MCU C language for loop delay program time calculation, assuming the crystal oscillator is 12MHz, that is, one machine cycle is 1us.
for(i=0,i<100;i++)
for(j=0,j<100;j++)
I think the time is 100*100*1us=10ms, how can it be 100ms
Answer:
Impossible, is there something wrong with your compilation?
I modified the crystal oscillator to 12M, compiled in KEIL 4.0, and the maximum result you get is 40ms. This is due to the software.
It is impossible to have such a big difference of 100ms. It is due to your software.
If you don't believe it, you can actually write a second program, use the principle calculation to write a second program burned into the microcontroller, and use the software test to burn into the microcontroller. You will find that the principle calculation program is correct.
4. Is _nop_() in the C language of 51 single-chip microcomputer an empty instruction? A short delay? How many machine cycles are empty?
Answer: This _nop_() is equivalent to the NOP instruction in the assembly, which means that one machine cycle is empty. If it is a traditional 51 microcontroller, it is equivalent to 12 clock cycles [i.e. one machine cycle]
5. How to calculate the delay of 51 MCU 500ms by machine cycle superposition?
Answer:
DELAY:
MOV R7,#4
D2:MOV R6,#250
D1:MOV R5,#250
DJNZ R5,$
DJNZ R6,D1
DJNZ R7,D2
RET
Assuming the crystal oscillator is 12MHz,
the delay time is:
250*250*4*2=500MS
6. What is the principle of the delay function in the C language program of 51 single-chip microcomputer?
Now find two functions
First:
void delay(void)
{ unsigned int i,j;
for(i=0;i<500;i++)
{ for(j=0;j<121;j++)
{;}
}
}
Second:
void delay(unsigned int k)
{ unsigned int i,j;
for(i=0;i
{ for(j=0;j<121;j++)
{;}
}
}
There are several questions:
(1): What is the principle of the delay function?
(2): What are the functions of the two for loops?
(3): What is the rule and basis for the values of i and j? Is it related to the frequency of the crystal oscillator connected to the microcontroller? How is the minimum unit time of delay calculated?
How to calculate the delay time! What if the crystal oscillator AT89C51RC+11.0592M is used?
Answer:
1: Principle: Just execute some so-called "meaningless instructions" that have no substantial impact, such as comparing the size, doing a self-addition operation of a certain int, etc.
2: The role of the double for: Simply put, just like the "multiplication principle" in high school mathematics, this can easily and quickly increase the number of the above "meaningless instructions"
3: About the value size: If this is changed under C, this value is not only related to the crystal oscillator and the computing speed of the microcontroller itself, but also to the C compiler. Therefore, although this value can be accurately calculated, in most cases, programmers use "experience values" - of course, if you use assembly programming, the situation is different, because the machine cycle used by each instruction is certain, you can of course accurately calculate the total time of the specific delay based on the total time used by all instructions. In
summary of your problem, I give you some advice, that is, when you first learn microcontrollers, you must honestly start with assembly programming - in this way, after you come into contact with C in the future, you can understand what kind of process you actually went through in the middle, and only in this way can you truly understand microcontrollers. Of course, once you have finally mastered a microcontroller, it is undoubtedly history's ruling that you should try to use C programming.
7. 51 single-chip microcomputer, crystal oscillator is 6M, find a 10ms delay program
Answer: There are many ways to delay. One is to let the microcontroller do a boring loop, and another is to use a timer.
The first algorithm is:
the period of the crystal oscillator T1=1/f; here f=6MHz so T1=1/6 us; (microseconds)
the microcontroller takes 12 T1s to execute an instruction,
so one machine cycle is equal to 12 crystal oscillator cycles,
T2=12*T1=2us
10ms=1000 0us
so if you want to get a 10ms delay you have to find a way to let the machine do 5000 "boring instructions"
so
DEL: MOV R5,#05H
F1: MOV R6,#05H
F2: MOV R7,#32H
F3: DJNZ R7,F3
DJNZ R6,F2
DJNZ R5,F1
RET
this method is used in places where time is not a big requirement, I'm talking about its idea, there may be mistakes in the program
I'm not very good at using the timer method so I won't mislead you (I'd like to add that this is written in assembly, you can use ACALL DEL to call it in the main program to delay.
8. Today, when I used a single-chip microcomputer to do the "blinking LED" experiment, the program ran and the light turned on or off every time, but when the delay was turned on, the expected light did not turn on or off. What's going on?
The hardware conditions of the experiment are: STC89C52, compilation environment: keil 3.
The following is the program I wrote, please ask the experts!!!
#include // File inclusion processing
#define uchar unsigned char // Macro definition, convenient for future program writing
#define uint unsigned int
sbit P1_0 = P1 ^ 0; // Bit variable definition
void Delay(uint t)
{
uchar i;
while(--t)
{
for(i = 0; i < 125; i++) // Delay 1MS, the crystal oscillator we use here is 12M, according to the calculation of the machine cycle, we
{;} // It can be calculated that the delay of this cycle is about 1MS
}
}
void main(void)
{
while(1)
{
P1_0 = 0; // Turn on the LED light
Delay(1000); // The single chip executes the program very quickly, so it must be delayed, otherwise the experimental phenomenon cannot be seen
P1_0 = 1; //Turn off the LED light
}
Additional question: I let P1.0 go low first, then go high after a delay, that is, the light turns on first and then turns off, and then starts the cycle
Answer: It should be written like this
while(1)
{
P1_0 = 0; //Turn on the LED light
Delay(1000); //The single chip executes the program very quickly, so a delay is required, otherwise the experimental phenomenon will not be seen
P1_0 = 1; //Turn off the LED light
Delay(1000);
Additional question reply: The problem is exactly here. After the cycle is completed, there is no time delay for the light to turn from off to on. That is, the light has not turned off in the first cycle, but it turns on in the second cycle. So this is the reason. This mistake is too low-level. Take it as a warning in the future.
9. Problem with the delay function of the microcontroller:
void delay(uchar i)
{
uchar j;
while(i--)
{
for(j=125;j>0;j--)
;
}
}
Is there any difference in the size of i and j in this function?
A: The size of j in this function depends on the data type you defined. Since you defined it as an unsigned character type, which is single-byte data, the maximum value is 255.
If you need to increase it, you can change the data type definition of j, such as unsigned int (2 bytes) can reach 65535; unsigned long (4 bytes) can reach 4294967295. The 256 mentioned above is -1, and you defined it as an unsigned character type.
10. Please tell me about the delay of AVR microcontroller
The external crystal oscillator is 8MHz, and the program for delaying 1 microsecond is as follows:
void delay_us(unsigned int delay_counter)//delay 1us
{
do
{
delay_counter--;
}
while(delay_counter>1);
}
Excuse me, why can it delay 1 microsecond?
Answer: 8MHZ means that the operating cycle of the microcontroller is 1/8us, which means that it takes 0.125us to execute one step.
You use software delay.
Then it takes time to extract and execute the program.
For example, it may take you one step to extract this function, so now it takes 0.125us.
Then you execute this function. Inside the microcontroller, the operation is realized by moving registers back and forth.
This takes time. You may see only one sentence, counter--this instruction may take several clock cycles to implement.
For example:
c=a+b, there is only one sentence, but it actually takes a long time.
mov a, #data1; //data data1 is put into register a
mov b, #data2; //data data2 is put into register b
add a, b; //add the value of register a to b, and put the result into a
mov c, a; //put the value of a into c
This is the instruction that is actually executed inside the microcontroller, which takes at least 4 clock cycles, not 1.
As for the transistor level, I will not explain it. You have to study assembly well to understand the operation of the microcontroller.
As for why this function can delay for 1ms, this is determined by experience. The most direct way is to use an oscilloscope to observe it. The above are all inferences.
11. Delay problem of PIC microcontroller crystal oscillator 4Mhz:
void delay()
{
unsigned int d=1000;
while(--d){;}
}
This function generates a delay of 10003us under 4M crystal, which is 10MS.
Question: I just calculated that it should have executed 999 instructions. A single-cycle instruction takes only 1us, which is 999us. Why is there a 10ms delay?
1: for(x=100;--x;){;} : 2: for(x=0;x<100;x++){;} The two sentences are the same
First sentence: Is the value range of X 1~99? Why?
Second sentence: Is the range of X 0~99? Why? This is how it is calculated. I know the difference between the first and the last sign. The two sentences should be different!
Answer:
Question 1: "I just calculated that it should execute 999 instructions" because you calculated it wrong. The delay time is determined by the generated assembly code. The C language statement is just an illusion. Don't think that one line of C language is one instruction! Because it involves double-byte subtraction, there will be additional judgments. It is not surprising that the compilation result consumes dozens of cycles per loop.
Question 2: In the first sentence, x starts to decrease from 100 and exits the loop when it decreases to 1. In the second sentence, x starts to increase from 0 and exits the loop when it increases to 100. The so-called "two sentences" are the same only means that the number of loops of the two loop bodies is the same. In fact, the execution process of the two loops is completely different, and the time consumed may also be different.
12. Delay problem of STC microcontroller, STC10F08XE microcontroller, crystal oscillator 22.1184M
void delay(unsigned long uldata)
{
unsigned int j = 0;
unsigned int g = 0;
for (j=0;j<5;j++)
{
for (g=0;g
{
_nop_();
_nop_();
_nop_();
}
}
}
When uldata=1, how many seconds is the delay?
Please give a specific algorithm............
Answer: Use Keil to convert it into assembly statements, and then calculate it according to the instruction table.
13. I want to use a single-chip microcomputer to continuously send numbers to a computer, as follows:
while (1)
{
send_char('9');
delay(n);
}
How many microseconds should be delayed each time a number is sent? In other words, what is the shortest possible delay? If the delay is too long, won't it take a long time to send a lot of data?
A: I won't do too much analysis on serial port processing, I will just talk about your question and your method:
first consider the serial port rate, assuming it is 9600, how long does it take to send a character?
(9600bit/S) / 10bit(a character 1+8+1) = 960 characters/second, about 1ms/byte.
In other words, if you send more than one character within 1ms, it will be meaningless because the hardware speed cannot reach it.
while(1)
{
send_char('9');
delay(n);
}
This loop has an execution period of only a dozen microseconds + the delay of delay(), so any delay less than 1040 microseconds is meaningless to the serial port hardware. The next one comes before the previous one is processed, so it cannot be executed at all.
If you have a statement like while(!TI);TI = 0; in send_char() or handle the serial port interrupt TI, then actually your delay() is already in the sending function. Does while(!TI); mean the delay waiting? Then there is no need for the main function to delay at all, just send it directly.
14. A problem with a delay subroutine of a single-chip microcomputer. I can't figure out why r7 and r6 are assigned 0, and then the following djnz r7, delayloop will keep looping. How can I continue the program?
org 0000h
ljmp start
org 0030h
start: mov a,#0feh
mov r5,#8
output: mov p1,a
rl a
call delay
djnz r5,output
ljmp start
delay: mov r6,#0
mov r7,#0
delayloop:djnz r7 ,delayloop
djnz r6,delayloop
ret
end
A: Your delay program is not because the value is 0, but because the jump position is wrong. Change it to the following:
delay: mov r6,#0
delayloop:mov r7,#0
:djnz r7,$
djnz r6,delayloop
ret
The initial value of R7 and R6 is 0, but when DJNZ is executed, this instruction first subtracts 1 and then makes a judgment, so 0-1=255, and the judgment is not 0, and it still loops 256 times.
Interpretation of 0-1=255:
0000 0000
- 0000 0001
-------------------------
1111
15. I would like to raise two issues about microcontroller delay and key presses
1: If there is a delay and key press in a program, and if the delay subroutine is relatively long (for example, 2 seconds), how to ensure that the key press can be responded to in time (if the PC is executing the delay subroutine and a key press is input at this time, it is not impossible to respond) -,,, the premise is that the timer cannot be used for timing scanning and interrupts, because I have other uses for timers and interrupts.
2: The microcontroller has no serial port. How can it communicate with 24C02 (24C02 is an EEPROM with 2K memory)
A:
First of all, you said that the microcontroller has no serial port, which should mean that it has no I2C port.
1. Add key detection to the delay program
2. Use the IO port to simulate I2C timing reading and writing
16. 51 MCU delay program, what does it mean?
delay200ms:
mov r2,#82
l0:mov r1,#116
l1:mov r0,#9
djnz r0,$
djnz r1,l1
djnz r2,l0
ret
Answer: The following is the time for each instruction, T is one machine cycle
delay200ms:
mov r2,#82;1T
l0:mov r1,#116;1T
l1:mov r0,#9;1T
djnz r0,$;2T
djnz r1,l1;2T
djnz r2,l0;2T
ret;2T
There are three layers of loops above. Ignoring some instructions, the simplest algorithm is:
2*9*116*82=171216
The instruction not to be ignored is:
1+(1+(1+2*9+2)*116+2)*82+2=200001
, so the delay time is about 200ms
17. Issues with delay time of 51 MCU
uchar i;i--;
uint i;i--;
How long do these two statements take to run under a 12M crystal oscillator?
Answer: One clock cycle, 2us, a total of 4us
18. How to program a subroutine with a 10-second delay for a 6MHZ MCU?
Answer:
/********************************************************************
* Name: Delay()
* Function: Delay, the delay time is 10ms * del. This is a software delay, there is a certain error.
* Input: del
* Output: None
**********************************************************************/
void Delay(uint del)
{
uint i,j;
for(i=0; i
for(j=0; j<1827; j++) //This is the number obtained by software simulation
;
}
This is a program for a 10ms delay for a microcontroller with a crystal oscillator of 12mhz. You only need to reduce it by half on this basis. Of course, the specific value still needs to be debugged.
19. Some programs of the microcontroller need to call delay programs. How can we reasonably arrange the number of loops and the number of empty operations?
A: If you use assembly language, you can calculate your instruction cycle based on your current crystal frequency, and then write a delay program based on the time you need to delay. If you use C, you still have to see what the final generated assembly code looks like. The easiest way is to write the program and then use the compiler to simulate the time.
20. Problems with MCU delay program
Delay program void delay(uint dt)
{
uchar bt;
for(;dt;dt--);
for(bt=0;bt<255;bt++);
}
There is a warning when compiling C:DOCUMENTS AND SETTINGSADMINISTRATORDesktop word 310 dot matrix LED display.C(46): warning C235: parameter 1: different types
Why? Please give me some advice
Answer: The parameter type passed to a function does not match the declared type.
In addition, your for(;dt;dt--); does not play the role of an outer loop...
|