標(biāo)題:
18b20+1602制作數(shù)字溫度計(jì)的C51程序
[打印本頁]
作者:
9geren
時(shí)間:
2014-3-21 01:19
標(biāo)題:
18b20+1602制作數(shù)字溫度計(jì)的C51程序
閑來無事,用18b20溫度傳感器和1602液晶做了一個(gè)溫度計(jì),學(xué)習(xí)一下有關(guān)傳感器的時(shí)序和操作,以及1602液晶顯示程序.
效果如下:
53cf4adctx6CXalmJswbc&690.jpeg
(20.49 KB, 下載次數(shù): 180)
下載附件
2014-3-21 01:19 上傳
[分享]18b20+1602制作數(shù)字溫度計(jì)的C51程序硬件連接:
1、18b201腳接GND,3腳接5V電源,2腳接P2.7,并將2腳與電源間串一4.7K電阻;
2、1602 VDD接5V電源,VSS接GND;A接5V電源,K接GND;
3、VO串一1K電阻接5V電源;
4、RS接P1.0,RW接P1.1;
5、使能信號(hào)端E接P1.2;
6、D0-D7分別接P0.0-P0.7.
程序如下(些段程序是用很多別人的程序拼湊的,功能能實(shí)現(xiàn),但肯定不是最優(yōu)化的代碼):
#include
#include
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef char int8;
typedef int int16;
sbit DQ = P2^7; //溫度輸入口
sbit RS = P1^0 ;
sbit RW = P1^1 ;
sbit EN = P1^2 ;
sbit BUSY = P0^7;
#define nops(); {_nop_(); _nop_(); _nop_(); _nop_();} //定義空指令
uint8 i;
uint16 temp,temp2;
unsigned char xiaoshu1,xiaoshu2,xiaoshu;
void wait(void)
{
P0 = 0xFF;
do
{
RS = 0;
RW = 1;
EN = 0;
EN = 1;
}while (BUSY == 1);
EN = 0;
}
void w_dat(uint8 dat)
{
wait();
EN = 0;
P0 = dat;
RS = 1;
RW = 0;
EN = 1;
EN = 0;
}
void w_cmd(uint8 cmd)
{
wait();
EN = 0;
P0 = cmd;
RS = 0;
RW = 0;
EN = 1;
EN = 0;
}
void w_string(uint8 addr_start, uint8 *p)
{
w_cmd(addr_start);
while (*p != '\0')
{
w_dat(*p++);
}
}
void Init_LCD1602(void)
{
w_cmd(0x38); // 16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
w_cmd(0x0C); // 顯示器開、光標(biāo)開、光標(biāo)允許閃爍
w_cmd(0x06); // 文字不動(dòng),光標(biāo)自動(dòng)右移
w_cmd(0x01); // 清屏
}
void delay(uint16 n)
{
while (n--);
}
void delay_ms(uint16 n)
{
uint8 m=120;
while (n--)
while (m--);
}
void DS18b20_reset(void)
{
bit flag=1;
while (flag)
{
while (flag)
{
DQ = 1;
delay(1);
DQ = 0;
delay(50); // 550us
DQ = 1;
delay(6); // 66us
flag = DQ;
}
delay(45); //延時(shí)500us
flag = ~DQ;
}
DQ=1;
}
void write_byte(uint8 val)
{
uint8 i;
for (i=0; i<8; i++)
{
DQ = 1;
_nop_();
DQ = 0;
nops(); //4us
DQ = val & 0x01; //最低位移出
delay(6); //66us
val >>= 1; //右移一位
}
DQ = 1;
delay(1);
}
uint8 read_byte(void)
{
uint8 i, value=0;
for (i=0; i<8; i++)
{
DQ=1;
_nop_();
value >>= 1;
DQ = 0;
nops(); //4us
DQ = 1;
nops(); //4us
if (DQ)
value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
void start_temp_sensor(void)
{
DS18b20_reset();
write_byte(0xCC); // 發(fā)Skip ROM命令
write_byte(0x44); // 發(fā)轉(zhuǎn)換命令
}
int16 read_temp(void)
{
uint8 temp_data[2]; // 讀出溫度暫放
DS18b20_reset(); // 復(fù)位
write_byte(0xCC); // 發(fā)Skip ROM命令
write_byte(0xBE); // 發(fā)讀命令
temp_data[0]=read_byte(); //溫度低8位
temp_data[1]=read_byte(); //溫度高8位
temp = temp_data[1];
temp2=temp_data[1];
temp <<= 8;
temp |= temp_data[0];
temp >>= 4;
xiaoshu1 = (temp_data[0]&0x0f)*10/16; //小數(shù)第一位
xiaoshu2 = (temp_data[0]&0x0f)*100/16;//小數(shù)
xiaoshu=xiaoshu1*10+xiaoshu2; //小數(shù)
//return temp;
}
unsigned char code word1[]={"Temperature:"};
uint8 table1[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07}; //自定義字符數(shù)據(jù)地址
unsigned char table[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//字符℃
uint16 a,j,k,n;
main()
{
while (1)
{
start_temp_sensor();
delay_ms (100); // 延時(shí)0.1秒
read_temp();
a=temp/100;
j=temp/10;
k=temp-100*a-10*j;
Init_LCD1602();
w_cmd(0x40);
for(n=0;n<8;n++)//寫入溫度符號(hào)代碼
{
w_dat(table[n]);
delay(1);
}
w_string(0x80,word1);
w_cmd(0xC4);
if(temp2>0x7f){
w_dat(45); }//如果溫度為負(fù),顯示負(fù)號(hào)
if(a!=0){
w_dat(a+48);}//如果百位是零則不顯示
w_dat(j+48);//十位
w_dat(k+48);//個(gè)位
w_dat(46);
w_dat(xiaoshu1+48);
w_dat(xiaoshu2+48);
w_dat(table1[0]);//溫度符號(hào)
}
}
在編寫程序中,有很多感慨,畢竟自己不是電子專業(yè),純屬業(yè)余愛好而已,所以編寫程序中遇到了一些意想不到的麻煩.
1、在寫延時(shí)程序時(shí),這是在編寫數(shù)碼管顯示程序時(shí)遇到的,當(dāng)時(shí)想改編一下別人的程序:
void led_delay(void)
{
unsigned char i,j;
for(i=0;i<250;i++)
for(j=0;j<250;j++)
;
}
程序中有一嵌套.我想加長(zhǎng)延時(shí)的時(shí)間,所以就想將i或j改大一些,改成300或以上,但燒錄后,卻不成功,當(dāng)時(shí)百思不得其解啊.后來才恍然大悟,char最大取值是255!所以就又加了一層嵌套.
2、在用1602顯示溫度時(shí),顯示簡(jiǎn)單漢字和英文均正常,但讀取18b20的溫度數(shù)值,顯示到1602時(shí),一直是亂碼.當(dāng)時(shí)想了各種辦法,怎么也不成功,從變量到顯示函數(shù)都認(rèn)真研究了一遍,就是找不到問題.偶然機(jī)會(huì),在網(wǎng)上看到,向1602發(fā)送的數(shù)字,1602當(dāng)ASCII碼!一語驚醒夢(mèng)中人啊,將溫度數(shù)字加上48后,一切正常!
發(fā)生了這么兩件簡(jiǎn)單的事情后,我發(fā)現(xiàn),不是專業(yè)出身,沒有經(jīng)過系統(tǒng)學(xué)習(xí)是不行的!所以我從網(wǎng)上找了一套單片機(jī)學(xué)習(xí)教程,系統(tǒng)的學(xué)習(xí)了一遍,雖然沒有達(dá)到精通的程度,但確實(shí)有了很大程度的進(jìn)步!
這套教程由淺入深,循序漸進(jìn),有大量資料和說明,并配有教程中的所有程序,學(xué)習(xí)起來非常方便.
現(xiàn)在只傳了一部分,其余部分陸續(xù)上傳
作者:
huanglipo
時(shí)間:
2014-8-13 14:17
學(xué)習(xí)了支持。
作者:
zhwyf
時(shí)間:
2014-8-18 22:38
可以再加上濕度測(cè)量就完美了
作者:
平淡人生
時(shí)間:
2014-10-12 21:59
******************
作者:
平淡人生
時(shí)間:
2014-10-12 22:00
作者:
風(fēng)緣
時(shí)間:
2014-12-4 14:26
由原理圖嗎
作者:
51hei電控2112312
時(shí)間:
2014-12-20 04:26
很好,正需要
作者:
51hei電控2112312
時(shí)間:
2014-12-20 04:35
學(xué)習(xí)了
作者:
taoge728
時(shí)間:
2014-12-22 14:41
大神 做過數(shù)顯油箱油量測(cè)量控制設(shè)計(jì)?
作者:
51hei電控2112312
時(shí)間:
2014-12-26 02:43
GOOD!!!
作者:
754470345
時(shí)間:
2016-4-16 01:11
贊一個(gè)
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1