DS18B20 ATMEGA16

基本介紹

  • 中文名:DS18B20 ATMEGA16
  • 外文名:無
  • 語言:C++
  • 學科:計算機學
簡介,案例,

簡介

#include <avr/io.h>//頭檔案
#include<util/delay.h>//延時函式
#define uchar unsigned char
#define uint unsigned int //宏定義
#define lcd_rs_h PORTC=PORTC|0x01
#define lcd_rs_l PORTC&=~0x01 //定義RS高低電平
#define lcd_rw_h PORTC=PORTC|0x02
#define lcd_rw_l PORTC&=~0x02 //定義RW高低電平
#define lcd_e_h PORTC=PORTC|0x04
#define lcd_e_l PORTC&=~0x04 //定義使能高低電平
#define ds18b20_h PORTD=PORTD|0x08
#define ds18b20_l PORTD&=~0x08 //定義18b20—DQ高低電平
void m16_ddr_init(void); // M16暫存器初始化
void lcd_1602_init(void); //1602液晶初始化
void ds18b20_init(void); //18b20存在脈衝檢測
uchar ds18b20_read(void); //讀18b20一個位元組
void ds18b20_write(uchar date);//寫18b20一個位元組
void t_18b20_transform(void);//將讀出溫度高低位轉換為整數和小數
void write_1602_com(uchar com);//寫1602命令
void write_1602_date(uchar date);//寫1602一個位元組
uchar temp_l,temp_h; //保存溫度低位和高位。
uchar t_integer,t_decimal;// 溫度顯示對應整數部分和小數部分

案例

//新手直觀程式 帶注釋 已驗證 不足之處請指教 謝謝
// 液晶1602接口 R/S=PORTC0 ;RW=PORTC1;E=PORTC2;D0-D7=PORTA;
//DS18B20接口 DQ=PORTD3;
//晶振 11.0592M。
//本人新手初學 聯繫
//com
int main(void)
{
m16_ddr_init();
_delay_ms(300);
lcd_1602_init();
_delay_ms(300);
while(1)
{
ds18b20_init();
ds18b20_init();
ds18b20_write(0xcc);//跳過rom
ds18b20_write(0x44);//啟動溫度轉換
_delay_ms(200);//等待溫度轉換完成低於60MS數據會錯誤
ds18b20_init();
ds18b20_write(0xcc);//跳過rom
ds18b20_write(0xbe);//啟動溫度轉換
temp_l=ds18b20_read();//保存低八位
temp_h=ds18b20_read();//保存高八位
// PORTB=temp_l; //將低8位數據送到PORTB口LED來驗證是否讀到隨溫度變化的數據
if((temp_h&0xf8)!=0x00) //寫入正負溫度標誌
{
write_1602_com(0x80+0x45);
write_1602_date('-');
}
else
{
write_1602_com(0x80+0x45);
write_1602_date('+');
}
t_18b20_transform();//將讀出溫度高低位轉換為整數和小數
write_1602_com(0x80+0x46);//寫入顯示地址
write_1602_date((t_integer/100)+0x30);//將得到的百位數字轉換為ascii碼並顯示
write_1602_com(0x80+0x47);
write_1602_date(((t_integer%100)/10)+0x30);//將得到的十位數字轉換為ascii碼並顯示
write_1602_com(0x80+0x48);
write_1602_date((t_integer%10)+0x30);//將得到的個位數字轉換為ascii碼並顯示
write_1602_com(0x80+0x49);
write_1602_date('.');
write_1602_com(0x80+0x4a);
write_1602_date(t_decimal+0x30);
}
}
void m16_ddr_init(void)
{
DDRA=0xff;
DDRB=0xff;
DDRC=0xff;
DDRD=0xff;
}
void lcd_1602_init(void)
{
write_1602_com(0x38);
write_1602_com(0x0c);
write_1602_com(0x06);
write_1602_com(0x01);
}
void write_1602_com(uchar com)
{
lcd_rs_l;
lcd_rw_l;
lcd_e_l;
PORTA=com;
_delay_ms(1);
lcd_e_h;
_delay_ms(1);
lcd_e_l;
}
void write_1602_date(uchar date)
{
lcd_rs_h;
lcd_rw_l;
lcd_e_l;
PORTA=date;
_delay_ms(1);
lcd_e_h;
_delay_ms(1);
lcd_e_l;
}
void ds18b20_init(void)
{
uchar ds;
ds18b20_h;
_delay_us(10);
ds18b20_l;
_delay_us(600);
ds18b20_h;
_delay_us(80);//讀出存在脈衝時間為40-140us 已驗證取值80;
ds=PIND;
if(!(ds&0x08))//檢測到存在脈衝顯示OK;
{
_delay_us(20);
write_1602_com(0x80+0x40);
write_1602_date('O');
write_1602_com(0x80+0x41);
write_1602_date('K');
}
else//檢測不到存在脈衝顯示NO;
{
write_1602_com(0x80+0x40);
write_1602_date('N');
write_1602_com(0x80+0x41);
write_1602_date('O');
}
}
void ds18b20_write(uchar date)//寫18b20一個位元組
{
uchar aa;
for(aa=0;aa<8;aa++)
{
ds18b20_h;
_delay_us(2);
ds18b20_l;
if(date&0x01) ds18b20_h;
else ds18b20_l;
_delay_us(50);
ds18b20_h;
_delay_us(2);
date=date>>1;
}
_delay_us(12);
}
uchar ds18b20_read(void)//讀18b20一個位元組
{
uchar bb;
uchar dat=0x00;
for(bb=0;bb<8;bb++)
{
ds18b20_h;
_delay_us(2);
ds18b20_l;
_delay_us(2);
ds18b20_h;
_delay_us(6);
dat=dat>>1;
if(PIND&0x08) dat|=0x80;
else dat|=0x00;
_delay_us(35);//時間實際值範圍20-?
}
return(dat);//返回值
}
void t_18b20_transform(void)//溫度轉換
{
uint tl_temp;
if(temp_h&0xf8)
{
temp_l=~temp_l;
temp_h=~temp_h;
tl_temp=temp_l+1;
temp_l=tl_temp;
if(tl_temp>255) temp_h++;
t_integer=temp_h*16+temp_l/16;
t_decimal=(temp_l%16)*10/16;
}
t_integer=temp_h*16+temp_l/16;
t_decimal=((temp_l%16)*10)/16;
}

相關詞條

熱門詞條

聯絡我們