|
希望可以幫我修改,謝謝
問(wèn)題:用這個(gè)程序燒寫(xiě)到單片機(jī)里面結(jié)果發(fā)現(xiàn)。三位數(shù)碼管中總有兩位顯示的時(shí)候閃個(gè)不停,并且亮度較正常顯示的時(shí)候暗。求大神教
數(shù)碼管顯示溫度程序如下:
#include<reg52.h> //包含單片機(jī)寄存器的頭文件
#include<intrins.h> //包含_nop_()函數(shù)定義的頭文件
unsigned char flag,tltemp; //負(fù)溫度標(biāo)志 和臨時(shí)暫存變量
unsigned char code s8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//數(shù)碼管數(shù)字0-9
void delay1ms()
{
unsigned char i,j;
for(i=0;i<4;i++)
for(j=0;j<33;j++)
;
}
void delaynms(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
/************************************************************************
以下是DS18B20的操作程序
************************************************************************/
sbit DQ=P3^3;
unsigned char time; //設(shè)置全局變量,專(zhuān)門(mén)用于嚴(yán)格延時(shí)
/*****************************************************
函數(shù)功能:將DS18B20傳感器初始化,讀取應(yīng)答信號(hào)
出口參數(shù):flag
***************************************************/
bit Init_DS18B20(void)
{
bit flag; //儲(chǔ)存DS18B20是否存在的標(biāo)志,flag=0,表示存在;flag=1,表示不存在
DQ = 1; //先將數(shù)據(jù)線(xiàn)拉高
for(time=0;time<2;time++) //略微延時(shí)約6微秒
;
DQ = 0; //再將數(shù)據(jù)線(xiàn)從高拉低,要求保持480~960us
for(time=0;time<200;time++) //略微延時(shí)約600微秒
; //以向DS18B20發(fā)出一持續(xù)480~960us的低電平復(fù)位脈沖
DQ = 1; //釋放數(shù)據(jù)線(xiàn)(將數(shù)據(jù)線(xiàn)拉高)
for(time=0;time<10;time++)
; //延時(shí)約30us(釋放總線(xiàn)后需等待15~60us讓DS18B20輸出存在脈沖)
flag=DQ; //讓單片機(jī)檢測(cè)是否輸出了存在脈沖(DQ=0表示存在)
for(time=0;time<200;time++) //延時(shí)足夠長(zhǎng)時(shí)間,等待存在脈沖輸出完畢
;
return (flag); //返回檢測(cè)成功標(biāo)志
}
/*****************************************************
函數(shù)功能:從DS18B20讀取一個(gè)字節(jié)數(shù)據(jù)
出口參數(shù):dat
***************************************************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat; //儲(chǔ)存讀出的一個(gè)字節(jié)數(shù)據(jù)
for (i=0;i<8;i++)
{
DQ =1; // 先將數(shù)據(jù)線(xiàn)拉高
_nop_(); //等待一個(gè)機(jī)器周期
DQ = 0; //單片機(jī)從DS18B20讀書(shū)據(jù)時(shí),將數(shù)據(jù)線(xiàn)從高拉低即啟動(dòng)讀時(shí)序
_nop_(); //等待一個(gè)機(jī)器周期
DQ = 1; //將數(shù)據(jù)線(xiàn)"人為"拉高,為單片機(jī)檢測(cè)DS18B20的輸出電平作準(zhǔn)備
for(time=0;time<2;time++)
; //延時(shí)約6us,使主機(jī)在15us內(nèi)采樣
dat>>=1;
if(DQ==1)
dat|=0x80; //如果讀到的數(shù)據(jù)是1,則將1存入dat
else
dat|=0x00;//如果讀到的數(shù)據(jù)是0,則將0存入dat
//將單片機(jī)檢測(cè)到的電平信號(hào)DQ存入r
for(time=0;time<8;time++)
; //延時(shí)3us,兩個(gè)讀時(shí)序之間必須有大于1us的恢復(fù)期
}
return(dat); //返回讀出的十六進(jìn)制數(shù)據(jù)
}
/*****************************************************
函數(shù)功能:向DS18B20寫(xiě)入一個(gè)字節(jié)數(shù)據(jù)
入口參數(shù):dat
***************************************************/
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=0; i<8; i++)
{
DQ =1; // 先將數(shù)據(jù)線(xiàn)拉高
_nop_(); //等待一個(gè)機(jī)器周期
DQ=0; //將數(shù)據(jù)線(xiàn)從高拉低時(shí)即啟動(dòng)寫(xiě)時(shí)序
DQ=dat&0x01; //利用與運(yùn)算取出要寫(xiě)的某位二進(jìn)制數(shù)據(jù),
//并將其送到數(shù)據(jù)線(xiàn)上等待DS18B20采樣
for(time=0;time<10;time++)
;//延時(shí)約30us,DS18B20在拉低后的約15~60us期間從數(shù)據(jù)線(xiàn)上采樣
DQ=1; //釋放數(shù)據(jù)線(xiàn)
for(time=0;time<1;time++)
;//延時(shí)3us,兩個(gè)寫(xiě)時(shí)序間至少需要1us的恢復(fù)期
dat>>=1; //將dat中的各二進(jìn)制位數(shù)據(jù)右移1位
}
for(time=0;time<4;time++)
; //稍作延時(shí),給硬件一點(diǎn)反應(yīng)時(shí)間
}
/*****************************************************
函數(shù)功能:做好讀溫度的準(zhǔn)備
***************************************************/
void ReadyReadTemp(void)
{
Init_DS18B20(); //將DS18B20初始化
WriteOneChar(0xCC); // 跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
delaynms(200); //轉(zhuǎn)換一次需要延時(shí)一段時(shí)間
Init_DS18B20(); //將DS18B20初始化
WriteOneChar(0xCC); //跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0xBE); //讀取溫度寄存器,前兩個(gè)分別是溫度的低位和高位
}
/*****************************************************
函數(shù)功能:顯示溫度的整數(shù)部分
入口參數(shù):x
***************************************************/
void display_temp1(unsigned char x)
{
unsigned char k,l; //j,k,l分別儲(chǔ)存溫度的百位、十位和個(gè)位
k=(x%100)/10; //取十位
l=x%10; //取個(gè)位
P0=0x00;
P0=s8[l]; //將個(gè)位數(shù)字的字符常量寫(xiě)入數(shù)碼管
P2=0xfd; //將十位數(shù)字的字符常量寫(xiě)入數(shù)碼管
delaynms(20); //延時(shí)1ms給硬件一點(diǎn)反應(yīng)時(shí)間
P0=0x00;
P0=s8[k];
P2=0xfe;
delaynms(1);
}
/*****************************************************
函數(shù)功能:顯示溫度的小數(shù)數(shù)部分
入口參數(shù):x
***************************************************/
void display_temp2(unsigned char x)
{
P0=0x00;
P0=s8[x];
P2=0xfb;
delaynms(20);
}
/*****************************************************
函數(shù)功能:主函數(shù)
***************************************************/
void main(void)
{
unsigned char TL; //儲(chǔ)存暫存器的溫度低位
unsigned char TH; //儲(chǔ)存暫存器的溫度高位
unsigned char TN; //儲(chǔ)存溫度的整數(shù)部分
unsigned char TD; //儲(chǔ)存溫度的小數(shù)部分
delaynms(5); //延時(shí)5ms給硬件一點(diǎn)反應(yīng)時(shí)間
while(1) //不斷檢測(cè)并顯示溫度
{
flag=0;
ReadyReadTemp(); //讀溫度準(zhǔn)備
TL=ReadOneChar(); //先讀的是溫度值低位
TH=ReadOneChar(); //接著讀的是溫度值高位
TN=TH*16+TL/16; //實(shí)際溫度值=(TH*256+TL)/16,即:TH*16+TL/16
//這樣得出的是溫度的整數(shù)部分,小數(shù)部分被丟棄了
TD=(TL%16)*10/16; //計(jì)算溫度的小數(shù)部分,將余數(shù)乘以10再除以16取整,
//這樣得到的是溫度小數(shù)部分的第一位數(shù)字(保留1位小數(shù))
display_temp2(TD);
display_temp1(TN); //顯示溫度的整數(shù)部
delaynms(1);
}
}
|
|