找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5123|回复: 15
收起左侧

如何使液晶屏显示小数点后两位?附单片机代码

[复制链接]
ID:819671 发表于 2021-4-22 16:40 来自手机 | 显示全部楼层 |阅读模式
100黑币
这是温度检测上下限可调keil的程序,现在是液晶屏显示后三位,怎么只让液晶屏显示小数点后两位,求大神解答

IMG_20210422_153632.jpg
回复

使用道具 举报

ID:819671 发表于 2021-4-22 18:50 | 显示全部楼层
  1. #include<reg52.h>
  2. #include"stdio.h"

  3. typedef unsigned char uint8;
  4. typedef unsigned int uint16;

  5. /***************************************************/

  6. sbit RS =P2^6;       //LCD1602的数据命令选择
  7. sbit RW = P2^5;
  8. sbit EN_LCD =P2^7;   //LCD1602的使能信号

  9. sbit BUZZER = P1^5;

  10. sbit K1          = P3^0;        //右
  11. sbit K2   =        P3^1;        //加
  12. sbit K3   = P3^2;        //减


  13. /****************DS18B20引脚**********************/
  14. sbit DS18B20 = P3^7;  //DS18B20数据端
  15. /***********************************************************/
  16. /******************************************************/

  17. void delay(uint16 time);        // 延时函数(6us单位)               
  18. void lcd_ini();                         // LCD1602的初始化
  19. void lcd_order(uint8 date);                // 向LCD1602的写1个指令
  20. void lcd_data(uint8 date);                // 向LCD1602的写1个指令

  21. void xie1602(uint8 add,uint8 daa); //写数据

  22. void xianshi1();//显示温度

  23. uint8 ds18_ini();        //ds18B20初使化函数
  24. void ds18_write(uint8 date);   //功能向DS18B20中写入一个数据
  25. uint8 ds18_read();                           //功能从DS18B20中读出一个数据并返回。
  26. void ds18_check();                           //起动DS18B20行进温度采集,并返回当前温度(tmp)
  27. void xiugai();                 //修改报警范围

  28. long  tmp=0;      //储存温度值
  29. long  t_h=37, t_l=10;          // 温度的上限和下限


  30. bit tmp_hb = 0;  tmp_lb = 0;     //温度上下限调节指示变量

  31. void panduan();                   //判断报警
  32. uint8 hodometer[]= "  H:00   L: 00  ";
  33. uint8 temp[]=           "  wendu:00.00   ";
  34. uint16 ji = 0;
  35. uint8 ku=0;         //biaozhiwei

  36. void main()
  37. {
  38.         lcd_ini();
  39.         ds18_ini();        //ds18B20初使化
  40.            ds18_write(0xcc);  //跳过序列号
  41.            ds18_write(0x44);  //启动温度转换
  42.          xie1602(4,t_h);
  43.          xie1602(12,t_l);
  44.         while(1)
  45.         {
  46.                 ds18_check();  //从DS18B20中读出温度
  47.                 xianshi1();
  48.                 xiugai();
  49.                 panduan();               
  50.         }
  51. }

  52. void xie1602(uint8 add,uint8 daa)
  53. {
  54.         lcd_order(0x80+add);
  55.         lcd_data(0x30+daa/10);
  56.         lcd_data(0x30+daa%10);
  57. }

  58. //判断是否在报警范围内
  59. void panduan()
  60. {
  61.         if(tmp<(t_l*1000)||tmp>(t_h*1000)&&t_l>=0)
  62.         {
  63.                 BUZZER = 0;
  64.                 delay(10);
  65.         }
  66.         else if(t_l<0&&tmp>(t_h*1000))
  67.         {
  68.                 BUZZER = 1;       
  69.         }
  70.         else
  71.                 BUZZER = 1;
  72. }


  73. //选择修改的内容
  74. void xiugai()
  75. {        uint8 jj;
  76.         uint8 i = 0;
  77.         BUZZER = 1;
  78.        
  79.         if(K1==0)
  80.         {
  81.                 while(!K1);
  82.                 while(1)
  83.                 {
  84.                         lcd_order(0x0f);  //开启光标显示
  85.                         lcd_order(0x80+5);//光标显示位置
  86.                         if(K2 == 0)                        //判断加按键按下
  87.                         {
  88.                                 while(K2 == 0);                  //等待按键释放
  89.                                         t_h++;                         //温度上限加1
  90.                                         xie1602(4,t_h);          //将温度上限显示出来
  91.                         }
  92.                         if(K3 == 0)                                   //判断减按键按下
  93.                         {
  94.                                 while(K3 == 0);                        //等待按键释放
  95.                                 if(t_h>t_l)                                //判断 温度上限大于温度下限
  96.                                         t_h--;
  97.                                 xie1602(4,t_h);                         //将温度上限显示出来
  98.                         }
  99.                         if(K1 == 0)                           //后面的注释类似
  100.                         {
  101.                                 while(K1 == 0);
  102.                                 while(1)
  103.                                 {
  104.                                         lcd_order(0x0f);
  105.                                         lcd_order(0x80+13);       
  106.                                         if(K2 == 0)
  107.                                         {
  108.                                                 while(K2 == 0);
  109.                                                 if(t_l<t_h&&t_l>=0)
  110.                                                 {
  111.                                                         lcd_order(0x80+11);
  112.                                                         lcd_data(' ');
  113.                                                         t_l++;
  114.                                                         xie1602(12,t_l);
  115.                                                 }
  116.                                                 else {
  117.                                                         t_l++;
  118.                                                         jj = ~t_l;
  119.                                                         xie1602(12,jj);
  120.                                                 }
  121.                                         }
  122.                                         if(K3 == 0)
  123.                                         {
  124.                                                 while(K3 == 0);
  125.                                                 if(t_l>(-50))
  126.                                                 {
  127.                                                         t_l--;
  128.                                                         if(t_l<0)
  129.                                                                 jj = ~t_l;
  130.                                                 }
  131.                                                 if(t_l>=0)
  132.                                                 {
  133.                                                         lcd_order(0x80+11);
  134.                                                         lcd_data(' ');
  135.                                                         xie1602(12,t_l);
  136.                                                 }
  137.                                                 if(t_l<0)
  138.                                                 {       
  139.                                                         xie1602(12,jj);
  140.                                                         lcd_order(0x80+11);
  141.                                                         lcd_data('-');
  142.                                                 }
  143.                                         }
  144.                                         if(K1 == 0)
  145.                                         {
  146.                                                 while(K1 == 0);
  147.                                                 goto loop;
  148.                                         }               
  149.                                 }
  150.                         }
  151.                 }                               
  152.         }
  153.         loop:BUZZER = 1;       
  154. }

  155. /**********************************************
  156. 函数名:delay
  157. 行参  :time 延时基数
  158. 功能  :用while延时
  159. ************************************************/
  160. // 延时函数(1ms单位)
  161. void delay(uint16 time)
  162. {
  163.         while(time--);
  164. }
  165. /**********************************************
  166. 函数名:lcd_ini
  167. 功能  :LCD1602的初始化
  168. ************************************************/
  169. void lcd_ini()
  170. {
  171.         uint8 i;
  172.                 RW = 0;
  173.           lcd_order(0x38);          //设置1602的显示光标功能
  174.           delay(100);                  
  175.           lcd_order(0x0e);          //显示开及光标设置
  176.           delay(100);
  177.           lcd_order(0x06);          //显示光标移动设置
  178.           delay(100);
  179.           lcd_order(0x01);          //显示清屏
  180.           delay(100);
  181.           lcd_order(0x80);
  182.                   for(i = 0;i<16;i++)
  183.                         lcd_data(hodometer[i]);
  184.   }


  185. /**********************************************
  186. 函数名:lcd_order
  187. 行参  :date 要定入的指令
  188. 功能  :向LCD1602的写1个指令
  189. ************************************************/
  190. void lcd_order(uint8 date)
  191. {
  192.   RS=0;                  //选择写指令  
  193.   EN_LCD=0;          //使能初使化
  194.   P0=date;          //发送指令
  195.   EN_LCD=1;          //开使能
  196.   delay(100);          //延时
  197.   EN_LCD=0;          //关使能
  198. }
  199. /**********************************************
  200. 函数名:lcd_order
  201. 行参  :date 要定入的指令
  202. 功能  :向LCD1602的写1个指令
  203. ************************************************/
  204. void lcd_data(uint8 date)
  205. {
  206.   RS=1;                  //选择写数据  
  207.   EN_LCD=0;          //使能初使化
  208.   P0=date;          //发送指令
  209.   EN_LCD=1;          //开使能
  210.   delay(100);          //延时
  211.   EN_LCD=0;          //关使能
  212. }

  213. /*************************************************************
  214.                                               DS18B20
  215. **************************************************************/
  216. /****************************************
  217. 函数名:    ds18_ini
  218. 功能:      对DS18B20进行初使化,
  219.             若DS18B20是好的则返回1
  220.                         若DS18B20是环的则返回0
  221. ****************************************/
  222. //ds18B20初使化函数,可根据资料上的时序来写
  223. uint8 ds18_ini()
  224. {
  225.   uint8 ans;
  226.   DS18B20 = 1;
  227.   delay(1);
  228.   DS18B20 = 0;
  229.   delay(100);
  230.   DS18B20 = 1;
  231.   delay(6);
  232.   ans = DS18B20;
  233.   delay(100);
  234.    if(!ans)
  235.      return 1;
  236.   else
  237.      return 0;
  238. }

  239. /**********************************
  240. 函数名:    ds18_write
  241. 函数行参:  date(向ds18b20写入的数据)
  242. 功能:      功能向DS18B20中写入一个数据
  243. ***********************************/
  244. void ds18_write(uint8 date)
  245. {
  246.   uint8 i;
  247.   DS18B20=1;
  248.   delay(1);
  249.   for(i=0;i<8;i++)        //根据时序将数据从低到高一位一位发送出来
  250.        {
  251.                     DS18B20 = 0;
  252.                  if(date&0x01) //从低到高取出数据的每位
  253.                  DS18B20 = 1;
  254.                  else
  255.                  DS18B20 = 0;
  256.                  delay(10);
  257.                  DS18B20 = 1;
  258.                  date>>=1;
  259.                  delay(1);
  260.                  
  261.            }


  262. }

  263. /*************************************************
  264. 函数名:    ds18_read
  265. 函数返回值:rate(从ds18b20中读出的数据)
  266. 功能:      功能从DS18B20中读出一个数据并返回。
  267. *************************************************/
  268. uint8 ds18_read()
  269. {
  270.   uint8 i,date = 0;
  271.   DS18B20 = 1;                  //释放总线
  272.   delay(1);
  273.   for(i = 0;i < 8;i ++)          //根据时序将数据从低到高一位一位接收
  274.        {  
  275.              
  276.               DS18B20 = 0;
  277.                   date >>= 1;
  278.                   DS18B20 = 1;
  279.                   if(DS18B20)
  280.                      date |= 0x80;         //将date的一位置1
  281.                   delay(8);
  282.                   DS18B20 = 1;
  283.                   delay(1);
  284.           
  285.            }
  286.    return date;                          //返回读出的数
  287. }
  288. /************************************************************
  289. 函数名:     ds18_check
  290. 函数返回值: tmp(当前温度)
  291. 功能:       起动DS18B20行进温度采集,并返回当前温度(tmp)
  292. *************************************************************/
  293. void ds18_check()
  294. {
  295.   uint8 date1,date2;
  296.   float ta;
  297.   if(ds18_ini())
  298.     {
  299.           
  300.           ds18_write(0xcc);          //跳过序列号
  301.           ds18_write(0x44);          // 启动温度转换
  302.           ds18_ini();                  // 复位
  303.           ds18_write(0xcc);          //跳过序列号
  304.           ds18_write(0xbe);          // 启动读取温度
  305.           date1 = ds18_read();   //读取两个温度字节
  306.           date2 = ds18_read();
  307.           tmp=date2;
  308.           tmp<<=8;
  309.           tmp=tmp|date1;
  310.           ta=tmp*0.0625;
  311.           tmp=ta*1000;
  312.         }


  313. }

  314. void xianshi1()
  315. {
  316.         uint8 i;
  317.         temp[8]=0x30+tmp/10000;
  318.         temp[9]=0x30+tmp/1000%100;
  319.         temp[11]=0x30+tmp/100%100;
  320.         temp[12]=0x30+tmp/10%100;
  321.         temp[13]=0x30+tmp%10;
  322.         lcd_order(0x80+0x40);
  323.         for(i = 0;i<16;i++)
  324.                 lcd_data(temp[i]);       
  325. }
