找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5321|回复: 14
收起左侧

新手求助单片机ds18b20仿真问题,仿真显示乱码

[复制链接]
ID:207108 发表于 2017-6-3 14:51 | 显示全部楼层 |阅读模式
仿真图.png

  1. #include<reg52.h> // 晶振为 11.0592MHz
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. sbit DQ=P2^5;// 接温度传感器
  5. sbit duan=P2^6;// 数码管段选
  6. sbit wei=P2^7; // 数码管位选
  7. uchar code numw[]={0x01,0x02,0x04,0x08,0x10,// 数码管位选
  8. 0x20,0x40,0x80,0x00};
  9. uchar code numd[]={0x3f,0x06,0x5b,0x4f,0x66,// 数码管段选显示( 0—9)
  10. 0x6d,0x7d,0x07,0x7f,0x6f};
  11. uchar code numdg[]={0xbf,0x86,0xdb,0xcf,0xe6,// 数码管“个”位段选显示因为保留一位小数,
  12. 0xed,0xfd,0x87,0xff,0xef};// 所以各位后要显示小数点,所以需要重新编码( 0— 9)
  13. uchar code numfh[]={0x40,0x00}; // 温度 + — 符号位
  14. /******************1ms 延时函数 ****************/
  15. void delay0(uint z)
  16. {
  17. uchar x,y;
  18. for(x=z;x>0;x--)
  19. for(y=110;y>0;y--);
  20. }
  21. /******************15us 延时函数 ****************/
  22. void delay(uint z)
  23. {
  24. while(z--);
  25. }
  26. /****************** 初始化 DS18B20函数 ****************/
  27. void reset_ds18b20()
  28. {
  29. uchar stat=0;
  30. DQ=1;
  31. delay(8);
  32. DQ=0;
  33. delay(80); //600us/12mhz
  34. DQ=1;
  35. delay(8);
  36. stat=DQ; // 高电平为存在,低电平为不存在( stat 应该为 0)
  37. delay(4);
  38. // while(!DQ);/* 等待 DQ 变为高电平
  39. // 因为存在脉冲检测结束后自动拉高 */
  40. //return stat;
  41. }
  42. /****************** 写一个字节函数 ****************/
  43. void write_byte(uchar dat)
  44. {
  45. uchar i;
  46. DQ=1; // 先拉高电平,为写作准备
  47. for(i=0;i<8;i++)
  48. {DQ=0;
  49. DQ=dat&0x01;
  50. delay(4);//DS18B20 采样单片机写给 DQ 线上的数据( 45us) ***************
  51. DQ=1;
  52. dat>>=1;
  53. }
  54. delay(4);
  55. }
  56. /****************** 读一个字节函数 ****************/
  57. uchar read_byte()
  58. {
  59. uchar vaul,i;
  60. DQ=1; // 先拉高电平,为读作准备
  61. for(i=0;i<8;i++)
  62. {
  63. DQ=0;
  64. vaul>>=1;
  65. DQ=1;
  66. if(DQ)
  67. vaul|=0x80;
  68. delay(4);
  69. }
  70. return vaul;
  71. }
  72. /****************** 读取温度值函数 ****************/
  73. int read_temper()
  74. {
  75. uchar templ,temph, flag;
  76. int temp;
  77. reset_ds18b20();// 复位操作
  78. write_byte(0xcc);// 跳过 ROM
  79. write_byte(0x44);// 温度转换
  80. delay(300);//***************************
  81. reset_ds18b20();// 复位操作
  82. write_byte(0xcc);// 跳过 ROM
  83. write_byte(0xbe);// 读内部 RAM 内容
  84. templ=read_byte();
  85. temph=read_byte();
  86. flag=(temph&0x80)>>7;// 判断高字节符号位是 1 还是 0(1 为负温度, 0 为正温度)
  87. if(flag==0)
  88. //temp=(temph<<=4)+((templ&=0xf0)>>4);
  89. temp=(templ+temph*256)*0.625;// 将精度 0.0625 扩大 10 倍,因为 temp 为整形,小数部分读不到
  90. // 此项目需要保留一位小数,所以 x10,小数点后移一位
  91. // 所以可得要保留几位小数点就扩大 10 的几次方
  92. else
  93. temp=(~((templ+temph*256)-1))*(-0.625);
  94. return temp;}
  95. /****************** 显示函数 ****************/
  96. void display(int num)
  97. {
  98. uchar i,zf,bai,shi,ge,fen;
  99. if(num<0)
  100. {
  101. zf=0;// 温度 — 符号位
  102. num=num*(-1);
  103. }
  104. else
  105. zf=1;// 温度 + 符号位
  106. bai=num/1000;
  107. shi=num%1000/100;
  108. ge=num%100/10;
  109. fen=num%10;
  110. for(i=0;i<6;i++)
  111. {

  112. duan=1;
  113. switch(i)
  114. {
  115. case 0: if(zf==0)
  116. P0=numfh[zf];
  117. else
  118. if(bai!=0)
  119. P0=numd[bai];
  120. else
  121. if(shi!=0)
  122. P0=numd[shi];
  123. else
  124. P0=numdg[ge];
  125. break;
  126. case 1: if(zf==0&&shi!=0)
  127. P0=numd[shi];
  128. else
  129. if(zf==0&&shi==0)
  130. P0=numdg[ge];
  131. else
  132. if(zf!=0&&bai!=0)
  133. P0=numd[shi];
  134. else
  135. if(zf!=0&&bai==0&&shi!=0)
  136. P0=numdg[ge];
  137. else
  138. if(zf!=0&&bai==0&&shi==0)
  139. P0=numd[fen];
  140. break;
  141. case 2: if(zf==0&&shi!=0)
  142. P0=numdg[ge];
  143. else
  144. if(zf==0&&shi==0)
  145. P0=numd[fen];
  146. else
  147. if(zf!=0&&bai!=0)
  148. P0=numdg[ge];
  149. else
  150. if(zf!=0&&bai==0&&shi!=0)
  151. P0=numd[fen];
  152. else
  153. if(zf!=0&&bai==0&&shi==0)
  154. P0=0x63;
  155. break;
  156. case 3: if(zf==0&&shi!=0)
  157. P0=numd[fen];
  158. else
  159. if(zf==0&&shi==0)
  160. P0=0x63;
  161. else
  162. if(zf!=0&&bai!=0)
  163. P0=numd[fen];
  164. else
  165. if(zf!=0&&bai==0&&shi!=0)
  166. P0=0x63;
  167. else
  168. if(zf!=0&&bai==0&&shi==0)
  169. P0=0x39;
  170. break;
  171. case 4: if(zf==0&&shi!=0)
  172. P0=0x63;
  173. else
  174. if(zf==0&&shi==0)
  175. P0=0x39;
  176. else
  177. if(zf!=0&&bai!=0)
  178. P0=0x63;
  179. else
  180. if(zf!=0&&bai==0&&shi!=0)
  181. P0=0x39;
  182. else
  183. P0=0x00;
  184. break;
  185. case 5: if(zf==0&&shi!=0)
  186. P0=0x39;else
  187. if(zf!=0&&bai!=0)
  188. P0=0x39;
  189. else
  190. P0=0x00;
  191. break;
  192. }
  193. duan=0;
  194. P0=0x00;// 消影
  195. wei=1;
  196. P0=numw[i];
  197. wei=0;
  198. P1=0x00;// 消影
  199. delay0(10);
  200. }
  201. }
  202. /****************** 主函数 ****************/
  203. void main()
  204. {
  205. while(1)
  206. {
  207. display(read_temper());
  208. }
  209. }

复制代码
回复

使用道具 举报

ID:123289 发表于 2017-6-3 19:25 | 显示全部楼层
弄清段码组字符的原理就一定能解决问题。
回复

使用道具 举报

ID:207108 发表于 2017-6-3 20:58 | 显示全部楼层
yzwzfyz 发表于 2017-6-3 19:25
弄清段码组字符的原理就一定能解决问题。

我是初学,不是太懂,能帮忙找一下具体问题吗
回复

使用道具 举报

ID:111634 发表于 2017-6-3 23:23 | 显示全部楼层
本帖最后由 zl2168 于 2017-6-4 08:23 编辑

显示函数太复杂,没必要。介绍你一个案例,供参考!
Proteus仿真一下,确认有效。
实例97 DS18B20测温.rar (51.78 KB, 下载次数: 30)
回复

使用道具 举报

ID:207108 发表于 2017-6-4 15:05 | 显示全部楼层
zl2168 发表于 2017-6-3 23:23
显示函数太复杂,没必要。介绍你一个案例,供参考!
先Proteus仿真一下,确认有效。

先说声谢谢!书我会去看的,但还是想知道我这个为什么有问题,显示程序不知道哪里有问题了
回复

使用道具 举报

ID:111634 发表于 2017-6-4 22:15 | 显示全部楼层
wdg 发表于 2017-6-4 15:05
先说声谢谢!书我会去看的,但还是想知道我这个为什么有问题,显示程序不知道哪里有问题了

那么多if-else,太复杂,程序不是这样编的。至于哪里错了,你的程序太冗长,一般人没耐心没时间看的,只有自己对照正确的程序,耐心细致的查找。
回复

使用道具 举报

ID:207882 发表于 2017-6-5 08:32 | 显示全部楼层
先单独调试数码管看显示正不正常,再看DS18b20程序部分,,时序很重要
回复

使用道具 举报

ID:207882 发表于 2017-6-5 08:33 | 显示全部楼层
先调试数码管,看能不能正常显示,再看18B20程序,主要时序不用弄错
回复

使用道具 举报

ID:201102 发表于 2017-6-5 18:59 | 显示全部楼层
数码管显示程序太长了,就算实现了基本功能速度也会很慢
回复

使用道具 举报

ID:207108 发表于 2017-6-6 13:31 | 显示全部楼层
改了一下显示程序,还是乱码,各位大佬帮忙看一下啊,到底哪里有问题
void display(int num)
{
uchar i,zf,bai,shi,ge,fen;
if(num<0)
{
zf=0;// 温度 — 符号位

}
else
zf=1;// 温度 + 符号位
bai=num/1000;
shi=num%1000/100;
ge=num%100/10;
fen=num%10;
for(i=0;i<7;i++)
{
wei=1;
P0=numw[i];
wei=0;
P1=0x00;// 消影
duan=1;
switch(i)
{
case 0: if(zf==0)
P0=numfh[zf];
else
P0=0x00;
delay0(5);
case 1: if(bai!=0)
P0=numd[bai];
else
P0=0x00;
delay0(5);
case 2: if(shi!=0)
P0=numd[shi];
else
if(bai==0)
P0=0x00;
else
P0=0x3f;
delay0(5);
case 3: if(ge!=0)
P0=numdg[ge];
delay0(5);
case 4:
P0=numd[fen];
delay0(5);
case 5:
P0=0x63;
delay0(5);
case 6:
P0=0x39;
delay0(5);       
}
duan=0;
P0=0x00;// 消影
delay0(5);
}
}
回复

使用道具 举报

ID:111634 发表于 2017-6-7 10:15 | 显示全部楼层
给了你正确的东西,你不去看,那么你就等吧!网上有多少忽悠人的东西,给你实实在在的,你不看不学,唉!
回复

使用道具 举报

ID:208743 发表于 2017-6-7 11:30 | 显示全部楼层
不要总用百度的东西,要自己写
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表