單片機程式設計中的一些時序問題
本文的的delay原型:
void delay(unsigned int t){
while(t--);//10us
}
今天在單片機程式設計時遇到了一些問題:
- LCD1602的第二行無法顯示
- DS18b20的溫度一開始一直為0,後來一直是變化的負數
這裡面有兩個原因,一個是延時時間不夠,如以下lcd程式中,在端口被指派一個位元組後的延時是必不可少的,LCD1602需要時間處理一個位元組的資料.
EN=1;
GPIO_LCD=order;//#define GPIO_LCD P0
delay(2000);
EN=0;
再如DS18B20的初始化中,釋放總線後的延時不能太短,我按照以下描述寫了個
delay(10)
,結果溫度一直0.06.
控制器首先将總線拉低480-960us.然後釋放總線,産生複位脈沖,DS18B20在接收到複位脈沖後會等待15-60us,之後将總線拉低并保持60-240us,産生存在脈沖,這表明DS18B20已經初始化完成
結果寫成
delay(20);
就可以了
bit Init18b20(){
DSPORT=0;//拉低480-960us
delay(80);//(60);
DSPORT=1;//釋放總線
delay(20);//(10);
if(DSPORT==0){
DSPORT=1;//whatever successful or fail,release the bus
return 0;//initial successfully
}
DSPORT=1;//whatever successful or fail,release the bus
return 1;//initial fail;
}
另一個問題則是我在寫讀 DS18B20時忘了釋放總線,下面的時序圖裡也沒有釋放總線的時序,但是釋放總線是必不可少的,隻有釋放了總線,DS18B20才可以在總線上寫1寫0.不然的話,總線将一直保持低電平,DS18B20無法把它拉高
u8 Read18b20(){
u8 i,dat=0;
for(i=0;i<8;i++){
DSPORT=0;
_nop_();
_nop_();
//将總線拉低并保持超過1us後釋放總線
//這是必不可少的,否則即使在寫一的時候,DS18B20也無法拉高總線
DSPORT=1;
dat>>=1;
_nop_();
if(DSPORT)
dat|=0x80;
DSPORT=1;//release the bus
delay(10);
}
return dat;
}
首先将總線拉低并保持超過1us後釋放總線,DS18B20檢測到這一操作後,迅速将要輸出的資料放到總線上。控制器會在拉低總線後的1~15us時間段内對總線進行采樣,如果檢測到低電平,就是從DS18B20中讀出了“0”,如果檢測到高電平,就是從DS18B20中讀出了“1”