Some special applications require more precise delays (such as DS18B20, etc.), but C is not like assembly language, and it is difficult to calculate the accuracy of delays. After repeated debugging, I compared the assembly source file compiled by KEIL and came up with the following precise delay statements (absolutely accurate! I have passed actual tests). I posted them here today, hoping to help friends in need.
Reference address:About the precise delay function written in C language in 51 single chip microcomputer
sbit LED = P1^0; // define a pin (for delay test)
unsigned int i = 3; // pay attention to the data types of i, j,
unsigned char j = 3; // different data types have very different delays
//-----------------Various precise delay statements-----------------------------------
while( (i--)!=1 ); // Delay 10*i machine cycles
i = 10; while( --i ); // Delay 8*i+2 machine cycles
i = 10; while( i-- ); // Delay (i+1)*9+2 machine cycles
j = 5; while( --j ); // Delay 2*j+1 machine cycles
j = 5; while( j-- ); // Delay (j+1)*6+1 machine cycles
i = 5;
while( --i ) // Delay i*10+2 machine cycles, at i*10+2 machine cyclesif
( LED==0 ) break; // When the LED pin is detected to be at a low level, the delay is jumped out
i = 5;
while( LED ) // Check the LED pin status every 10 machine cycles. When LED
is low or 10*i+2 machine cycles have passed, the delay is jumped out.
//--------------------------------------------------------------------
For example, the reset function of 18b20 (12M crystal oscillator):
//***********************************************************************
// Function: 18B20 reset
// Input parameter: None
// Output parameter: unsigned char x: 0: Success 1: Failure
//***********************************************************************
unsigned char ow_reset(void)
{
unsigned char x=0; // 12M crystal oscillator 1 machine cycle is 1us
DQ = 1; // DQ reset
j = 10; while(--j);// Do a short delay (delay 10*2+1=21 machine cycles, 21us)
DQ = 0; // MCU pulls DQ low
j = 85; while(j--);// Accurate delay (greater than 480us) 85*6+1=511us
DQ = 1; // Pull the bus high
j = 10; while(j--);// Accurate delay 10*6+1=61us
x = DQ; // After a short delay,
return x; // If x=0, initialization is successful and x=1, initialization fails
j = 25; while(j--);// Accurate delay 25*6+1=151us
}
//************************************************************************************
unsigned int i = 3; // pay attention to the data types of i, j,
unsigned char j = 3; // different data types have very different delays
//-----------------Various precise delay statements-----------------------------------
while( (i--)!=1 ); // Delay 10*i machine cycles
i = 10; while( --i ); // Delay 8*i+2 machine cycles
i = 10; while( i-- ); // Delay (i+1)*9+2 machine cycles
j = 5; while( --j ); // Delay 2*j+1 machine cycles
j = 5; while( j-- ); // Delay (j+1)*6+1 machine cycles
i = 5;
while( --i ) // Delay i*10+2 machine cycles, at i*10+2 machine cyclesif
( LED==0 ) break; // When the LED pin is detected to be at a low level, the delay is jumped out
i = 5;
while( LED ) // Check the LED pin status every 10 machine cycles. When LED
is low or 10*i+2 machine cycles have passed, the delay is jumped out.
//--------------------------------------------------------------------
For example, the reset function of 18b20 (12M crystal oscillator):
//***********************************************************************
// Function: 18B20 reset
// Input parameter: None
// Output parameter: unsigned char x: 0: Success 1: Failure
//***********************************************************************
unsigned char ow_reset(void)
{
unsigned char x=0; // 12M crystal oscillator 1 machine cycle is 1us
DQ = 1; // DQ reset
j = 10; while(--j);// Do a short delay (delay 10*2+1=21 machine cycles, 21us)
DQ = 0; // MCU pulls DQ low
j = 85; while(j--);// Accurate delay (greater than 480us) 85*6+1=511us
DQ = 1; // Pull the bus high
j = 10; while(j--);// Accurate delay 10*6+1=61us
x = DQ; // After a short delay,
return x; // If x=0, initialization is successful and x=1, initialization fails
j = 25; while(j--);// Accurate delay 25*6+1=151us
}
//************************************************************************************
Another example is the infrared decoding program:
(Let’s first talk about the disadvantages of traditional infrared decoding:
the program uses an infinite loop such as while(IR_IO);while(!IR_IO);. If the pin is always in a certain state, the while loop will be executed continuously, causing a "freeze". Of course, this situation is rare, but we have also taken it into consideration. The following program will not do this. If there is no correct level signal within the specified time, it will return to the main program, so there will be no "freeze")
(Let’s first talk about the disadvantages of traditional infrared decoding:
the program uses an infinite loop such as while(IR_IO);while(!IR_IO);. If the pin is always in a certain state, the while loop will be executed continuously, causing a "freeze". Of course, this situation is rare, but we have also taken it into consideration. The following program will not do this. If there is no correct level signal within the specified time, it will return to the main program, so there will be no "freeze")
//***************************External interrupt 0***********************************
void int0(void) interrupt 0
{
unsigned char i,j;
unsigned int count = 800;
//--------------8.5ms low level boot code-------------------------------------
while( --count )
if( IR_IO==1 ) return; // A high level appears in less than 8ms, return
count = 100; // Delay 1ms
while( !IR_IO ) // Wait for high levelif
( (--count)==0 ) return; // No high level appears within 9ms, return
//-------------4.5ms high level boot code------------------------------------
count = 410; // Delay 4.1ms
while( --count ) // ...
if( IR_IO==0 ) return; // A low level appears within 4.1ms, return
count = 50; // Delay 0.5ms
while( IR_IO ) // Wait for low levelif
( (--count)==0 ) return; // No low level appears within 4.7ms, return
//-----------------------------------------------------------------
//------------4 data codes------------------------------------
for( j=0;j<4;j++ )
{
for( i=0;i<8;i++ )
{
IR_data[j] <<= 1; // Load data
count = 60; // Delay 0.6ms
while( !IR_IO ) // Wait for high levelif
( (--count)==0 ) return; // No high level appears within 0.6ms, return
count = 40; // Low level ends, continuewhile
( --count ) // Delay 0.4ms
if( IR_IO==0 ) return; // Low level appears within 0.4ms, return
count = 100; // Delay 1.4ms
while( IR_IO ) // Detect IO statusif
( (--count)==0 ) // Wait for 1.4ms to arrive
{ // All high levels within 1.4ms
IR_data[j] |= 1; // Two units of high level, data 1
break; // Jump out of the loop
}
count = 20; // Delay 0.2ms
while( IR_IO ) // Wait for low level to jump
outif( (--count)==0 ) return; // No low level appears within 0.2ms, return
}
}
//-------------------------------------------------------------------
flag_IR = 1; // Set the infrared reception success flag
}
void int0(void) interrupt 0
{
unsigned char i,j;
unsigned int count = 800;
//--------------8.5ms low level boot code-------------------------------------
while( --count )
if( IR_IO==1 ) return; // A high level appears in less than 8ms, return
count = 100; // Delay 1ms
while( !IR_IO ) // Wait for high levelif
( (--count)==0 ) return; // No high level appears within 9ms, return
//-------------4.5ms high level boot code------------------------------------
count = 410; // Delay 4.1ms
while( --count ) // ...
if( IR_IO==0 ) return; // A low level appears within 4.1ms, return
count = 50; // Delay 0.5ms
while( IR_IO ) // Wait for low levelif
( (--count)==0 ) return; // No low level appears within 4.7ms, return
//-----------------------------------------------------------------
//------------4 data codes------------------------------------
for( j=0;j<4;j++ )
{
for( i=0;i<8;i++ )
{
IR_data[j] <<= 1; // Load data
count = 60; // Delay 0.6ms
while( !IR_IO ) // Wait for high levelif
( (--count)==0 ) return; // No high level appears within 0.6ms, return
count = 40; // Low level ends, continuewhile
( --count ) // Delay 0.4ms
if( IR_IO==0 ) return; // Low level appears within 0.4ms, return
count = 100; // Delay 1.4ms
while( IR_IO ) // Detect IO statusif
( (--count)==0 ) // Wait for 1.4ms to arrive
{ // All high levels within 1.4ms
IR_data[j] |= 1; // Two units of high level, data 1
break; // Jump out of the loop
}
count = 20; // Delay 0.2ms
while( IR_IO ) // Wait for low level to jump
outif( (--count)==0 ) return; // No low level appears within 0.2ms, return
}
}
//-------------------------------------------------------------------
flag_IR = 1; // Set the infrared reception success flag
}
Previous article:The use of 51 MCU RAM
Next article:DC motor drive based on 51 single chip microcomputer (L298)
- Popular Resources
- Popular amplifiers
Recommended Content
Latest Microcontroller Articles
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
MoreDaily News
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
Guess you like
- Application of solid state relays in servo motors
- Circuit principle help
- Design and implementation of platinum resistance thermometer
- About STM32's SPI_Direction_1Line_Rx mode
- ADS1115 based on MSP430F5529 microcontroller
- Voltage and current sampling
- A case study on the fault repair of a single-chip microcomputer-controlled electric fan mainboard
- Sinlinx A64 development board Linux kernel waiting queue poll --- blocking and non-blocking
- iTOP-iMX6 development board-device tree driver-compile driver as module
- How to read TI DSP's complex technical documents