词条 | DS18B20 ATMEGA16 |
释义 | #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。 //本人新手初学 联系 //donglele2005 //@163. //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; } |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。