標(biāo)題: 誤人子弟的程序分析 [打印本頁]
作者: codenew 時間: 2014-10-6 22:36
標(biāo)題: 誤人子弟的程序分析
本帖最后由 codenew 于 2014-10-6 22:42 編輯
下面程序是我從別的地方搞來的,最后發(fā)現(xiàn)很多錯誤。為了避免誤人子弟,特地作了一下分析,開頭部分for分析是我寫的,程序中紅色的部分我是加上去的。
在軟件仿真環(huán)境下,把晶振改成12.0Mhz,C51標(biāo)簽代碼優(yōu)化設(shè)為0,見圖附件,測得for語句的延時為:
for(time=0;time<1;time++); //15us
for(time=0;time<2;time++); //23us
for(time=0;time<3;time++); //31us
for(time=0;time<4;time++); //39us
for(time=0;time<5;time++); //47us
for(time=0;time<6;time++); //55us
for(time=0;time<7;time++); //63us
for(time=0;time<8;time++); //71us
for(time=0;time<9;time++); //79us
for(time=0;time<10;time++); //87us
for(time=0;time<20;time++); //167us
for(time=0;time<60ime++); //487us
for(time=0;time<70ime++); //567us
for(time=0;time<80ime++); //647us
for(time=0;time<100;time++); //807us
for(time=0;time<200;time++); //1607us
由上可看出,成等差數(shù)列,公差d=8。一般地,如果n>m,an=am+8*(n-m)。
/*****************************************************
函數(shù)功能:將DS18B20傳感器初始化,讀取應(yīng)答信號
出口參數(shù):flag
***************************************************/
bit Init_DS18B20(void)
{
bitflag; //儲存DS18B20是否存在的標(biāo)志,flag=0,表示存在;flag=1,表示不存在
DQ= 1; //先將數(shù)據(jù)線拉高
for(time=0;time<2;time++);//略微延時約6微秒。實際是延時23us。
DQ= 0; //再將數(shù)據(jù)線從高拉低,要求保持480~960us
for(time=0;time<200;time++);//略微延時約600微秒,以向DS18B20發(fā)出一持續(xù)480~960us的低電平復(fù)位脈沖。實際是延時1607us,重大錯誤,都超過960us了。
DQ= 1; //釋放數(shù)據(jù)線(將數(shù)據(jù)線拉高)
for(time=0;time<10;time++);//延時約30us(釋放總線后需等待15~60us讓DS18B20輸出存在脈沖)。實際是延時87us,延時多過60us,反而能保證讀到存在脈沖,這點誤撞了。
flag=DQ; //讓單片機(jī)檢測是否輸出了存在脈沖(DQ=0表示存在)
for(time=0;time<200;time++); //延時足夠長時間,等待存在脈沖輸出完畢
return(flag); //返回檢測成功標(biāo)志
}
/*****************************************************
函數(shù)功能:從DS18B20讀取一個字節(jié)數(shù)據(jù)
出口參數(shù):dat
***************************************************/
unsigned char ReadOneChar(void)
{
unsignedchar i=0;
unsignedchar dat; //儲存讀出的一個字節(jié)數(shù)據(jù)
for(i=0;i<8;i++)
{
DQ=1; //先將數(shù)據(jù)線拉高
_nop_(); //等待一個機(jī)器周期
DQ= 0; //單片機(jī)從DS18B20讀書據(jù)時,將數(shù)據(jù)線從高拉低即啟動讀時序
dat>>=1;
_nop_(); //等待一個機(jī)器周期
DQ= 1; //將數(shù)據(jù)線"人為"拉高,為單片機(jī)檢測DS18B20的輸出電平作準(zhǔn)備
for(time=0;time<2;time++);//延時約6us,使主機(jī)在15us內(nèi)采樣。實際是延時23us,超過了15us。
if(DQ==1)
dat|=0x80; //如果讀到的數(shù)據(jù)是1,則將1存入dat
else
dat|=0x00;/如果讀到的數(shù)據(jù)是0,則將0存入dat,將單片機(jī)檢測到的電平信號DQ、r
for(time=0;time<8;time++);//延時3us,兩個讀時序之間必須有大于1us的恢復(fù)期。實際是延時71us。思路根本不對,讀時隙至少延時60us,這里又誤撞對了,把至少延時和讀時隙間隔至少1us都包含進(jìn)了。
}
return(dat); //返回讀出的十進(jìn)制數(shù)據(jù)
}
/*****************************************************
函數(shù)功能:向DS18B20寫入一個字節(jié)數(shù)據(jù)
入口參數(shù):dat
***************************************************/
WriteOneChar(unsigned char dat)
{
unsignedchar i=0;
for(i=0; i<8; i++)
{
DQ=1; // 先將數(shù)據(jù)線拉高
_nop_(); //等待一個機(jī)器周期
DQ=0; //將數(shù)據(jù)線從高拉低時即啟動寫時序
DQ=dat&0x01; //利用與運(yùn)算取出要寫的某位二進(jìn)制數(shù)據(jù),并將其送到數(shù)據(jù)線上等待DS18B20采樣
for(time=0;time<10;time++);//延時約30us,DS18B20在拉低后的約15~60us期間從數(shù)據(jù)線上采樣。實際是延時87us。
DQ=1; //釋放數(shù)據(jù)線
for(time=0;time<1;time++);//延時3us,兩個寫時序間至少需要1us的恢復(fù)期 。實際是延時15us。
dat>>=1; //將dat中的各二進(jìn)制位數(shù)據(jù)右移1位
}
for(time=0;time<4;time++);//稍作延時,給硬件一點反應(yīng)時間。延時39us。
}
/*****************************************************
函數(shù)功能:做好讀溫度的準(zhǔn)備
***************************************************/
void ReadyReadTemp(void)
{
Init_DS18B20(); //將DS18B20初始化
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換
for(time=0;time<100;time++);//溫度轉(zhuǎn)換需要一點時間。延時807us。
Init_DS18B20(); //將DS18B20初始化
WriteOneChar(0xCC);//跳過讀序號列號的操作
WriteOneChar(0xBE);//讀取溫度寄存器,前兩個分別是溫度的低位和高位
}
/*****************************************************
函數(shù)功能:延時若干毫秒
入口參數(shù):n
***************************************************/
voiddelaynms(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
照理說void delaynms(unsigned char n),參數(shù)n的取值范圍是0~255,因是是無符號數(shù)。但在主函數(shù)中卻調(diào)用delaynms(1000),明顯錯誤,超出取值范圍。
-
C51.jpg
(87.78 KB, 下載次數(shù): 189)
下載附件
2014-10-6 22:36 上傳
C51代碼優(yōu)化
作者: 明白 時間: 2014-10-7 08:47
程序的注釋,不是完全對。
程序通過返復(fù)調(diào)整得到正確代碼,這是每一個程序員編程過程,
在這過程中不可能總是修改注釋,
這樣就導(dǎo)致注釋的不同步。
延時函數(shù)一般情況下是線性。
原程序的運(yùn)行機(jī)器周期可能不是1us
作者: codenew 時間: 2014-10-7 10:54
樓上,我敢保證我的想法是對的。因為把源程序原封不動寫入芯片,測溫是正常顯示的,晶振是12Mhz。當(dāng)然引腳也是對應(yīng)的。
作者: codenew 時間: 2014-10-7 11:13
這要動腦再想想哪程序錯了,為什么還能正常用,的確運(yùn)氣很好。例如源程序的另一個延時程序又是錯的,其注釋思路肯定不對,但其實際效果還是接近1ms的:
/*****************************************************
函數(shù)功能:延時1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以認(rèn)為是1毫秒
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<4;i++)
for(j=0;j<33;j++);
}
作者: 明白 時間: 2014-10-7 15:37
DS18B20的讀寫操作需要一段時間,是不能短于時順規(guī)定的時間,如果延時長了,只是浪費時間而已。
可以長,但是不能短
作者: 明白 時間: 2014-10-7 15:40
如果晶振是12Mhz。那么
void delay1ms()
{
unsigned char i,j;
for(i=0;i<4;i++)
for(j=0;j<33;j++);
}
這個就不能認(rèn)為是1ms,相差不只一倍
作者: 明白 時間: 2014-10-7 15:48
你延時這樣計算就有錯誤
看看 delay1ms()
編譯出來的內(nèi)碼,精算一下:
delay1ms: CLR A //1T
MOV R7,A //1T
D1: CLR A //1T
MOV R6,A //1T
D2: INC R6 //1T
CJNE R6,#21H,D2 //2T
INC R7 //1T
CJNE R7,#04H,D1 //2T
RET //2T
2T + [( 2T + 33 * 3T) + 1T + 2T ] * 4 + 2T
= 2T + [ 101T + 1T + 2T ] * 4 + 2T
= 2T + [ 104 T] * 4 + 2T
= 2T + [ 104 T] * 4 + 2T
= 420T
再加上調(diào)用delay1ms()時間,需要的LCALL兩個機(jī)器周期,就是:
422us
作者: 明白 時間: 2014-10-7 16:12
for(time=0;time<1;time++); //15us for(time=0;time<2;time++); //23us
for(time=0;time<3;time++); //31us
for(time=0;time<4;time++); //39us
for(time=0;time<5;time++); //47us
for(time=0;time<6;time++); //55us
for(time=0;time<7;time++); //63us
for(time=0;time<8;time++); //71us
for(time=0;time<9;time++); //79us
for(time=0;time<10;time++); //87us
for(time=0;time<20;time++); //167us
for(time=0;time<60ime++); //487us
for(time=0;time<70ime++); //567us
for(time=0;time<80ime++); //647us
for(time=0;time<100;time++); //807us
for(time=0;time<200;time++); //1607us
這些原地延時是沒有可變性的(當(dāng)然是排除中斷的騷擾),
編譯出來的機(jī)器碼是有固定模式的:
START: CLR A //1T
MOV R7,A //1T
LOOP: INC R7 //1T
CJNE R7,#02H,LOOP //2T
所以延時時間:2T+time*(1T+2T)=2T+time*3T=(2+time*3)T
如果一個機(jī)器周期為:1us
an=am+8*(n-m)。這跟:
=2+3*time。差別大不大?
for(time=0;time<1;time++); //15us-------5us
for(time=0;time<2;time++); //23us-------8us
for(time=0;time<3;time++); //31us-------11us
for(time=0;time<4;time++); //39us-------14us
for(time=0;time<5;time++); //47us-------17us
for(time=0;time<6;time++); //55us-------20us
for(time=0;time<7;time++); //63us-------23us
for(time=0;time<8;time++); //71us-------26us
for(time=0;time<9;time++); //79us-------29us
for(time=0;time<10;time++); //87us-------32us
for(time=0;time<20;time++); //167us-------62us
for(time=0;time<60ime++); //487us-------182us
for(time=0;time<70ime++); //567us-------212us
for(time=0;time<80ime++); //647us-------242us
for(time=0;time<100;time++); //807us-------302us
for(time=0;time<200;time++); //1607us-------602us
作者: codenew 時間: 2014-10-7 20:31
本帖最后由 codenew 于 2014-10-7 20:37 編輯
樓上算錯了吧。見附圖,運(yùn)行完359行指令res=0;時的時間點為631us;運(yùn)行完360行指令 for(time=0;time<1;time++); 時的時間點為646us,注意黃色箭頭指向下一條。646us-631us=15us,即為 運(yùn)行for(time=0;time<1;time++); 的時間。
我反匯編 for(time=0;time<1;time++); 代碼如下:
360: for(time=0;time<1;time++);
C:0x0005 752E00 MOV time(0x2E),#0x00
C:0x0008 E52E MOV A,time(0x2E)
C:0x000A C3 CLR C
C:0x000B 9401 SUBB A,#0x01
C:0x000D 5004 JNC C:0013
C:0x000F 052E INC time(0x2E)
C:0x0011 80F5 SJMP C:0008
361: res=0;
C:0x0013 C20B CLR 0x21.3
-
d1.jpg
(10.12 KB, 下載次數(shù): 217)
下載附件
2014-10-7 20:29 上傳
-
d2.jpg
(10.55 KB, 下載次數(shù): 210)
下載附件
2014-10-7 20:29 上傳
作者: codenew 時間: 2014-10-7 20:50
本帖最后由 codenew 于 2014-10-7 21:01 編輯
看看delay1ms(),1774us-647us=1127us,接近1ms。
void delay1ms()
{
unsigned char i,j;
for(i=0;i<4;i++)
for(j=0;j<33;j++);
}
d3.jpg (7.58 KB, 下載次數(shù): 207)
下載附件
2014-10-7 20:58 上傳
d4.jpg (7.66 KB, 下載次數(shù): 185)
下載附件
2014-10-7 20:50 上傳
作者: a110 時間: 2014-10-7 22:15
我靠 太牛了 ,樓主的這個帖子對我的幫助非常大 ,佩服得五體投地 阿
作者: 明白 時間: 2014-10-7 22:19
本帖最后由 明白 于 2014-10-7 23:59 編輯
剛才我也仿真一下:
for(time=0;time<1;time++);的話:
396-391=5個機(jī)器周期
-
參數(shù)1結(jié)束.png
(3.38 KB, 下載次數(shù): 183)
下載附件
2014-10-7 23:45 上傳
-
參數(shù)1開始.png
(4.2 KB, 下載次數(shù): 216)
下載附件
2014-10-7 23:45 上傳
作者: 明白 時間: 2014-10-7 23:16
本帖最后由 明白 于 2014-10-8 00:25 編輯
for(time=0;time<2;time++);的話:
399-391=8個機(jī)器周期
-
參數(shù)2結(jié)束.png
(3.08 KB, 下載次數(shù): 206)
下載附件
2014-10-7 23:56 上傳
-
參數(shù)2開始.png
(3.43 KB, 下載次數(shù): 204)
下載附件
2014-10-7 23:56 上傳
-
原地延時機(jī)器碼.jpg
(16.78 KB, 下載次數(shù): 168)
下載附件
2014-10-8 00:25 上傳
作者: 明白 時間: 2014-10-8 00:06
本帖最后由 明白 于 2014-10-8 00:37 編輯
delay1ms()延時函數(shù):
void delay1ms()
{
unsigned char i,j;
for(i=0;i<4;i++)
for(j=0;j<33;j++);
}
834-412=422
看看delay1ms(),跟我上面精度計算結(jié)果也是422,一模一樣。
-
函數(shù)調(diào)用結(jié)束.jpg
(18.06 KB, 下載次數(shù): 196)
下載附件
2014-10-8 00:06 上傳
-
函數(shù)調(diào)用開始.jpg
(26.17 KB, 下載次數(shù): 167)
下載附件
2014-10-8 00:06 上傳
-
函數(shù)調(diào)用延時機(jī)器碼.jpg
(32.77 KB, 下載次數(shù): 183)
下載附件
2014-10-8 00:24 上傳
作者: 明白 時間: 2014-10-8 00:30
全部的機(jī)器碼
-
全部代碼.jpg
(88.27 KB, 下載次數(shù): 189)
下載附件
2014-10-8 00:30 上傳
作者: 明白 時間: 2014-10-8 00:36
本帖最后由 明白 于 2014-10-8 00:42 編輯
你篡改了別人原c語言程序的本意,
到此為止,你也應(yīng)該知道源程序哪里被你改了吧
作者: finalex 時間: 2014-10-8 10:21
沒看懂的說

作者: codenew 時間: 2014-10-8 17:14
本帖最后由 codenew 于 2014-10-8 17:31 編輯
認(rèn)真看了一下存在的爭議,主要是代碼優(yōu)化和全局變量出了問題。我之前發(fā)的貼,代碼優(yōu)化是設(shè)為0的,由于代碼沒有優(yōu)化,存在冗余部分,所以執(zhí)行時間較長。另外全局變量和局部變量也會影響執(zhí)行時間。
新建的工程代碼優(yōu)化默認(rèn)為8,見下圖所示。
代碼優(yōu)化為8.jpg (71.51 KB, 下載次數(shù): 165)
下載附件
優(yōu)化為8
2014-10-8 16:33 上傳
1.晶振設(shè)為12Mhz時,代碼優(yōu)化為8 ,time為全局變量時,主程序如下:
#include <reg52.h>#include <intrins.h>
unsigned char time;//設(shè)置全局變量,專門用于嚴(yán)格延時
void main()
{
bit res;
res=1;
while(1)
{
res=0;
for(time=0;time<1;time++);
res=0;
}
}
測得 for(time=0;time<1;time++);時間如下:
c1.jpg (7.95 KB, 下載次數(shù): 212)
下載附件
2014-10-8 16:48 上傳
c2.jpg (9.74 KB, 下載次數(shù): 177)
下載附件
2014-10-8 16:48 上傳
397us-391us=6us,即for(time=0;time<1;time++);為6us。同理time<2時,為10us;time<3時,為14us。一般地,n>m,time<n,n為正整數(shù),an=am+4*(n-m)。m=1時,an=6+4*(n-1)=4n+2。
for(time=0;time<1;time++); //6us
for(time=0;time<2;time++); //10us
for(time=0;time<3;time++); //14us
for(time=0;time<4;time++); //18us
for(time=0;time<5;time++); //22us
for(time=0;time<6;time++); //26us
for(time=0;time<7;time++); //30us
for(time=0;time<8;time++); //34us
for(time=0;time<9;time++); //38us
for(time=0;time<10;time++); //42us
for(time=0;time<20;time++); //82us
for(time=0;time<60ime++); //242us
for(time=0;time<70ime++); //282us
for(time=0;time<80ime++); //322us
for(time=0;time<100;time++); //402us
for(time=0;time<200;time++); //802us
2.晶振設(shè)為12Mhz時,代碼優(yōu)化為8 ,time為局部變量時,主程序如下:
#include <reg52.h>
#include <intrins.h>
void main()
{
unsigned char time;//設(shè)置局部變量
bit res;
res=1;
while(1)
{
res=0;
for(time=0;time<1;time++);
res=0;
}
}
測得 for(time=0;time<1;time++);時間如下:
c3.jpg (7.81 KB, 下載次數(shù): 191)
下載附件
2014-10-8 17:02 上傳
c4.jpg (8.5 KB, 下載次數(shù): 171)
下載附件
2014-10-8 17:03 上傳
396us-391us=5us,即for(time=0;time<1;time++);為5us。同理time<2時,為8us;time<3時,為11us。一般地,n>m,time<n,n為正整數(shù),an=am+3*(n-m)。m=1時,an=5+3*(n-1)=3n+2。
for(time=0;time<1;time++); //5us
for(time=0;time<2;time++); //8us
for(time=0;time<3;time++); //11us
for(time=0;time<4;time++); //14us
for(time=0;time<5;time++); //17us
for(time=0;time<6;time++); //20us
for(time=0;time<7;time++); //23us
for(time=0;time<8;time++); //26us
for(time=0;time<9;time++); //29us
for(time=0;time<10;time++); //32us
for(time=0;time<20;time++); //62us
for(time=0;time<60ime++); //182us
for(time=0;time<70ime++); //212us
for(time=0;time<80ime++); //242us
for(time=0;time<100;time++); //302us
for(time=0;time<200;time++); //602us
這點和8樓的一致。 3.重要說明,源程序的time是全局變量!當(dāng)優(yōu)化代碼為默認(rèn)的級別8時,再回頭看源程序的注釋。void delay1ms()正如7樓所說,是422us,不是源程序注釋所說的1ms,其它的可參照第1點全局變量time所羅列的延時時間。
作者: codenew 時間: 2014-10-9 09:50
本帖最后由 codenew 于 2014-10-9 09:58 編輯
//下面的time在源程序中都是全局變量!
/*****************************************************
函數(shù)功能:將DS18B20傳感器初始化,讀取應(yīng)答信號
出口參數(shù):flag
***************************************************/
bit Init_DS18B20(void)
{
bitflag; //儲存DS18B20是否存在的標(biāo)志,flag=0,表示存在;flag=1,表示不存在
DQ= 1; //先將數(shù)據(jù)線拉高
for(time=0;time<2;time++);//略微延時約6微秒。實際是延時10us,局部變量時為8us,不是注釋所說的6us。
DQ= 0; //再將數(shù)據(jù)線從高拉低,要求保持480~960us
for(time=0;time<200;time++);//略微延時約600微秒,以向DS18B20發(fā)出一持續(xù)480~960us的低電平復(fù)位脈沖。實際是延時802us,time為局部變量時才為602us,即約600us。這點作者明顯誤撞了,幸好802us還在范圍內(nèi)。
DQ= 1; //釋放數(shù)據(jù)線(將數(shù)據(jù)線拉高)
for(time=0;time<10;time++);//延時約30us(釋放總線后需等待15~60us讓DS18B20輸出存在脈沖)。實際是延時42us,time為局部變量時才為 32us,即約32us。明顯作者又錯了,把time當(dāng)作局部變量了,幸好 42us還在范圍內(nèi)。實際最好延時60us,確保能讀到存在脈沖。
flag=DQ; //讓單片機(jī)檢測是否輸出了存在脈沖(DQ=0表示存在)
for(time=0;time<200;time++); //延時足夠長時間,等待存在脈沖輸出。延時802us。
return(flag); //返回檢測成功標(biāo)志
}
/*****************************************************
函數(shù)功能:從DS18B20讀取一個字節(jié)數(shù)據(jù)
出口參數(shù):dat
***************************************************/
unsigned char ReadOneChar(void)
{
unsignedchar i=0;
unsignedchar dat; //儲存讀出的一個字節(jié)數(shù)據(jù)
for(i=0;i<8;i++)
{
DQ=1; //先將數(shù)據(jù)線拉高
_nop_(); //等待一個機(jī)器周期
DQ= 0; //單片機(jī)從DS18B20讀書據(jù)時,將數(shù)據(jù)線從高拉低即啟動讀時序
dat>>=1;
_nop_(); //等待一個機(jī)器周期
DQ= 1; //將數(shù)據(jù)線"人為"拉高,為單片機(jī)檢測DS18B20的輸出電平作準(zhǔn)備
for(time=0;time<2;time++);//延時約6us,使主機(jī)在15us內(nèi)采樣。實際是延時10us,局部變量時為8us,都不是注釋的6us。
if(DQ==1)
dat|=0x80; //如果讀到的數(shù)據(jù)是1,則將1存入dat
else
dat|=0x00;/如果讀到的數(shù)據(jù)是0,則將0存入dat,將單片機(jī)檢測到的電平信號DQ、r
for(time=0;time<8;time++);//延時3us,兩個讀時序之間必須有大于1us的恢復(fù)期。實際是延時34us,與3us差很多。
}
return(dat); //返回讀出的十進(jìn)制數(shù)據(jù)
}
/*****************************************************
函數(shù)功能:向DS18B20寫入一個字節(jié)數(shù)據(jù)
入口參數(shù):dat
***************************************************/
WriteOneChar(unsigned char dat)
{
unsignedchar i=0;
for(i=0; i<8; i++)
{
DQ=1; // 先將數(shù)據(jù)線拉高
_nop_(); //等待一個機(jī)器周期
DQ=0; //將數(shù)據(jù)線從高拉低時即啟動寫時序
DQ=dat&0x01; //利用與運(yùn)算取出要寫的某位二進(jìn)制數(shù)據(jù),并將其送到數(shù)據(jù)線上等待DS18B20采樣
for(time=0;time<10;time++);//延時約30us,DS18B20在拉低后的約15~60us期間從數(shù)據(jù)線上采樣。實際是延時42us,局部變量時才為32us。
DQ=1; //釋放數(shù)據(jù)線
for(time=0;time<1;time++);//延時3us,兩個寫時序間至少需要1us的恢復(fù)期 。實際是延時6us,局部變量時才為5us。
dat>>=1; //將dat中的各二進(jìn)制位數(shù)據(jù)右移1位
}
for(time=0;time<4;time++);//稍作延時,給硬件一點反應(yīng)時間。延時18us。
}
/*****************************************************
函數(shù)功能:做好讀溫度的準(zhǔn)備
***************************************************/
void ReadyReadTemp(void)
{
Init_DS18B20(); //將DS18B20初始化。既然Init_DS18B20();有返回值flag,不判斷其值是否成功就寫命令了,又筆誤。
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換
for(time=0;time<100;time++);//溫度轉(zhuǎn)換需要一點時間。延時402us。
Init_DS18B20(); //將DS18B20初始化
WriteOneChar(0xCC);//跳過讀序號列號的操作
WriteOneChar(0xBE);//讀取溫度寄存器,前兩個分別是溫度的低位和高位
}
/*****************************************************
函數(shù)功能:延時若干毫秒
入口參數(shù):n
***************************************************/
voiddelaynms(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
// 照理說void delaynms(unsigned char n),參數(shù)n的取值范圍是0~255,因是是無符號數(shù)。但在主函數(shù)中卻調(diào)用delaynms(1000),明顯錯誤,超出取值范圍。/*****************************************************
函數(shù)功能:延時1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以認(rèn)為是1毫秒
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<4;i++)
for(j=0;j<33;j++);
}
//實際延時422us,代碼優(yōu)化為0時才接近1ms。
作者: gemxie 時間: 2015-10-18 14:20
好的,謝謝分享了。。。
作者: 88528 時間: 2015-12-28 10:09
有沒有完整的對的程序u
作者: bx2008love 時間: 2016-1-10 21:04
18b20有時候跟硬件關(guān)系很大,不同硬件程序跑出來不一樣,還有中斷也會影響到它的測量
作者: ztrdiy 時間: 2016-7-23 12:13
樓主人好,技術(shù)不錯。
作者: 的神煩大叔 時間: 2016-10-3 15:54
看不懂呀,有完整程序啊
作者: zhang790614 時間: 2017-5-5 10:54
完整的有嗎?
作者: w1179benp 時間: 2017-5-10 09:52
欽佩做事認(rèn)真的人,因為曾有偉人說過,“世界上怕就怕認(rèn)真二字”,科學(xué)來不得半點馬虎。
作者: boboxuexi 時間: 2020-4-1 08:29
阻塞式延時都是垃圾,,哈哈
作者: 張小不懂 時間: 2020-4-1 10:44
神仙打架
| 歡迎光臨 (http://m.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |