|
LCD1602溫度檢測顯示程序(ATmega16)
單片機(jī)源程序如下:
- //**********************************************************************//
- //************************* 頭文件定義 **********************//
- //**********************************************************************//
- #include<iom16v.h>
- #include <macros.h>
- //宏定義
- #define uchar unsigned char
- #define uint unsigned int
- //溫度18b20(數(shù)據(jù)線端口)
- #define tmp (PINB&BIT(PB3))
- #define temp_h PORTB |= BIT(PB3)
- #define temp_l PORTB &=~BIT(PB3)
- #define temp_o DDRB |= BIT(PB3)
- #define temp_i DDRB &=~BIT(PB3)
- //LCD1602液晶顯示(數(shù)據(jù)線端口)
- #define rs_h PORTB |= BIT(PB0)//數(shù)據(jù)/命令選擇
- #define rs_l PORTB &=~BIT(PB0)
- #define rw_h PORTB |= BIT(PB1)//讀/寫選擇
- #define rw_l PORTB &=~BIT(PB1)
- #define en_h PORTB |= BIT(PB2)//使能信號
- #define en_l PORTB &=~BIT(PB2)
- //溫度18b20(變量定義)
- unsigned char dat1=0x00;//保存讀出的溫度 L
- unsigned char dat2=0x00;//保存讀出的溫度 H
- unsigned long int dat=0;//保存讀出的溫度 XS
- unsigned char flag=0;//錯誤標(biāo)志位
- //按鍵定義
- unsigned char key1=0;
- unsigned char key2=0;
- //unsigned char key3=0;
- //unsigned char key4=0;
- //返回值變量
- unsigned char keyvalue=0;
- //溫度H
- unsigned char tempH=30;
- //溫度L
- unsigned char tempL=20;
- //**********************************************************************//
- //************************* IO 端口定義 **********************//
- //**********************************************************************//
- void IO_init(void)
- {
- DDRA = 0XFF;
- DDRB = 0XF0;
- DDRC = 0XFF;
- DDRD = 0XFF;
- PORTA = 0X00;
- PORTB = 0X00;
- PORTC = 0XFF;
- PORTD = 0XFF;
- }
- //**********************************************************************//
- //************************* 延時函數(shù) **********************//
- //**********************************************************************//
- void delayms(uint z) //8M晶振下,延時1ms
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=1333;y>0;y--);
- }
- //**********************************************************************//
- //*************************** 18B20 ************************//
- //**********************************************************************//
- void Ds18b20_reset(void)//DS18B20初始化
- {
- uint count;
- temp_o;
- temp_l;
- for(count=700;count>0;count--);//延時480us
- temp_h;
- temp_i;//不須配置PORT內(nèi)部上拉電阻,MCU輸入輸出自動切換
- while((tmp==0x08));//&&(i>0)) i--;
- for(count=700;count>0;count--);//延時480us
- }
- void Ds18b20_write(uchar dat)//向DS18B20寫一個字節(jié)
- {
- uchar count;
- uchar i;
- temp_o;
- for(i=8;i>0;i--)
- {
- temp_l;
- for(count=2;count>0;count--);
- //temp_h;//不能有此語句
- if(dat&0x01==0x01)
- temp_h;
- else
- temp_l;
- for(count=120;count>0;count--);//延時60us
- temp_h;
- dat>>=1;
- }
- }
- uchar Ds18b20_read(void)//從DS18B20讀一個字節(jié)
- {
- uchar i,datt;
- uchar count;
- for(i=8;i>0;i--)
- {
- datt>>=1;
- temp_o;
- temp_l;
- for(count=2;count>0;count--);
- temp_h;//此語句必須有,參考datasheet的P15
- for(count=1;count>0;count--);
- temp_i;
- if(tmp==0x08)
- datt|=0x80;
- for(count=120;count>0;count--); //延時60us
- }
- return datt;
- }
- void temp_Read(void)//溫度讀取
- {
- Ds18b20_reset();//DS18B20初始化
- Ds18b20_write(0xcc);//跳過ROM
- Ds18b20_write(0x44);//發(fā)送溫度轉(zhuǎn)換命令
- delayms(1000);//延時1s,等待溫度轉(zhuǎn)換完成
- Ds18b20_reset();//DS18B20初始化
- Ds18b20_write(0xcc);//跳過ROM
- Ds18b20_write(0xbe);//發(fā)送讀溫度寄存器命令
- dat1=Ds18b20_read();//讀溫度值的低字節(jié)
- dat2=Ds18b20_read();//讀溫度值的高字節(jié)
- }
- void temp_display(void)//溫度顯示
- {
- if(dat2>=240)//dat2溫度值的高字節(jié)為1時為負(fù)溫度
- {
- dat=(~(dat2*256+dat1)+1)*0.625;//負(fù)溫度:取反加一,保留一位小數(shù)
- flag=1;
- }
- else
- {
- dat=(dat2*256+dat1)*0.625;
- flag=0;
- }
- if(flag==1)//負(fù)溫度顯示
- {
- LCD_write_str(0,0," 18B20 ");
- LCD_write_str(3,1,"Temp:");
- LCD_write_str(8,1,"-");// 符號“- ”
- LCD_write_char(9,1,0x30+dat/1000);
- LCD_write_char(10,1,0x30+dat%1000/100);
- LCD_write_char(11,1,0x30+dat%100/10);
- LCD_write_str (12,1,".");// 符號“. ”
- LCD_write_char(13,1,0x30+dat%10);
- }
- if(flag==0)//正溫度顯示
- {
- LCD_write_str(0,0," 18B20 ");
- LCD_write_str(3,1,"Temp:");
- LCD_write_str(8,1," ");// 符號“+ ”
- LCD_write_char(9,1,0x30+dat/1000);
- LCD_write_char(10,1,0x30+dat%1000/100);
- LCD_write_char(11,1,0x30+dat%100/10);
- LCD_write_str (12,1,".");// 符號“. ”
- LCD_write_char(13,1,0x30+dat%10);
- }
- }
- void tempH_Setting(void)//最高溫度設(shè)置顯示
- {
- LCD_write_str(0,0," temp(H)Setting ");
- LCD_write_char(6,1,0x30+tempH%1000/100);
- LCD_write_char(7,1,0x30+tempH%100/10);
- LCD_write_char(8,1,0x30+tempH%10);
- }
- void tempL_Setting(void)//最低溫度設(shè)置顯示
- {
- LCD_write_str(0,0," temp(L)Setting ");
- LCD_write_char(6,1,0x30+tempL%1000/100);
- LCD_write_char(7,1,0x30+tempL%100/10);
- LCD_write_char(8,1,0x30+tempL%10);
- }
- void temp_police(void)//溫度報警
- {
- if(dat/10>=tempH)//最高檢測溫度>=設(shè)定溫度:燈亮
- {
- PORTC&=~BIT(7);
- }
- else
- {
- PORTC|= BIT(7);
- }
- if(dat/10<=tempL)//最低檢測溫度<=設(shè)定溫度:燈亮
- {
- PORTC&=~BIT(6);
- }
- else
- {
- PORTC|= BIT(6);
- }
- }
- //**********************************************************************//
- //*************************** LCD1602 ************************//
- //**********************************************************************//
- void LCD_init(void)//LCD顯示屏初始化函數(shù)
- {
- DDRA = 0xFF; //I/O口方向設(shè)置
- DDRB|=BIT(PB0)|BIT(PB1)|BIT(PB2);
- delayms(15); //上電延時一段時間,使供電穩(wěn)定
- Write_Instruction(0x38); //8bit interface,2line,5*7dots
- delayms(5);
- Write_Instruction(0x38);
- delayms(5);
- Write_Instruction(0x38);
- Write_Instruction(0x08); //關(guān)顯示,不顯光標(biāo),光標(biāo)不閃爍
- Write_Instruction(0x01); //清屏
- delayms(5);
- Write_Instruction(0x04); //寫一字符,整屏顯示不移動
- //Write_Instruction(0x05); //寫一字符,整屏右移
- //Write_Instruction(0x06); //寫一字符,整屏顯示不移動
- //Write_Instruction(0x07); //寫一字符,整屏左移
- delayms(5);
- //Write_Instruction(0x0B); //關(guān)閉顯示(不顯示字符,只有背光亮)
- Write_Instruction(0x0C); //開顯示,光標(biāo)、閃爍都關(guān)閉
- //Write_Instruction(0x0D); //開顯示,不顯示光標(biāo),但光標(biāo)閃爍
- //Write_Instruction(0x0E); //開顯示,顯示光標(biāo),但光標(biāo)不閃爍
- //Write_Instruction(0x0F); //開顯示,光標(biāo)、閃爍均顯示
- }
- void lcd_en(void) //en端產(chǎn)生一個高電平脈沖,控制LCD寫時序
- {
- delayms(1);
- en_h;
- delayms(1);
- en_l;
- }
- void LCD_clear(void)//清屏函數(shù)
- {
- Write_Instruction(0x01);
- delayms(5);
- }
- void Write_Instruction(uchar com)//向LCD1602寫命令
- {
- rs_l;
- rw_l;
- en_h;
- PORTA=com;
- lcd_en();//寫入命令
- }
- void lcd_dat(uchar dat)//向LCD1602寫數(shù)據(jù)
- {
- rs_h;
- rw_l;
- en_h;
- PORTA=dat;
- lcd_en();//寫入數(shù)據(jù)
- }
- void LCD_SET_XY(uchar X,uchar Y)//字符顯示初始地址設(shè)置
- {
- uchar address;
- if(Y==0)
- address=0x80+X;//Y=0,表示在第一行顯示,地址基數(shù)為0x80
- else
- address=0xc0+X;//Y非0時,表時在第二行顯示,地址基數(shù)為0XC0
- Write_Instruction(address);//寫指令,設(shè)置顯示初始地址
- }
- void LCD_write_str(uchar X,uchar Y,uchar *s)//在第X行Y列開始顯示,指針*S所指向的字符串
- {
- LCD_SET_XY(X,Y);//設(shè)置初始字符顯示地址
- while(*s)//逐次寫入顯示字符,直到最后一個字符"/0"
- {
- lcd_dat(*s);//寫入當(dāng)前字符并顯示
- s++;//地址指針加1,指向下一個待寫字符
- }
- }
- void LCD_write_char(uchar X,uchar Y,uchar Wdata)//在第X行Y列開始顯示W(wǎng)data所對應(yīng)的單個字符
- {
- LCD_SET_XY(X,Y);//寫地址
- lcd_dat(Wdata);//寫入當(dāng)前字符并顯示
- }
- void LCD_Start(void)//LCD啟動界面
- {
- LCD_write_str(0,0," 18B20 ");
- LCD_write_str(0,1," temp display ");
- }
- //**********************************************************************//
- //*************************** 按鍵掃描 ************************//
- //**********************************************************************//
- uchar keys(void)
- {
- if(!(PIND&BIT(0)))//溫度顯示
- {
- delayms(20);
- if(!(PIND&BIT(0)))
- {
- LCD_clear();//LCD清屏
- keyvalue=0;
- while(!(PIND&BIT(0)));//等待按鍵抬起
- }
- }
- if(!(PIND&BIT(1)))//最高、最低溫度設(shè)置選擇
- {
- delayms(20);
- if(!(PIND&BIT(1)))
- {
- LCD_clear();//LCD清屏
- key1=key1+1;
- switch(key1)
- {
- case 1:
- tempH_Setting();//最高溫度設(shè)置顯示
- keyvalue=1;//按鍵最高溫度返回值:1
- break;
- case 2:
- tempL_Setting();//最低溫度設(shè)置顯示
- keyvalue=2;//按鍵最低溫度返回值:2
- key1=0;//按鍵清零
- break;
- }
- while(!(PIND&BIT(1)));//等待按鍵抬起
- }
- }
- if(!(PIND&BIT(2)))//溫度加
- {
- delayms(20);
- if(!(PIND&BIT(2)))
- {
- if(keyvalue==1)
- {
- tempH++;
- if(tempH>=100)
- {
- tempH=100;
- }
- tempH_Setting();//最高溫度設(shè)置顯示
- }
- else if(keyvalue==2)
- {
- tempL++;
- if(tempL>=100)
- {
- tempL=100;
- }
- tempL_Setting();//最低溫度設(shè)置顯示
- }
- //while(!(PIND&BIT(2)));//等待按鍵抬起
- }
- }
- if(!(PIND&BIT(3)))//溫度減
- {
- delayms(20);
- if(!(PIND&BIT(3)))
- {
- if(keyvalue==1)
- {
- tempH--;
- if(tempH<=10)
- {
- tempH=10;
- }
- tempH_Setting();//最高溫度設(shè)置顯示
- }
- else if(keyvalue==2)
- {
- tempL--;
- if(tempL<=10)
- {
- tempL=10;
- }
- tempL_Setting();//最低溫度設(shè)置顯示
- }
- //while(!(PIND&BIT(3)));//等待按鍵抬起
- }
- }
- }
- //**********************************************************************//
- //*************************** 主函數(shù) ************************//
- //**********************************************************************//
- void main(void)
- {
- uchar key_j;
- IO_init(); //端口初始化
- LCD_init(); //LCD初始化
- LCD_clear();//LCD清屏
- //LCD_Start();//LCD啟動界面
- while(1)
- {
- keys();
- if(keyvalue==0)
- {
- temp_Read();//溫度讀取
- temp_display();//溫度顯示
- temp_police();//溫度報警
- }
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
LCD1602&DS18B20溫度測試.zip
(254.85 KB, 下載次數(shù): 89)
2018-12-17 16:49 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
|