單片機開發(fā)--時序影響
在單片機開發(fā)中,如果時序關系不正確定的話,數據就不能正確的讀寫。因此,在程序中,如何正確的控制時序關系,就顯得特別的重要。
本文引用地址:http://2s4d.com/article/201611/320781.htm先來看以下的兩個例子:
1.DS1302時鐘芯片,采用SPI總線;
2.24C08存儲芯片,采用I2C總線。
在對DS1302進行編程時,發(fā)現數碼管只顯示時間的奇數值,而偶數值則不顯示。
檢查了下程序,問題定位在讀出數據與寫入數據的函數,原函數具體如下:
uchar ReadDs1302()
{
uchar dat,i;
SCLK=1;
Delayus(2);
for(i=0;i<8;i++)
{
dat>>=1;
if(DATA==1)
{
dat|=0x80;
}
SCLK=1;
Delayus(2);
SCLK=0;
Delayus(2);
}
return da;
}
將上面紅色字體的那行程序刪除,或者改為:SCLK=0,再重新燒寫后,數碼管顯示的時間正常。
而寫入數據的函數如下:
void WriteDs1302(uchar dat)
{
uchar i;
SCLK=0;
Delayus(2);
for(i=0;i<8;i++)
{
DATA=dat&0x01;
Delayus(2);
SCLK=1;
Delayus(2);
SCLK=0;
dat>>=1;
Delayus(2);
}
}
若只將上面藍色部分的程序改為:
if(i<7)
{
SCLK=0;
}
重新燒寫進去后,數碼管也能正確的顯示。
以藍色那行程序的修改,分析其原因:
先看下SPI總線的讀操作時序,其為下降沿采樣,如下圖所示:
從時序圖中,可看出,對于寫數據,是在時鐘的上升沿,而讀數據,則是在時鐘的下降沿。
程序修改前,在往DS1302中寫入第八位數據后,時鐘信號就變?yōu)榈碗娖?。此后,進入讀階段,在DS1302還沒將數據送到SDA線上時,時鐘就變?yōu)楦唠娖?,此時對應的SDA上的數據,還是為寫入的數據1。
而程序修改后,即在SDA寫入數據后,在第八位數據時,SCLK就不降為低電平了,一直保持為高電平,直到DS1302將數據送到SDA時,才變?yōu)榈碗娖剑谙陆笛貢r對SDA上的數據進行采樣。
即修改后的程序,在讀寫操作交替那個時鐘,等到DS1302送數據到SDA線上后,才變?yōu)榈碗娖?,進行采樣的。
對于24C08,其采用I2C總線技術,當程序燒寫進入后,發(fā)現不能正常的工作。
問題定位在I2C結束信號函數,具體如下所示:
void Stop()
{
SCL=1;
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
上面紅色兩行程序的順序對調下,則能正確的讀寫24C08芯片內部的數據。
分析其原因,則在于若執(zhí)行Stop()這個函數之前時,若SDA上存在幾個周期的高電平時,此時執(zhí)行SCL=1;SDA=0,相當于多出了個I2C的開始信號,導致錯誤。
在實際中,總結了下以后幾點,希望可以盡量避免時序操作錯誤:
1. 特別注意單字節(jié)讀,寫函數剛開始或結束時,時鐘信號的高低電平;
2. 可確定1或者0為程序的默認電平。如對于DS1302的CLK,可以低電平;
3. 從節(jié)省功耗的角度出發(fā),盡量保證默認電平功耗低。以I2C總線為例,因其有上拉電阻 的存在,故可保證默認電平為高;
4. 同樣從功耗的角度出發(fā),盡量保證各類信號少翻轉;
5. 對于總線控制信號(如SPI總線的RST),一切信號都準備好之后,控制信號才開啟。當總線要停止工作時,先將控制信號關斷,再作其他信號的處理;
6. 當然,得時刻警惕信號的建立時間與保持時間。
當然,若在程序中查找不出問題時,可采用示波器,同時測量時鐘與數據信號,判斷時序是否正確。
評論