|
這是原來輔導(dǎo)大學(xué)生電子設(shè)計(jì)大賽時(shí)讓學(xué)生熱身用的,其中溫度符號(hào)是自定義的。
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^3; //溫度輸入口
uint h;
uint temp;
unsigned char presence;
typedef bit BOOL ;
sbit rs = P2^0 ;
sbit rw = P2^1 ;
sbit ep = P2^2;
void delay(int) ;
void delaylcd(uchar) ;
void lcd_wcmd(uchar) ;
void lcd_sef_chr(); //LCD自定義字符程序
BOOL lcd_bz() ;
void lcd_pos(uchar) ;
void lcd_wdat(uchar) ;
void display(uchar,uchar *) ;
code uchar dis1[] = {" Now TEMP is : "} ;
uchar data temp_data[2]={0x00,0x00}; //讀出溫度暫放
unsigned char data dis_buf1[16]; //lcd上排顯示緩沖區(qū)
uchar data displayT[10];
/*****************11us延時(shí)函數(shù)*************************/
void delay(int t)
{
for (;t>0;t--);
}
/****************DS18B20復(fù)位函數(shù)************************/
unsigned char ow_reset(void)
{
DQ = 0; //pull DQ line low
delay(29); // leave it low for 480μs
DQ = 1; // allow line to return high
delay(3); // wait for presence
presence = DQ; // get presence signal
delay(25); // wait for end of timeslot
return(presence); // presence signal returned
} // presence = 0, no part = 1
/****************DS18B20寫命令函數(shù)************************/
//向1-WIRE 總線上寫1個(gè)字節(jié)
void write_byte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_(); //從高拉倒低
DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 us
DQ=val&0x01; //最低位移出
delay(6); //66 us
val=val/2; //右移1位
}
DQ=1;
delay(1);
}
/****************DS18B20讀1字節(jié)函數(shù)************************/
//從總線上取1個(gè)字節(jié)
uchar read_byte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us
DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us
if(DQ)value|=0x80;
delay(6); //66 us
}
DQ=1;
return(value);
}
/****************讀出溫度函數(shù)************************/
read_temp()
{
ow_reset(); //總線復(fù)位
delay(200);
write_byte(0xcc); //發(fā)命令
write_byte(0x44); //發(fā)轉(zhuǎn)換命令
ow_reset();
delay(1);
write_byte(0xcc); //發(fā)命令
write_byte(0xbe);
temp_data[0]=read_byte(); //讀溫度值的第字節(jié)
temp_data[1]=read_byte(); //讀溫度值的高字節(jié)
temp_data[1]&=0x0f;
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0]; // 兩字節(jié)合成一個(gè)整型變量。
//P0=temp;
//temp>>=4; //去掉小數(shù)部分
//P1=temp;
return temp; //返回溫度值
}
//
work_temp(uint temp)
{
uint j,i,m,n;
//if(tem>6348) // 溫度值正負(fù)判斷
// {tem=65536-tem;n=1;} // 負(fù)溫度求補(bǔ)碼,標(biāo)志位置1
i=temp;
i=i&0x000f;
temp>>=4;
temp-=3;//修正系數(shù)
displayT[0]='+';
displayT[1]=temp/100+48; // 取百位數(shù)據(jù)暫存
j=temp%100; // 取后兩位數(shù)據(jù)暫存
displayT[2]=j/10+48; // 取十位數(shù)據(jù)暫存
displayT[3]=j%10+48; // 取個(gè)位數(shù)據(jù)暫存
m=((0x08&i)>>3)*5000+((0x04&i)>>2)*2500+((0x02&i)>>1)*1200+(0x01&i)*625;
displayT[5]=m/1000+48;
//P1=m/10000;
n=m%1000;
displayT[6]=n/100+48;
n%=100;
displayT[7]=n/10+48;
displayT[8]=n%10+48;
}
void delaylcd(uchar ms)
{ // 延時(shí)子程序
uchar i ;
while(ms--)
{
for(i = 0 ; i<250;i++) ;
}
}
BOOL lcd_bz()
{ // 測(cè)試LCD忙碌狀態(tài)
BOOL result ;
rs = 0 ;
rw = 1 ;
ep = 1 ;
result = (BOOL)(P0 & 0x80) ;
ep = 0 ;
return result ;
}
void lcd_wcmd(uchar cmd)
{ // 寫入指令數(shù)據(jù)到LCD
while(lcd_bz()) ;
rs = 0 ;
rw = 0 ;
ep = 0 ;
P0 = cmd ;
ep = 1 ;
ep = 0 ;
}
void lcd_pos(uchar pos)
{ //設(shè)定顯示位置
lcd_wcmd(pos | 0x80) ;
}
void lcd_wdat(uchar dat)
{ //寫入字符顯示數(shù)據(jù)到LCD
while(lcd_bz()) ;
rs = 1 ;
rw = 0 ;
ep = 0 ;
P0 = dat ;
ep = 1 ;
ep = 0 ;
}
void lcd_init()
{ //LCD初始化設(shè)定
lcd_wcmd(0x38) ; //function set
delaylcd(1) ;
lcd_wcmd(0x38) ; //function set
delaylcd(1) ;
lcd_wcmd(0x08) ; //display on/off
delaylcd(1) ;
lcd_wcmd(0x01) ; //清除LCD的顯示內(nèi)容
delaylcd(1) ;
lcd_wcmd(0x06) ; //entry mode set
delaylcd(1) ;
lcd_wcmd(0x0c) ; //entry mode set
delaylcd(1) ;
}
/*---------------
函數(shù)名稱:display()
功能 :在LCD上顯示數(shù)組的數(shù)據(jù)
說明 :先寫顯示地址,后寫顯示數(shù)據(jù)
調(diào)用 :lcd_wcmd(), lcd_pos()
入口參數(shù):pos 寫入的位置,q指向要寫入的數(shù)據(jù)所在的數(shù)組
返回值 :無
----------------*/
void display(uchar pos, uchar *q)
{
uchar i ;
delaylcd(1) ;
lcd_pos(pos) ;
for(i=0 ;i<16;i++)
{
lcd_wdat(*q) ;
q++ ;
delaylcd(10) ;
}
}
void lcd_sef_chr()//自定義字符
{
lcd_wcmd(0x40); //"01 000 000" 第1行地址 (D7D6為地址設(shè)定命令形式 D5D4D3為字符存放位置(0--7),D2D1D0為字符行地址(0--7))
lcd_wdat(0x07); //"XXX 11111" 第1行數(shù)據(jù)(D7D6D5為XXX,表示為任意數(shù)(一般用000),D4D3D2D1D0為字符行數(shù)據(jù)(1-點(diǎn)亮,0-熄滅)
lcd_wcmd(0x41); //"01 000 001" 第2行地址
lcd_wdat(0x05); //"XXX 10001" 第2行數(shù)據(jù)
lcd_wcmd(0x42); //"01 000 010" 第3行地址
lcd_wdat(0x07); //"XXX 10101" 第3行數(shù)據(jù)
lcd_wcmd(0x43); //"01 000 011" 第4行地址
lcd_wdat(0x00); //"XXX 10001" 第4行數(shù)據(jù)
lcd_wcmd(0x44); //"01 000 100" 第5行地址
lcd_wdat(0x00); //"XXX 11111" 第5行數(shù)據(jù)
lcd_wcmd(0x45); //"01 000 101" 第6行地址
lcd_wdat(0x00); //"XXX 01010" 第6行數(shù)據(jù)
lcd_wcmd(0x46); //"01 000 110" 第7行地址
lcd_wdat(0x00); //"XXX 11111" 第7行數(shù)據(jù)
lcd_wcmd(0x47); //"01 000 111" 第8行地址
lcd_wdat(0x00); //"XXX 00000" 第8行數(shù)據(jù)
}
main()
{ lcd_init() ; // 初始化LCD
delaylcd(10) ;
delay(10) ;
lcd_wcmd(0x01) ; //清除LCD的顯示內(nèi)容
ow_reset(); //開機(jī)先轉(zhuǎn)換一次
write_byte(0xcc); //Skip ROM
write_byte(0x44); //發(fā)轉(zhuǎn)換命令
//lcd_wcmd(0x07) ; //entry mode set
delay(1) ;
lcd_sef_chr(); //寫入自定義字符號(hào)
while(1) //"1234567890123456"
{
display(0x00,dis1) ;
work_temp(read_temp()); //處理溫度數(shù)據(jù)
lcd_pos(0x41) ; lcd_wdat('+');
lcd_pos(0x42) ; lcd_wdat(displayT[1]);
lcd_pos(0x43) ; lcd_wdat(displayT[2]);
lcd_pos(0x44) ; lcd_wdat(displayT[3]);
lcd_pos(0x45) ; lcd_wdat('.');
lcd_pos(0x46) ; lcd_wdat(displayT[5]);
lcd_pos(0x47) ; lcd_wdat(displayT[6]);
lcd_pos(0x48) ; lcd_wdat(displayT[7]);
lcd_pos(0x49) ; lcd_wdat(displayT[8]);
lcd_pos(0x4a);
lcd_wdat(dis_buf1[0]);
lcd_pos(0x4b);
lcd_wdat('C');
}
}
|
|