找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2457|回复: 2
打印 上一主题 下一主题
收起左侧

请问一下protues模拟ds18b20显示总是是15.93是什么原因呢

[复制链接]
跳转到指定楼层
楼主
#include"reg52.h"
  1. #include"myled.h"
  2. #include"ds18b20.h"
  3. #include"delay.h"
  4. #include"lcd1602.h"
  5. #include"stdio.h"
  6. //#include "temp.h"

  7. void Timer0_Init(void);
  8. unsigned char menuflag,ds18b20_timer;
  9. unsigned char timer_us;
  10. unsigned int timer_ms;
  11. unsigned int timer_xs;

  12. void main()
  13. {
  14.         unsigned int ack;
  15.         int ds18b20_temp;//用来接收数据
  16.         int inttemp,dectemp;//保存分离温度inttemp整数部分和dectemp小数部分
  17.         unsigned char str[12];//用来保存数据转换成的字符串ascll码
  18.         unsigned char len;
  19.         
  20.         Timer0_Init();
  21.         lcd1602_init();
  22.         delay1ms(10);
  23.         EA = 1;
  24.         while (1)
  25.         {
  26.           if(menuflag)
  27.                 {
  28. //                        inttemp = 6;
  29. //                        ack = ds18b20_giveOrder(inttemp);
  30. //                        lcd1602set_position(0,1);
  31. //                        lcd1602_write_dat(ack + '0');
  32.                         ack = ds18b20_giveOrder(0);
  33.                         
  34.                         if(ack)
  35.                         {
  36.                                 inttemp = ack>>4;//保留整数部分,即去高4位
  37.                                 dectemp = ack&0x0f;//取小数部分,就是低4位
  38.                                 len = lcd1602_integertostr(inttemp,str);//len就是inttemp的长度,这个函数就是计算长度的
  39.                                 str[len++] = '.';
  40.                                 dectemp = (dectemp*100)/16;   //*0.0625
  41.                                 str[len++] = dectemp/10+'0';  //
  42.                                 str[len++] = dectemp%10+'0';  //
  43.                                 str[len] = '\0';              //结束符
  44.                                 while(len < 6)
  45.                                 {
  46.                                         str[len++] = ' ';//空格填满
  47.                                 }
  48.                                 lcd1602_shwo_str(0,0,str);
  49.                         }
  50. //                                   led_display(timer_ms);
  51.                 }
  52.         }
  53.         
  54. }

  55. void Timer0_Init(void)                //10微秒@12.000MHz
  56. {
  57. //                AUXR |= 0x80;                //定时器时钟1T模式
  58.         TMOD &= 0xF0;                //设置定时器模式
  59.         TMOD |= 0x01;                //设置定时器模式
  60.         TL0 = 0x88;                //设置定时初始值
  61.         TH0 = 0xFF;                //设置定时初始值
  62.         TF0 = 0;                //清除TF0标志
  63.   ET0 = 1;
  64.         TR0 = 1;                //定时器0开始计时
  65. }

  66. void timer0_isr() interrupt 1
  67. {
  68.         TR0 = 0;

  69.         ds18b20_timer = 1;

  70.                
  71.         if(ds18b20_timer == 1)
  72.         {
  73.                 timer_us++;
  74.                 if(timer_us >= 10)
  75.                 {        
  76.                          timer_us = 0;                                
  77.                          timer_ms++;
  78.                         if(timer_ms >= 500)
  79.                         {
  80.                                 timer_ms = 0;
  81.                                 menuflag = ~menuflag;
  82.                                 timer_xs++;        
  83.                                 if(timer_xs >= 1000)
  84.                                 {
  85.                                        
  86.                                 }
  87.                         }
  88.                 }
  89.         }
  90.         TL0 = 0x88;                //设置定时初始值
  91.         TH0 = 0xFF;                //设置定时初始值
  92.         TR0 = 1;
  93. }

  94. #include"ds18b20.h"
  95. #include"intrins.h"

  96. void delay_us(uchar us)//约2us延时函数
  97. {
  98.         while(--us);
  99. }


  100. /*******************************************************************************
  101. * 函 数 名         : Ds18b20ReadByte
  102. * 函数功能                   : 读取一个字节
  103. * 输    入         : 无
  104. * 输    出         : 无
  105. *******************************************************************************/
  106. unsigned char ds18b20_readbyte()
  107. {
  108.         uchar i,dat;
  109.         for(i=0;i<8;i++)
  110.         {
  111.                 ds18b20=0;
  112.                 dat>>=1;
  113.                 ds18b20=1;
  114.                 if(ds18b20)
  115.                         dat|=0x80;
  116.                 delay_us(25);
  117.         }
  118.         return (dat);        
  119. }
  120. /*******************************************************************************
  121. * 函 数 名         : ds18b20_wretebyte
  122. * 函数功能                   : 向18B20写入一个字节
  123. * 输    入         : 无
  124. * 输    出         : 无
  125. *******************************************************************************/
  126. void ds18b20_writebyte(unsigned char dat)
  127. {
  128.         uchar i;
  129.         for(i=0;i<8;i++)
  130.         {
  131.                 ds18b20=0;
  132.                 ds18b20=dat&0x01;
  133.                 delay_us(25);//延时
  134.                 ds18b20=1;//释放总线准备下一次数据的写入
  135.                 dat>>=1;
  136.         }
  137. }

  138. bit ds18b20_init()
  139. {
  140.         bit i;        
  141.         ds18b20=1;
  142.         delay_us(5);
  143.         ds18b20=0;
  144.         delay_us(200);//拉低总线499.45us,总线上的温度传感器将会被全部复位
  145.         delay_us(200);
  146.         ds18b20=1;//释放总线
  147.         delay_us(50);//延时37.95us,等待温度传感器发回存在信号        
  148.         i=ds18b20;
  149.         delay_us(25);//延时141.95us,读取温度传感器存在的时间
  150.         return (i);
  151. }
  152. unsigned int ds18b20_giveOrder(u16 dat)//下达指令
  153.         {
  154.                 unsigned int mynum;
  155.                 unsigned char msb,lsb;
  156.                                       //初始化ds18b20
  157.                 if(dat==0)
  158.                 {
  159.                                 ds18b20_init();
  160.                                 ds18b20_writebyte(0xcc);         //跳过ROM操作命令
  161.                                 ds18b20_writebyte(0x44);         //发送温度转换                                                               
  162.                                 delay1ms(5);
  163.                                 ds18b20_init();
  164.                                 ds18b20_writebyte(0xcc);         //跳过ROM操作命令
  165.                                 ds18b20_writebyte(0xbe);         //发送读取温度命令        
  166.                                 lsb = ds18b20_readbyte();
  167.                                 msb = ds18b20_readbyte();
  168.                                 msb<<=8;
  169.                                 mynum = ((int)msb<<8)+lsb;                        
  170.                 }
  171.                 return mynum;
  172.         }
  173. #ifndef _DS18B20_H_
  174. #define _DS18B20_H_

  175. #include"reg52.h"
  176. #include"delay.h"

  177. #ifndef uchar
  178. #define uchar unsigned char
  179. #endif

  180. #ifndef u16
  181. #define u16 unsigned char
  182. #endif

  183. sbit ds18b20 = P3^7;

  184. unsigned int ds18b20_giveOrder(u16 dat1);//下达指令

  185. #endif


  186. #ifndef _LCD1602_H_
  187. #define _LCD1602_H_

  188. #include"reg52.h"
  189. #include"delay.h"

  190. #define lcd1602_dat P0
  191. //#define LCD1602_4PINS

  192. sbit lcd1602_rs = P2^0;
  193. sbit lcd1602_rw = P2^1;
  194. sbit lcd1602_en = P2^2;

  195. void lcd1602_readbf();
  196. void lcd1602_init();
  197. void lcd1602_write_cmd(unsigned char cmd);
  198. void lcd1602_write_dat(unsigned char dat);
  199. void lcd1602_shwo_str(unsigned char x,unsigned char y,unsigned char *str);
  200. unsigned char lcd1602_integertostr(long dat,unsigned char *str);
  201. void lcd1602set_position(unsigned char x,unsigned char y);


  202. #endif


  203. #include"lcd1602.h"

  204. #ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
  205. void lcd1602_readbf()//读lcd忙函数
  206. {
  207.         unsigned char state;
  208.         unsigned char i;
  209.          lcd1602_dat= 0xff;//IO 口置1 做输入
  210.          lcd1602_dat |= 0xf0;//接四路高四位 口置1 做输入
  211.          lcd1602_rs = 0;
  212.          lcd1602_rw = 1;
  213.          do
  214.          {
  215.                  lcd1602_en = 1;
  216.                  state = lcd1602_dat;//一个脉冲只接四位 第一次为高四位
  217.                  lcd1602_en = 0;
  218.                  i++;                //lcd1602_dat就是p0总io口
  219.                  if(i>50)
  220.                          break;
  221.          }
  222.          while(state & 0x80);
  223.                
  224. }
  225. #else
  226. void lcd1602_readbf()//读lcd忙函数
  227. {
  228.         unsigned char state;
  229.         unsigned char i;
  230. //         lcd1602_dat= 0xff;//IO 口置1 做输入
  231.         //1602必须要接高四位
  232.          lcd1602_dat |= 0xf0;//接四路高四位 口置1 做输入
  233.          lcd1602_rs = 0;
  234.          lcd1602_rw = 1;
  235.          do
  236.          {
  237.                  lcd1602_en = 1;
  238.                  state = lcd1602_dat;//一个脉冲只接四位 第一次为高四位
  239.                  lcd1602_en = 0;
  240.                  delay1ms(1);        //lcd1602_dat就是p0总io口
  241.                  lcd1602_en = 1;      
  242.                  state |= lcd1602_dat; //再次发送 得到低四位
  243.                  lcd1602_en = 0;
  244.                  i++;
  245.                  if(i>50)
  246.                          break;
  247.          }
  248.          while(state & 0x80);
  249.                
  250. }
  251. #endif



  252. #ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
  253. void lcd1602_write_cmd(unsigned char cmd)
  254. {
  255.         lcd1602_readbf();//忙检测
  256.         lcd1602_rs = 0;//函数
  257.         lcd1602_rw = 0;//写
  258.         lcd1602_dat= cmd;//lcd1602_dat就是p0总io口
  259.         delay1ms(1);
  260.         lcd1602_en = 1;
  261.         lcd1602_en = 0;
  262. }
  263. #else
  264. void lcd1602_write_cmd(unsigned char cmd)
  265. {
  266.         lcd1602_readbf();//忙检测
  267.         lcd1602_rs = 0;//函数
  268.         lcd1602_rw = 0;//写
  269.         lcd1602_dat= cmd;//高四位不需要处理,因为接的是高四位
  270.         delay1ms(5);
  271.         lcd1602_en = 1;
  272.         delay1ms(1);
  273.         lcd1602_en = 0;
  274.         lcd1602_dat = cmd << 4;
  275.         delay1ms(5);
  276.         lcd1602_en = 1;
  277.         delay1ms(1);
  278.         lcd1602_en = 0;
  279. }
  280. #endif

  281. #ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
  282. void lcd1602_write_dat(unsigned char dat)
  283. {
  284.         lcd1602_readbf();//忙检测
  285.         lcd1602_rs = 1;//数据
  286.         lcd1602_rw = 0;//写
  287.         lcd1602_dat= dat;//高四位不需要处理,因为接的是高四位
  288.         delay1ms(1);
  289.         lcd1602_en = 1;
  290.         lcd1602_en = 0;
  291. }
  292. #else
  293. void lcd1602_write_dat(unsigned char dat)
  294. {
  295.         lcd1602_readbf();//忙检测
  296.         lcd1602_rs = 1;//数据
  297.         lcd1602_rw = 0;//写
  298.         lcd1602_dat= dat;//高四位不需要处理,因为接的是高四位
  299.         delay1ms(5);
  300.         lcd1602_en = 1;  //lcd1602_dat就是p0总io口
  301.         delay1ms(1);
  302.         lcd1602_en = 0;
  303.         lcd1602_dat = dat << 4;//低四位需要左移 因为接的是高四位所以数据需要左移
  304.         delay1ms(5);
  305.         lcd1602_en = 1;
  306.         delay1ms(1);
  307.         lcd1602_en = 0;
  308. }
  309. #endif

  310. #ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
  311. void lcd1602_init()
  312. {
  313.         lcd1602_write_cmd(0x02);//归位就是复位
  314.         lcd1602_write_cmd(0x06);//进入设置模式
  315.         lcd1602_write_cmd(0x0c);//显示开
  316.         lcd1602_write_cmd(0x38);//8位8位数据口,两行,5*8点阵
  317.         lcd1602_write_cmd(0x01);//清屏
  318. }
  319. #else
  320. void lcd1602_init()
  321. {
  322.         lcd1602_write_cmd(0x02);//归位就是复位
  323.         lcd1602_write_cmd(0x06);//进入设置模式
  324.         lcd1602_write_cmd(0x0c);//显示开
  325. //        lcd1602_write_cmd(0x38);//8位8位数据口,两行,5*8点阵
  326.         lcd1602_write_cmd(0x33);
  327.         delay1ms(5);
  328.         lcd1602_write_cmd(0x32);
  329.         lcd1602_write_cmd(0x28);//4位8位数据口,两行,5*8点阵
  330.         lcd1602_write_cmd(0x01);//清屏
  331. }
  332. #endif

  333. void lcd1602_shwo_str(unsigned char x,unsigned char y,unsigned char *str)//定位加*str指针方式发送字符串
  334. {
  335.         lcd1602_write_cmd(0x38);
  336.         if(y == 0)
  337.         {
  338.                 lcd1602_write_cmd(0x80 + x);
  339.         }else{
  340.                 lcd1602_write_cmd(0xc0 + x);
  341.         }
  342.         while(*str != '\0')// '\0'这个是结束符的意思
  343.         {
  344.                 lcd1602_write_dat(*str++);
  345.         }
  346.         
  347. }

  348. unsigned char lcd1602_integertostr(long dat,unsigned char *str)
  349. {
  350.         unsigned int i = 0;
  351.         unsigned char len = 0;
  352.         unsigned char buf[11];
  353.         if(dat < 0)
  354.         {
  355.                 dat = -dat;//如果是负数,取绝对值
  356.                 *str++ = '-';
  357.                 len++;
  358. //                dat = Numerical_conversion(dat);
  359.                         for(i=0;dat>9; i++)
  360.                         {
  361.                                 buf[i] = dat%10;     //先遇10取余
  362.                                 dat /=10;
  363.                                 len++;                                
  364.                         }
  365.                         *str++ = dat%10 + '0';     //转换ascll码 + '0'或者*0x30
  366.                          len++;
  367.                         for(i=len;i>2;i--)
  368.                         {
  369.                                 *str++ = buf[i-3] + '0';
  370.                         }
  371.                         *str = '\0';

  372.          }
  373.         if(dat > 0)
  374.         {
  375.                         for(i=0;dat>9; i++)
  376.                         {
  377.                                 buf[i] = dat%10;        //先遇10取余
  378.                                 dat /=10;
  379.                                 len++;                                
  380.                         }
  381.                         *str++ = dat%10 + '0';    //转换ascll码 + '0'或者*0x30
  382.                          len++;
  383.                         for(i=len;i>1;i--)
  384.                         {
  385.                                 *str++ = buf[i-2] + '0';
  386.                         }
  387.                                 *str = '\0';
  388.          }

  389.         return len;
  390. }

复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2021-10-1 20:42 | 只看该作者
给你一个示例对照查找问题。
ds18b20 0~120度PWM恒温控制LCD显示 仿真.zip (161.62 KB, 下载次数: 17)

回复

使用道具 举报

板凳
ID:639106 发表于 2021-10-4 09:11 | 只看该作者
延时要长点
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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