找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5230|回复: 0
收起左侧

求解决单片机LCD1602光标闪烁问题

[复制链接]
ID:432874 发表于 2018-12-5 22:17 | 显示全部楼层 |阅读模式
小弟单片机萌新,正在做一个课程设计。
求大佬帮我解决一个问题:调时间的时候,所选择的那一位如:时、分、秒处于闪烁状态,调节完毕后继续正常工作。
解释一下程序功能:按下K3时,时钟停止,再按下K1可以切换需要调节的位置(第一次默认为秒),按下K2实现+1。

  1. /*******************************************************************************
  2. * 实验名                  :温度+时钟显示
  3. * 使用的IO             :
  4. * 实验效果       :1602显示温度
  5. *        注意                                         :
  6. *******************************************************************************/

  7. #include<reg51.h>
  8. #include"lcd.h"
  9. #include"ds1302.h"
  10. #include"temp.h"

  11. sbit K1=P3^1;
  12. sbit K2=P3^0;
  13. sbit K3=P3^2;
  14. sbit K4=P3^3;

  15. uchar CNCHAR[6] = "摄氏度";
  16. void Int0Configuration();
  17. void LcdDisplay(int);
  18. void UsartConfiguration();
  19. unsigned char SetState,SetPlace;
  20. void Delay10ms(void);   //误差 0us
  21. void LcdDisplay1();

  22. /*******************************************************************************
  23. * 函数名         : main
  24. * 函数功能                   : 主函数
  25. * 输入           : 无
  26. * 输出                  : 无
  27. *******************************************************************************/

  28. void main()
  29. {
  30.         unsigned char i;
  31.         Int0Configuration();
  32.         UsartConfiguration();
  33.         LcdInit();                         //初始化LCD1602
  34.         LcdWriteCom(0x80+0x4f);        //写地址 80表示初始地址
  35.         LcdWriteData('C');
  36.         Ds1302Init();
  37.         while(1)
  38.         {
  39.                     if(SetState==0)
  40.                 {
  41.                         Ds1302ReadTime();
  42.                 }
  43.                 else
  44.                 {
  45.                         if(K1==0)                //检测按键K1是否按下
  46.                         {
  47.                                 Delay10ms();        //消除抖动
  48.                                 if(K1==0)
  49.                                 {
  50.                                         SetPlace++;         
  51.                                         if(SetPlace>=7)
  52.                                                 SetPlace=0;                                       
  53.                                 }

  54.                                 while((i<50)&&(K1==0))         //检测按键是否松开
  55.                                 {
  56.                                         Delay10ms();
  57.                                         i++;
  58.                                 }
  59.                                 i=0;
  60.                         }
  61.                         if(K2==0)                //检测按键K2是否按下
  62.                         {
  63.                                 Delay10ms();        //消除抖动
  64.                                 if(K2==0)
  65.                                 {
  66.                                         TIME[SetPlace]++;
  67.                                         if((TIME[SetPlace]&0x0f)>9)                                         //换成BCD码。
  68.                                         {
  69.                                                 TIME[SetPlace]=TIME[SetPlace]+6;
  70.                                         }
  71.                                         if((TIME[SetPlace]>=0x60)&&(SetPlace<2))                //分秒只能到59
  72.                                         {
  73.                                                 TIME[SetPlace]=0;
  74.                                         }
  75.                                         if((TIME[SetPlace]>=0x24)&&(SetPlace==2))                //小时只能到23
  76.                                         {
  77.                                                 TIME[SetPlace]=0;
  78.                                         }
  79.                                         if((TIME[SetPlace]>=0x32)&&(SetPlace==3))                //日只能到31
  80.                                         {
  81.                                                 TIME[SetPlace]=0;       
  82.                                         }
  83.                                         if((TIME[SetPlace]>=0x13)&&(SetPlace==4))                //月只能到12
  84.                                         {
  85.                                                 TIME[SetPlace]=0;
  86.                                         }       
  87.                                         if((TIME[SetPlace]>=0x8)&&(SetPlace==5))                //周只能到7
  88.                                         {
  89.                                                 TIME[SetPlace]=1;
  90.                                         }               
  91. //                                        if(SetPlace==5)                //月只能到12
  92. //                                        {
  93. //                                                TIME[SetPlace]=;
  94. //                                        }       
  95.                                 }
  96.                                
  97.                                 while((i<50)&&(K2==0))         //检测按键是否松开
  98.                                 {
  99.                                         Delay10ms();
  100.                                         i++;
  101.                                 }
  102.                                 i=0;
  103.                                
  104.                         }                                               
  105.                 }
  106.                         LcdDisplay1();       
  107.                         LcdDisplay(Ds18b20ReadTemp());        //                Delay1ms(1000);//1s钟刷一次
  108.                           
  109.         }
  110. }

  111. /*******************************************************************************
  112. * 函数名         : LcdDisplay()
  113. * 函数功能                   : LCD显示读取到的温度
  114. * 输入           : v
  115. * 输出                  : 无
  116. *******************************************************************************/
  117. void LcdDisplay(int temp)          //lcd显示
  118. {
  119.    
  120.   unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组
  121.         float tp;  
  122.         if(temp< 0)                                //当温度值为负数
  123.           {
  124.                   LcdWriteCom(0x80+0x49);                //写地址 80表示初始地址
  125.                 SBUF='-';//将接收到的数据放入到发送寄存器
  126.                 while(!TI);                                 //等待发送数据完成
  127.                 TI=0;                                                 //清除发送完成标志位
  128.             LcdWriteData('-');                  //显示负
  129.                 //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
  130.                 temp=temp-1;
  131.                 temp=~temp;
  132.                 tp=temp;
  133.                 temp=tp*0.0625*100+0.5;       
  134.                 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  135.                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  136.                 //算由?.5,还是在小数点后面。

  137.           }
  138.         else
  139.           {                       
  140.                   LcdWriteCom(0x80+0x49);                //写地址 80表示初始地址
  141.             LcdWriteData('+');                 //显示正
  142.                 SBUF='+';//将接收到的数据放入到发送寄存器
  143.                 while(!TI);                                 //等待发送数据完成
  144.                 TI=0;                                                 //清除发送完成标志位
  145.                 tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
  146.                 //如果温度是正的那么,那么正数的原码就是补码它本身
  147.                 temp=tp*0.0625*100+0.5;       
  148.                 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  149.                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  150.                 //算加上0.5,还是在小数点后面。
  151.         }
  152.         datas[0] = temp / 10000;
  153.         datas[1] = temp % 10000 / 1000;
  154.         datas[2] = temp % 1000 / 100;
  155.         datas[3] = temp % 100 / 10;
  156.         datas[4] = temp % 10;

  157.        
  158.         LcdWriteCom(0x80+0x4a);                 //写地址 80表示初始地址
  159.         LcdWriteData('0'+datas[1]); //十位
  160.         SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
  161.         while (!TI);                                 //等待发送数据完成
  162.         TI = 0;

  163.         LcdWriteCom(0x80+0x4b);                //写地址 80表示初始地址
  164.         LcdWriteData('0'+datas[2]); //个位
  165.         SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器
  166.         while (!TI);                                 //等待发送数据完成
  167.         TI = 0;

  168.         LcdWriteCom(0x80+0x4c);                //写地址 80表示初始地址
  169.         LcdWriteData('.');                 //显示 ‘.’
  170.         SBUF = '.';//将接收到的数据放入到发送寄存器
  171.         while (!TI);                                 //等待发送数据完成
  172.         TI = 0;

  173.         LcdWriteCom(0x80+0x4d);                 //写地址 80表示初始地址
  174.         LcdWriteData('0'+datas[3]); //显示小数点  
  175.         SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器
  176.         while (!TI);                                 //等待发送数据完成
  177.         TI = 0;

  178.         LcdWriteCom(0x80+0x4e);                 //写地址 80表示初始地址
  179.         LcdWriteData('0'+datas[4]); //显示小数点
  180.         SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器
  181.         while (!TI);                                 //等待发送数据完成
  182.         TI = 0;
  183.         for(i=0; i<6; i++)
  184.         {
  185.                  SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
  186.                 while (!TI);                                 //等待发送数据完成
  187.                 TI = 0;
  188.         }

  189. }
  190. void LcdDisplay1()
  191. {
  192.         LcdWriteCom(0x80+0X40);
  193.         LcdWriteData('0'+TIME[2]/16);                                //时
  194.         LcdWriteData('0'+(TIME[2]&0x0f));Delay10ms();                                 
  195.         LcdWriteData('-');
  196.         LcdWriteData('0'+TIME[1]/16);                                //分
  197.         LcdWriteData('0'+(TIME[1]&0x0f));Delay10ms();       
  198.         LcdWriteData('-');
  199.         LcdWriteData('0'+TIME[0]/16);                                //秒
  200.         LcdWriteData('0'+(TIME[0]&0x0f));Delay10ms();

  201.         LcdWriteCom(0x80);
  202.         LcdWriteData('2');
  203.         LcdWriteData('0');
  204.         LcdWriteData('0'+TIME[6]/16);                        //年
  205.         LcdWriteData('0'+(TIME[6]&0x0f));
  206.         LcdWriteData('-');
  207.         LcdWriteData('0'+TIME[4]/16);                        //月
  208.         LcdWriteData('0'+(TIME[4]&0x0f));
  209.         LcdWriteData('-');
  210.         LcdWriteData('0'+TIME[3]/16);                        //日
  211.         LcdWriteData('0'+(TIME[3]&0x0f));
  212.         LcdWriteCom(0x8D);
  213.         LcdWriteData('0'+(TIME[5]&0x07));        //星期                         
  214. }

  215.                  

  216. /*******************************************************************************
  217. * 函数名         : Int0Configuration()
  218. * 函数功能                   : 配置外部中断0
  219. * 输入           : 无
  220. * 输出                  : 无
  221. *******************************************************************************/

  222. void Int0Configuration()
  223. {
  224.         //设置INT0
  225.         IT0=1;//跳变沿出发方式(下降沿)
  226.         EX0=1;//打开INT0的中断允许。
  227.         EA=1;//打开总中断       
  228. }
  229. /*******************************************************************************
  230. * 函数名         : Int0()
  231. * 函数功能                   : 外部中断0 中断函数
  232. * 输入           : 无
  233. * 输出                  : 无
  234. *******************************************************************************/

  235. void Int0() interrupt 0                 
  236. {
  237.         Delay10ms();
  238.         if(K3==0)
  239.         {
  240.                 SetState=~SetState;
  241.                 SetPlace=0;
  242.                 Ds1302Init();       
  243.         }
  244. }
  245. /*******************************************************************************
  246. * 函数名         : Delay10ms
  247. * 函数功能                   : 延时函数,延时10ms
  248. * 输入           : 无
  249. * 输出                  : 无
  250. *******************************************************************************/
  251. void Delay10ms(void)   //误差 0us
  252. {
  253.     unsigned char a,b,c;
  254.     for(c=1;c>0;c--)
  255.         for(b=38;b>0;b--)
  256.             for(a=130;a>0;a--);
  257. }
  258. /*******************************************************************************
  259. * 函 数 名         :UsartConfiguration()
  260. * 函数功能                   :设置串口
  261. * 输    入         : 无
  262. * 输    出         : 无
  263. *******************************************************************************/

  264. void UsartConfiguration()
  265. {
  266.         SCON=0X50;                        //设置为工作方式1
  267.         TMOD=0X20;                        //设置计数器工作方式2
  268.         PCON=0X80;                        //波特率加倍
  269.         TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的
  270.         TL1=0XF3;
  271. //        ES=1;                                                //打开接收中断
  272. //        EA=1;                                                //打开总中断
  273.         TR1=1;                                        //打开计数器
  274. }
复制代码


LCD显示温度 时间 串口接收温度.zip

59.06 KB, 下载次数: 16

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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