完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
#include
#include #define MAXNUM 8 //定义最多有8个 DS18B20 ***it DQ=P2^3; //定义DS18B20数据线 ***it RS=P2^0; //液晶端口控制线端口定义 ***it RW=P2^1; //液晶端口控制线端口定义 ***it E= P2^2; //液晶端口控制线端口定义 unsigned char code lcd0[]={"SEARCH ROMING..."}; unsigned char code lcd1[]={"SEARCH ROM OK!"}; unsigned char code lcd2[]={"The total is:"}; unsigned char code lcd3[]={"No.( ):"}; unsigned char code lcd4[]={'0','1','2','3','4','5','6','7','8','9','.',0xdf,0x43,' '}; //0xdf在1602中是“℃”符号的左上角那个圆,0X43是大写的"C" 他们一起构成了”℃“这个符号 unsigned char dat[6];//用来显示温度的参数 unsigned char temp_l,temp_h,negetiveflag=0,temp_over,t; unsigned char num=0; unsigned int i; idata unsigned char al[MAXNUM]; idata unsigned char ID[MAXNUM][8]; /***********************液晶模块**********************************/ void delaylcd(void)//延时程序 { unsigned char y; for(y=0;y<250;y++); } void LCD_write_com(unsigned char com)//液晶写命令函数 { delaylcd(); RS=0; //RS为1 写命令 RW=0; E=0; E=1; P0=com; E=0; delaylcd(); } void LCD_write_data(unsigned char dat)//液晶写数据函数 { delaylcd(); RS=1; //RS为1 写数据 RW=0; E=0; E=1; P0=dat; E=0; delaylcd(); } void lcdinit(void)//初始化 { LCD_write_com(0x01); //液晶清屏 LCD_write_com(0x38); //1602”功能设置命令字“ 显示2行 每行字体用5*8 ASCII显示 8位数据接口 LCD_write_com(0x0c); //显示控制,开始显示,不显示游标,游标不闪烁 LCD_write_com(0x06); //输入方式为增量输入,不移屏幕 } /************************ds18b20****************************/ void delay_nus(unsigned int n)//延时 程序 一次8+6(进出)=14us { while(n--); } void reset(void) //ds18b20初始化复位操作 { unsigned char x=0; DQ = 1; //DQ复位 delay_nus(8); //稍做延时 DQ = 0; //单片机将DQ拉低 delay_nus(80); //精确延时 大于 480us DQ = 1; //拉高总线 delay_nus(10); x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay_nus(5); } void write_bit(unsigned char dat) //DS18B20 写一位 操作 { DQ = 0; _nop_(); _nop_(); DQ = dat&0x01; delay_nus(5); DQ = 1; } void write_byte(unsigned char dat)//写一个字节 { unsigned char i,j; for (i=8; i>0; i--) { j=dat&0x01; write_bit(j); dat>>=1; } } unsigned char read_2bit(void)//读二位 子程序 { unsigned char i; unsigned char dat = 0; for (i=2;i>0;i--) { DQ = 0; // 给脉冲信号 dat<<=1; DQ = 1; // 给脉冲信号 if(DQ) dat|=0x01; delay_nus(4); } return(dat); } unsigned char read_byte(void)//读一个字节 子程序 { 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_nus(4); } return(dat); } void delay_nms(unsigned int n) { unsigned int j=0; unsigned char i=0; for(j=0;j for(i=0;i<120;i++) { _nop_(); } } } void read_temp(unsigned char num_data)//读取温度 子程序 参数表示读第几个传感器 { unsigned char f; reset(); write_byte(0xcc);//发送跳过ROM号命令 write_byte(0x44);//发送温度转换命令 delay_nms(2000); reset(); write_byte(0x55);//发送匹配ROM号命令 for(f=0;f<8;f++) //8字节ROM号 { write_byte(ID[num_data][f]);//发匹配ROM } delay_nus(100); write_byte(0xbe);//读寄存器命令 delay_nus(100); temp_l=read_byte(); temp_h=read_byte(); } void temp_convert(void)//温度转换 { negetiveflag=0; negetiveflag=temp_h&0x80; if(negetiveflag) { negetiveflag=1; temp_h=~temp_h; if(temp_l==0) { temp_h++; //若低8位全为0且温度为负,取补时就要向高位进1 } temp_l=~temp_l+1; } temp_h<<=4; temp_l>>=4; temp_over=temp_h|temp_l; } /*******************显示***************************/ void search_cartoon(void)//搜索ROM动画 { lcdinit(); LCD_write_com(0x80);//液晶第一行地址 for(i=0;i<16;i++) { LCD_write_data(lcd0[i]); } LCD_write_com(0xc0);//液晶第二行地址 for(i=0;i<16;i++) { LCD_write_data(0xff);//显示类似进度条的黑点 delay_nms(num*80); } } void display_total(void) //显示搜索到的DS18B20传感器数目 { lcdinit(); LCD_write_com(0x80);//第一行地址 for(i=0;i<14;i++) { LCD_write_data(lcd1[i]); } LCD_write_com(0xc0);//第二行地址 for(i=0;i<13;i++) { LCD_write_data(lcd2[i]); } LCD_write_data(lcd4[num]); delay_nms(2000); } void display_ds18b20(i)//显示编号为i的DS18B20的温度// { unsigned int data_b,data_temp,l; data_b=temp_over/100;//百位// data_temp=temp_over%100; dat[0]=data_temp/10;//十位// dat[1]=data_temp%10;//个位// dat[2]=13; //空格 dat[3]=13; //空格 dat[4]=11; //摄氏度符号 dat[5]=12; //摄氏度符号 LCD_write_com(0xc0); for(l=0;l<7;l++) { LCD_write_data(lcd3[l]); } LCD_write_com(0xc4); LCD_write_data(lcd4[++i]); LCD_write_com(0xc8); if(negetiveflag==1) { LCD_write_data(0x2d); } else { LCD_write_data(lcd4[data_b]); } for(l=0;l<6;l++) LCD_write_data(lcd4[dat[l]]); delay_nms(1000); } /***********************自动搜索ROM*****************************/ void search_rom(void)//搜索ROM { unsigned char k=0,l=0,chongtuwei=0,m=0,n=0; unsigned char s=0; unsigned char zhan[MAXNUM]; unsigned char ss[64]; do { reset(); write_byte(0xf0); //搜索ROM命令 for(m=0;m<8;m++) { for(n=0;n<8;n++) { k=read_2bit();//读两位数据 k=k&0x03; s>>=1; if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应 { write_bit (0); ss[(m*8+n)]=0; } else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应 { s=s|0x80; write_bit (1); ss[(m*8+n)]=1; } else if(k==0x00)//读到的数据为0 有冲突位 判断冲突位 { //如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1 chongtuwei=m*8+n+1; if(chongtuwei>zhan[l]) { write_bit (0); ss[(m*8+n)]=0; zhan[++l]=chongtuwei; } else if(chongtuwei s=s|((ss[(m*8+n)]&0x01)<<7); write_bit (ss[(m*8+n)]); } else if(chongtuwei==zhan[l]) { s=s|0x80; write_bit (1); ss[(m*8+n)]=1; l=l-1; } } else { goto loop; } } ID[num][m]=s; } num++; } while(zhan[l]!=0&&(num search_cartoon(); display_total(); } void main (void) { unsigned char i=0,t=0; delay_nms(50); search_rom();//搜索ROM并且存储,把18B20的每一个ROM读取出来,方便下次调用 reset(); while(1) { for(i=0;i read_temp(i); //读编号 i 的ds18b20 的温度 temp_convert(); //调用温度转换 display_ds18b20(i);//显示 编号 i 的温度 } } }//while(1)结束 |
|
相关推荐
4个回答
|
|
|
同求大神解释
|
|
|
|
|
|
大概看了一下你的程序,你还是学生吧。出现没法显示温度的原因很多,一个是读取温度出错,或者读取ROM码出错,还有其他问题等,程序那么长,你只能一个个去排除。
建议先完成一个温度的读取和显示,先不要做多个的,不要去读取MAC地址,等这个行了,再接着去做多个的。最好先在仿真上实现,仿真可以单步运行,一步步排除错误。 还有就是你的程序没用的延时太多了,太浪费CPU资源。不过如果只是玩玩的话,玩玩就过了 |
|
|
|
|
冰融潇 发表于 2015-9-9 15:31 嗯嗯,我是学生,刚自学半个月,我已经可以读一个的温度了,就是想实现读多个,我现在觉得应该是读取ROM码的程序出了问题,因为这个程序是我在读一个的基础上拼接了读ROM码的子函数,正在想办法解决,可以麻烦帮我看看读ROM的子函数有没有问题吗?因为是自学没几天,对单片机的理解还不能融会贯通,改起来好吃力,拜托拜托。 |
|
|
|
|
Mr_sky 发表于 2015-9-14 21:39 这个还真心不好帮,最好能够用仿真调试,然后一步步排除,protues仿真倒是不错。比如先查看读一个ROM的程序,先只读一个,看看有没有问题,然后再去做多个的。读多个ROM网上有很多算法,也有相应的解释。慢慢来吧,这种东西急不得,可以去请教你们的学长们 |
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 11:08 , Processed in 1.515347 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
3874