?? w013.c
字號:
/*******************************************************************************
* 實驗名稱: 數(shù)字溫度表(DS18B20)LCD1620顯示 *
********************************************************************************
* 實驗描述: LCD1620顯示測量的溫度 *
* 實驗說明: DS18B20正常時,顯示“DS18B20 OK”及溫度值 *
* DS18B20沒有安裝時,顯示“DS18B20 ERR0R PLEASE CHECK” *
* 實驗前要在J7上安裝DS18B20 *
* 1:接DS18B20的GND端 *
* 2:接DS18B20的DQ端 *
* 3:接DS18B20的VDD端 *
*******************************************************************************/
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS = P2^3;
sbit LCD_RW = P2^4;
sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;
#define SELECT_LCD() HC138_A=0; HC138_B=1; HC138_C=0
#define NOSELECT_LCD() HC138_A=1; HC138_B=1; HC138_C=1
sbit DQ = P3^7 ; //定義DS18B20端口DQ
bit presence ; //DS18B20初始化成功標(biāo)志位
uchar data temp_data[2] = {0x00,0x00} ; //溫度數(shù)據(jù)緩存
uchar data dis_data[5]={0,0,0,0,0}; //溫度值百十個小數(shù)位及一個數(shù)據(jù)緩存
uchar code dis_code1[ ] = {" DS18B20 OK "} ;
uchar code dis_code2[ ] = {" TEMP: . C "} ;
uchar code dis_code3[ ] = {" DS18B20 ERR0R "} ;
uchar code dis_code4[ ] = {" PLEASE CHECK "} ;
/*溫度小數(shù)部分查表*/
unsigned char code ditab[16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
/*自定義字符*/
unsigned char code mytab[8] = {0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00} ; //度的符號
void Delay(unsigned int num) //us級延時函數(shù)
{
while( --num ) ;
}
bit LCD_Busy() //LCD忙碌狀態(tài)檢測
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
SELECT_LCD();
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0 & 0x80);
NOSELECT_LCD();
return result;
}
LCD_WriteCommand(uchar cmd) //寫指令數(shù)據(jù)到LCD
{
while(LCD_Busy());
LCD_RS = 0;
LCD_RW = 0;
NOSELECT_LCD();
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
SELECT_LCD();
_nop_();
_nop_();
_nop_();
_nop_();
NOSELECT_LCD();
}
LCD_WriteDate(uchar dat) //寫字符顯示數(shù)據(jù)到LCD
{
while(LCD_Busy());
LCD_RS = 1;
LCD_RW = 0;
NOSELECT_LCD();
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
SELECT_LCD();
_nop_();
_nop_();
_nop_();
_nop_();
NOSELECT_LCD();
}
LCD_DisplayPosit(uchar pos) //設(shè)定字符在LCD上顯示的位置
{
LCD_WriteCommand(pos | 0x80);
}
LCD_Init() //LCD初始化
{
LCD_WriteCommand(0x38);
Delay(5);
LCD_WriteCommand(0x0c);
Delay(5);
LCD_WriteCommand(0x06);
Delay(5);
LCD_WriteCommand(0x01);
Delay(5);
}
void LCD_WriteMytab() //自定義字符寫入CGRAM函數(shù)
{
unsigned char i ;
LCD_WriteCommand(0x40) ; //寫CGRAM
for (i = 0 ; i< 8 ; i++)
LCD_WriteDate(mytab[ i ]) ;
}
void LCD_DisplayLine(uchar a[ ],uchar b[ ]) //LCD1620顯示兩行字符函數(shù)
{
uchar m ;
LCD_Init() ; //初始化LCD
LCD_DisplayPosit(0) ; //設(shè)置顯示位置為第一行的第1個字符
m = 0 ;
while(a[m] != '\0')
{ //顯示第一行字符
LCD_WriteDate(a[m]) ;
m++ ;
}
LCD_DisplayPosit(0x40) ; //設(shè)置顯示位置為第二行第1個字符
m = 0 ;
while(b[m] != '\0')
{
LCD_WriteDate(b[m]) ; //顯示第二行字符
m++ ;
}
}
DS18B20_Init(void) //DS18B20初始化函數(shù)
{
DQ = 1 ; //DQ復(fù)位
Delay(8) ; //延時
DQ = 0 ; //單片機將DQ拉低
Delay(90) ; //延時 大于 480us
DQ = 1 ; //拉高總線
Delay(8) ;
presence = DQ ; //如果 presence=0則初始化成功 presence=1則初始化失敗
Delay(100) ;
DQ = 1 ;
return(presence) ; // 返回信號,0=presence,1= no presence
}
ReadOneChar(void) //讀一個字節(jié)數(shù)據(jù)函數(shù)
{
unsigned char i = 0 ;
unsigned char dat = 0 ;
for (i = 8 ; i > 0 ; i--)
{
DQ = 0 ;
dat >>= 1 ;
DQ = 1 ;
if(DQ)
dat |= 0x80 ;
Delay(4) ;
}
return (dat) ;
}
WriteOneChar(unsigned char dat) //寫一個字節(jié)數(shù)據(jù)函數(shù)
{
unsigned char i = 0 ;
for (i = 8 ; i > 0 ; i--)
{
DQ = 0 ;
DQ = dat&0x01 ;
Delay(5) ;
DQ = 1 ;
dat>>=1 ;
}
}
ReadTemperature(void) //讀取溫度函數(shù)
{
DS18B20_Init() ;
WriteOneChar(0xCC) ; //跳過讀序號列號的操作
WriteOneChar(0x44) ; //啟動溫度轉(zhuǎn)換
DS18B20_Init() ;
WriteOneChar(0xCC) ; //跳過讀序號列號的操作
WriteOneChar(0xBE) ; //讀取溫度寄存器
temp_data[0] = ReadOneChar() ; //讀溫度低8位
temp_data[1] = ReadOneChar() ; //讀溫度高8位
}
TemperatureDisplay() //溫度數(shù)據(jù)轉(zhuǎn)換和顯示函數(shù)
{
dis_data[4]=temp_data[0]&0x0f ; //temp_data[0]低4為有效
dis_data[3]=ditab[dis_data[4]]+0x30; //查表得小數(shù)位的值
dis_data[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
dis_data[2]=dis_data[4]%10+0x30; //個位
dis_data[1]=(dis_data[4]/10)%10+0x30; //十位
dis_data[0]=dis_data[4]/100+0x30; //百位
if(dis_data[0]==0x30) //百位為0,不顯示
{
dis_data[0]=0x20;
if(dis_data[1]==0x30) //十位為0,不顯示
dis_data[1]=0x20 ;
}
LCD_DisplayPosit(0x48) ;
LCD_WriteDate(dis_data[0]) ; //百位數(shù)顯示
LCD_DisplayPosit(0x49) ;
LCD_WriteDate(dis_data[1]) ; //十位數(shù)顯示
LCD_DisplayPosit(0x4a) ;
LCD_WriteDate(dis_data[2]) ; //個位數(shù)顯示
LCD_DisplayPosit(0x4c) ;
LCD_WriteDate(dis_data[3]) ; //小數(shù)位數(shù)顯示
LCD_WriteMytab() ; //自定義字符(度的符號)寫入CGRAM
Delay(5) ;
LCD_DisplayPosit(0x4d) ;
LCD_WriteDate(0x00) ; //顯示自定義字符(度的符號)
}
void DS18B20_OkMenu () //DS18B20 OK 菜單顯示函數(shù)
{
LCD_DisplayLine(dis_code1,dis_code2);
}
void DS18B20_ErrorMenu () //DS18B20 ERROR 菜單顯示函數(shù)
{
LCD_DisplayLine(dis_code3,dis_code4);
}
void main() //主函數(shù)
{
DS18B20_OkMenu () ;
do
{
ReadTemperature() ;
TemperatureDisplay() ;
}
while(!presence) ;
DS18B20_ErrorMenu () ;
do
{
DS18B20_Init() ;
}
while(presence) ;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -