找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1683|回复: 6
收起左侧

51单片机通过串口实现双机通信的问题

[复制链接]
ID:650067 发表于 2020-3-29 22:17 | 显示全部楼层 |阅读模式
我用主机的点阵弄了个9-0秒的倒计时,从机给主机发送按键值(主机倒计时是用定时器0,串口用了定时器一,串口的通信是ok的)。
我要实现的功能是:从机扫描按下按键,主机开始显示倒计时。
我现在的问题是:
我的点阵只能显示9(不会变成8),我显示是放在串口中断里面,定时器0只用来计时(50ms一次溢出),串口波特率4800
请问:1.显示的函数应该在哪个地方,中断还是while循环
          2.中断的优先级需不需要改
请大神们帮帮忙。
看看哪里需要修改。

这是单片机代码

  1. u8 Time=0,second=0;
  2. u8 Val=0;

  3. void zhongduan_Init(void)
  4. {
  5.         TMOD = 0x21; //开启定时器0、1
  6.           TH0 = 0x3C;         //设置初始值,定时50ms
  7.           TL0 = 0xB0;
  8.         TH1=0xF3;         //计数器初始值设置,注意波特率是4800
  9.         TL1=0xF3;
  10.           ET0 = 1;  //打开定时器0中断
  11.           TR0 = 0;  //不启动定时器0
  12.         TR1=1;          //打开定时器1
  13.         SM0=0;//设置串口工作方式
  14.         SM1=1;
  15.         REN=1;        //打开串口接收中断
  16.         IP=0x10;
  17.         EA=1;          //打开总中断
  18.         ES=1;//打开串口中断
  19.         
  20. }
  21. void main()
  22. {        
  23.         zhongduan_Init();
  24.         while(1)
  25.         {
  26.         }
  27.         
  28. }
  29. void Timer0() interrupt 1                //中断服务函数
  30. {
  31.     TH0 = 0x3C;        
  32.     TL0 = 0xB0;
  33.         Time++;
  34.         if(Time==20)
  35.         {
  36.                 Time=0;
  37.                 second++;        //一秒时间
  38.                 //if(second>=1)convert();        //心形移位
  39.         }
  40. }
  41. void Usart() interrupt 4
  42. {
  43.         Val=SBUF;
  44.          switch(Val)
  45.         {
  46.                 case 1:
  47.                         display(Val);//显示
  48.                         break;
  49.         }
  50.         RI=0;
  51. }
  52. [\code]
  53. [code=c]
  54. void display(u8 DATa)//点阵显示函数
  55. {        
  56.         u8 j;
  57.         P0=0x7f;
  58.         
  59.         switch(DATa)
  60.         {
  61.                 case 0:                                                //初始画面
  62.                                 for(j=0;j<8;j++)
  63.                                 {
  64.                                         P0=bubian[j];
  65.                                         Senddata(ten[j]);
  66.                                         delay(10);
  67.                                         Senddata(0x00);//消隐
  68.                                 }
  69.                                 break;
  70.                 case 1:        
  71.                                 show_1();
  72.                                 break;
  73.         }
  74. }
  75. void show_1(void)//倒计时显示
  76. {
  77.         u8 j;
  78.         TR0=1;//开启定时器
  79.         
  80.         while(second<10)//时间一到回到初始页面
  81.         {
  82.                 for(j=0;j<8;j++)
  83.                 {
  84.                         P0=bubian[j];
  85.                         Senddata(count[second][j]);
  86.                         delay(5);
  87.                         Senddata(0x00);//消隐
  88.                 }
  89.         }               
  90. }
复制代码

回复

使用道具 举报

ID:164602 发表于 2020-3-30 08:35 | 显示全部楼层
显示函数还是放在主函数里好。要显示的内容通过变量传递标记即可。串口中断服务函数只需要传递显示标记。
回复

使用道具 举报

ID:650067 发表于 2020-3-30 13:54 | 显示全部楼层
HC6800-ES-V2.0 发表于 2020-3-30 08:35
显示函数还是放在主函数里好。要显示的内容通过变量传递标记即可。串口中断服务函数只需要传递显示标记。

好的,谢谢您,但是我现在显示函数放在主循环里面,又有其他问题了。
我从机有几个按键,按键一是开启点阵倒计时,按键二是显示几个logo,我预想的效果是显示完一个按键的东西后回到初始界面,可是这个串口老是发东西过来(已经没按按键了),导致刚回到初始界面就又开始倒计时了,如此反复,请问怎么解决比较妥当
这是main函数:
void main()
{       
        u8 flag=0;
        zhongduan_Init();
        while(1)
        {
                if(flag==0)
                {
                        switch(Val)
                        {
                                case 1:show_1();flag=1;break;
                                case 2:show_2();flag=1;break;               
                                case 3:show_3();flag=1;break;       
                                case 4:show_4();flag=1;break;       
                                default:show_5();flag=1;break;        //初始画面
                        }
                }
                if(flag==1)
                {
                        Val=0;
                        flag=0;
                }
        }
       
}
回复

使用道具 举报

ID:164602 发表于 2020-3-31 08:38 | 显示全部楼层
nimab 发表于 2020-3-30 13:54
好的,谢谢您,但是我现在显示函数放在主循环里面,又有其他问题了。
我从机有几个按键,按键一是开启点 ...

我猜是:你的按键程序中,没有消抖啊,所以就会有由于抖动而产生的好几个“按键”。机械按键,必须要消抖。
这不是你的完整程序,我只能猜了
回复

使用道具 举报

ID:650067 发表于 2020-4-1 09:25 | 显示全部楼层
HC6800-ES-V2.0 发表于 2020-3-31 08:38
我猜是:你的按键程序中,没有消抖啊,所以就会有由于抖动而产生的好几个“按键”。机械按键,必须要消抖 ...

你好,我是用Proteus仿真的,而且有消抖
回复

使用道具 举报

ID:650067 发表于 2020-4-1 09:29 | 显示全部楼层
HC6800-ES-V2.0 发表于 2020-3-31 08:38
我猜是:你的按键程序中,没有消抖啊,所以就会有由于抖动而产生的好几个“按键”。机械按键,必须要消抖 ...

能不能帮我调试一下,谢谢了

project_3.zip

157.11 KB, 下载次数: 8

回复

使用道具 举报

ID:650067 发表于 2020-4-1 17:48 | 显示全部楼层
HC6800-ES-V2.0 发表于 2020-3-31 08:38
我猜是:你的按键程序中,没有消抖啊,所以就会有由于抖动而产生的好几个“按键”。机械按键,必须要消抖 ...

我那个从机按键按下的时候,要等一会才有画面,正常吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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