About the precise delay function written in C language in 51 single chip microcomputer

Publisher:数字梦想Latest update time:2015-10-29 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
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.
 
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 

//************************************************************************************
 
 
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")
 
 
//***************************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 
Reference address:About the precise delay function written in C language in 51 single chip microcomputer

Previous article:The use of 51 MCU RAM
Next article:DC motor drive based on 51 single chip microcomputer (L298)

Latest Microcontroller Articles
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号