M16溫度傳感器DS18B20控制示例程序
//DS18b20的C語(yǔ)言驅(qū)動(dòng)程序,三位數(shù)碼管顯示,讀取當(dāng)前環(huán)境溫度,精度達(dá)0.1度,溫度范圍0-99度
//DS18B20詳細(xì)引腳功能描述1、GND地信號(hào);2、DQ數(shù)據(jù)輸入出引腳。開漏單總線接口引腳。當(dāng)被用在寄生電源下
//也可以向器件提供電源;3、VDD可選擇的VDD引腳。當(dāng)工作于寄生電源時(shí),此引腳必須接地。
//DS18B20的使用方法。DS18B20采用的是1-Wire總線協(xié)議方式
//即在一根數(shù)據(jù)線實(shí)現(xiàn)數(shù)據(jù)的雙向傳輸
//編譯環(huán)境AVRStudio4.13/AVRGCC
//系統(tǒng)時(shí)鐘7.3728MHz,設(shè)置熔絲位為外部高頻石英晶體振蕩,啟動(dòng)時(shí)間4.1ms
//***********************************************************************
//包含文件
//***********************************************************************
#include
#include
#defineF_CPU7372800//單片機(jī)主頻為7.3728MHz,用于延時(shí)子程序
#include
#include
#include
#include//中斷信號(hào)頭文件
//***********************************************************************
//定義變量區(qū)
//CH451各個(gè)功能命令值,根據(jù)需要寫入
//***********************************************************************
#defineCH451_RESET0x0201//復(fù)位
#defineCH451_LEFT MOV 0x0300//設(shè)置移動(dòng)方式-作移
#defineCH451_LEFTCYC0x0301//設(shè)置移動(dòng)方式-左循
#defineCH451_RIGHT MOV 0x0302//設(shè)置移動(dòng)方式-右移
#defineCH451_RIGHTCYC0x0303//設(shè)置移動(dòng)方式-右循
#defineCH451_SYSOFF0x0400//關(guān)顯示、鍵盤、看門狗
#defineCH451_SYSON10x0401//開顯示
#defineCH451_SYSON20x0403//開顯示、鍵盤
#defineCH451_SYSON30x0407//開顯示、鍵盤、看門狗功能
#defineCH451_DSP0x0500//設(shè)置默認(rèn)顯示方式
#defineCH451_BCD0x0580//設(shè)置BCD譯碼方式
#defineCH451_TWINKLE0x0600//設(shè)置閃爍控制
#defineCH451_DIG00x0800//數(shù)碼管位0顯示
#defineCH451_DIG10x0900//數(shù)碼管位1顯示
#defineCH451_DIG20x0a00//數(shù)碼管位2顯示
#defineCH451_DIG30x0b00//數(shù)碼管位3顯示
#defineCH451_DIG40x0c00//數(shù)碼管位4顯示
#defineCH451_DIG50x0d00//數(shù)碼管位5顯示
#defineCH451_DIG60x0e00//數(shù)碼管位6顯示
#defineCH451_DIG70x0f00//數(shù)碼管位7顯示
#defineLED00x0000//數(shù)碼管位0顯示的數(shù)據(jù)
#defineled10x0000//數(shù)碼管位0顯示的數(shù)據(jù);0x0010為不亮
#defineled20x0000//數(shù)碼管位0顯示的數(shù)據(jù)
#defineled30x0010//數(shù)碼管位0顯示的數(shù)據(jù)
#defineled40x0010//數(shù)碼管位0顯示的數(shù)據(jù)
#defineled50x0010//數(shù)碼管位0顯示的數(shù)據(jù)
#defineled60x0010//數(shù)碼管位0顯示的數(shù)據(jù)
#defineled70x0010//數(shù)碼管位0顯示的數(shù)據(jù)
#definedclk0PORTD&=~(1<
#defineDQ_INDDRC&=~(1<
#definedelay_us(x)_delay_us(x)//AVRGCC延時(shí)函數(shù)x(us)
#definedelay_ms(x)_delay_ms(x)//AVRGCC延時(shí)函數(shù)x(ms)
#defineucharunsignedchar
#defineuintunsignedint
uintvalue;
uinttemp,A1,A2,A3;//定義的變量,顯示數(shù)據(jù)處理
ucharflag1;
uchartable[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,
0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
0x0e,0x0f};//數(shù)碼管的BCD碼
//*************************************************************************
//初始化子程序
//*************************************************************************
voidsystem_init()
{
SFIOR=(1<<2)|SFIOR;//PUD=1;關(guān)閉上拉電阻
PORTD=0x70;
DDRD=0x70;
}
voidch451_init()
{
din0;//先低后高,選擇4線輸入
din1;
}
//*************************************************************************
//輸出命令子程序
//定義一無(wú)符號(hào)整型變量存儲(chǔ)12字節(jié)的命令字
//************************************************************************
voidch451_write(unsignedintcommand)
{
unsignedchari;
load0;//命令開始
for(i=0;i<12;i++)
{//送入12位數(shù)據(jù),低位在前
if(command&1)
{
din1;
}
else
din0;
dclk0;
dclk1;//上升沿有效
command>>=1;
}
load1;//加載數(shù)據(jù)
}
//*************************************************************************
//顯示函數(shù)
//*************************************************************************
voiddisplay(uintb_d,uints_d,uintg_d)
{
ch451_init();
ch451_write(CH451_SYSOFF);//關(guān)顯示、鍵盤、看門狗
ch451_write(CH451_SYSON1);//開顯示
ch451_write(CH451_BCD);//設(shè)置BCD譯碼方式
ch451_write(CH451_TWINKLE);//設(shè)置閃爍控制
ch451_write(CH451_DIG0|table[b_d]);//顯示百位數(shù)據(jù)
ch451_write(CH451_DIG1|table[s_d]|0x80);//顯示十位數(shù)據(jù)
ch451_write(CH451_DIG2|table[g_d]);//顯示個(gè)位數(shù)據(jù)
ch451_write(CH451_DIG3|led3);//其他數(shù)碼管不顯示,熄滅狀態(tài)
ch451_write(CH451_DIG4|led4);
ch451_write(CH451_DIG5|led5);
ch451_write(CH451_DIG6|led6);
ch451_write(CH451_DIG7|led7);
}
//*************************************************************************
//DS18B20初始化
//*************************************************************************
unsignedchards1820_reset(void)//初始化和復(fù)位
{
unsignedchari;
DQ_OUT;
DQ_CLR;
delay_us(500);//延時(shí)500uS(480-960)
DQ_SET;
DQ_IN;
delay_us(80);//延時(shí)80uS
i=DQ_R;
delay_us(500);//延時(shí)500uS(保持>480uS)
if(i)
{
return0x00;
}
else
{
return0x01;
}
}
//*************************************************************************
//DS18B20讀一個(gè)字節(jié)函數(shù)
//*************************************************************************
unsignedchards1820_read_byte(void)
{
unsignedchari;
unsignedcharvalue=0;
for(i=8;i!=0;i--)
{
value>>=1;
DQ_OUT;
DQ_CLR;
delay_us(4);//*延時(shí)4uS
DQ_SET;
DQ_IN;
delay_us(10);//*延時(shí)10uS
if(DQ_R)
{
value|=0x80;
}
delay_us(60);//*延時(shí)60uS
}
return(value);
}
//*************************************************************************
//向18B20寫一個(gè)字節(jié)函數(shù)
//*************************************************************************
/*DS18B20字節(jié)寫入函數(shù)*/
voidds1820_write_byte(unsignedcharvalue)
{
unsignedchari;
for(i=8;i!=0;i--)
{
DQ_OUT;
DQ_CLR;
delay_us(4);//延時(shí)4uS
if(value&0x01)
{
DQ_SET;
}
delay_us(80);//延時(shí)80uS
DQ_SET;//位結(jié)束
value>>=1;
}
}
//*************************************************************************
//發(fā)送溫度轉(zhuǎn)換命令
//*************************************************************************
/*啟動(dòng)ds1820轉(zhuǎn)換*/
voidds1820_start(void){
ds1820_reset();
ds1820_write_byte(0xCC);//勿略地址
ds1820_write_byte(0x44);//啟動(dòng)轉(zhuǎn)換
}
//*************************************************************************
//DS8B20讀取溫度信息
//*************************************************************************
unsignedintds1820_read_temp(void)
{
unsignedinti;
unsignedcharbuf[9];
ds1820_reset();
ds1820_write_byte(0xCC);//勿略地址
ds1820_write_byte(0xBE);//讀取溫度
for(i=0;i<9;i++)
{
buf[i]=ds1820_read_byte();
}
i=buf[1];
i<<=8;
i|=buf[0];
value=i;
value=value*0.625;//不是乘以0.0625的原因是為了把小數(shù)點(diǎn)后一位數(shù)據(jù)也轉(zhuǎn)化為可以顯示的數(shù)據(jù)
//比如溫度本身為27.5度,為了在后續(xù)的數(shù)據(jù)處理程序中得到BCD碼,我們先放大到275
//然后在顯示的時(shí)候確定小數(shù)點(diǎn)的位置即可,就能顯示出27.5度了
//value=value*10;
returni;
}
//*************************************************************************
//溫度數(shù)據(jù)處理函數(shù)
//*************************************************************************
voiddata_do(uintd)
{
uintA2t;
A1=d/100;//分出百,十,和個(gè)位
A2t=d%100;
A2=A2t/10;
A3=A2t%10;
}
//*************************************************************************
//主程序
//*************************************************************************
voidmain(void)
{
DDRC=0x00;
PORTC=0xFF;
system_init();//系統(tǒng)初始化
delay_ms(250);
ds1820_reset();//復(fù)位D18B20
while(1)
{
ds1820_start();//啟動(dòng)一次轉(zhuǎn)換
delay_ms(300);//等待轉(zhuǎn)換結(jié)束
ds1820_read_temp();//讀取溫度數(shù)值
data_do(value);//處理數(shù)據(jù),得到要顯示的值
display(A1,A2,A3);//顯示溫度值
delay_ms(1000);//延時(shí)1S
}
}