复制代码

这是网友的程序 求解
回复

使用道具 举报

ID:819671 发表于 2021-4-22 18:55 | 显示全部楼层
我自己改成这样好像也不对是乱码请大神帮忙解决
B%MNN2R[4YWJZIXAAR85)M7.png
回复

使用道具 举报

ID:819671 发表于 2021-4-22 21:40 | 显示全部楼层
没人吗
回复

使用道具 举报

ID:213173 发表于 2021-4-22 22:17 | 显示全部楼层
鹤见川 发表于 2021-4-22 18:55
我自己改成这样好像也不对是乱码请大神帮忙解决

给你一个ds18b20+LCD1602显示2位小数的示例参考,但在实践中显示1位小数足以,末位小数频繁变化看的不太舒服。
ds18b20温度LCD显示 仿真.zip (106.94 KB, 下载次数: 45)

评分

参与人数 1黑币 +5 收起 理由
鹤见川 + 5

查看全部评分

回复

使用道具 举报

ID:819671 发表于 2021-4-22 22:24 | 显示全部楼层
wulin 发表于 2021-4-22 22:17
给你一个ds18b20+LCD1602显示2位小数的示例参考,但在实践中显示1位小数足以,末位小数频繁变化看的不太 ...

我们老大强制要后两位小数显示 请问这个程序能更改成显示两位吗求大佬帮助 我自己改改出来显示乱码
回复

