天天看點

@toc[單片機程式設計中的一些時序問題]

單片機程式設計中的一些時序問題

本文的的delay原型:

void delay(unsigned int t){
	while(t--);//10us
}
           

今天在單片機程式設計時遇到了一些問題:

  1. LCD1602的第二行無法顯示
  2. 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無法把它拉高

@toc[單片機程式設計中的一些時序問題]
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”

繼續閱讀