使用道具 举报

ID:819671 发表于 2021-4-22 22:29 | 显示全部楼层
wulin 发表于 2021-4-22 22:17
给你一个ds18b20+LCD1602显示2位小数的示例参考,但在实践中显示1位小数足以,末位小数频繁变化看的不太 ...

参考了您的但是改出来还是乱码我懵了
回复

使用道具 举报

ID:160500 发表于 2021-4-22 22:30 | 显示全部楼层
好好看看ds18b20的datasheet就明白了
回复

使用道具 举报

ID:213173 发表于 2021-4-23 05:45 | 显示全部楼层
鹤见川 发表于 2021-4-22 22:29
参考了您的但是改出来还是乱码我懵了

无标题.jpg

回复

使用道具 举报

ID:89515 发表于 2021-4-23 07:50 来自手机 | 显示全部楼层
你图片的分解方法就很好啊,只要温度不大于100,直接将第三位小数缓存不要就行了
回复

使用道具 举报

ID:585428 发表于 2021-4-23 07:53 | 显示全部楼层
没看你的代码。但是我分享下思路,温度读出来以后,将温度*100,比如21.12*100=2112。然后你可以取余将21和12分别用÷和%的方法提取出来放在数组内,然后,显示的时候,你显示21然后显示一个小数点,然后显示12。只要你温度传感器精度够,想显示几位小数都没问题。
回复

使用道具 举报

ID:390416 发表于 2021-4-23 09:47 | 显示全部楼层
回复

使用道具 举报

ID:905171 发表于 2021-4-23 12:04 | 显示全部楼层
本帖最后由 真皮沙发 于 2021-4-23 13:25 编辑

小数乘100化整数,再显示,中间加小数点
回复

使用道具 举报

ID:905171 发表于 2021-4-23 12:06 | 显示全部楼层
void xianshi1()
{
        uint8 i;
        long a;
        a=tmp*100;
        temp[8]=0x30+a/10000;
        temp[9]=0x30+a/1000%10;
        temp[11]=0x30+a/100%10;
        temp[12]=0x2e;
        temp[13]=0x30+a/10%10;
        temp[14]=0x30+a%10;
        lcd_order(0x80+0x40);
        for(i = 0;i<16;i++)
                lcd_data(temp[i]);      
}
回复

使用道具 举报

ID:137736 发表于 2022-9-18 10:46 | 显示全部楼层
先乘上100,注意要转换成int类型,否则取余错误。
回复

使用道具 举报

ID:137736 发表于 2022-9-18 10:50 | 显示全部楼层
先乘上100,将浮点数强制转换成int类型,然后才能取余,分离每位数,否则错误。显示时中间加上小数点。末尾数字跳动时可以用平均值滤波。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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