找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机串口中断程序逻辑问题求助

[复制链接]
跳转到指定楼层
楼主
ID:453144 发表于 2019-11-4 21:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为什么串口中断这里用if判断就可以发送数组里的全部数据,而用while循环就只能发送出一位数据。感觉逻辑上走不通啊,求大神讲解一下

单片机源程序如下:
  1. #include <reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4.         
  5. bit cmdArrived = 0; //命令到达flag
  6. uchar cmdIndex = 0;
  7. uchar *ptrTxd ;
  8. uchar cmdTxd = 0;

  9. uchar arry1[] = "1-HELLO!\r\n";
  10. uchar arry2[] = {1,2};
  11. uchar arry3[] = {1,2,3,4};
  12. uchar arry4[] = {1,2,3,4,5,6,7,8};

  13. void ConfigUART(uint baud);
  14. int main(void)
  15. {
  16.         EA = 1;
  17.         ConfigUART(9600);
  18.         
  19.         while(1)
  20.         {
  21.                 if(cmdArrived)
  22.                 {
  23.                         cmdArrived = 0;
  24.                         switch(cmdIndex)
  25.                         {
  26.                         case 1:  ptrTxd = arry1;
  27.                                                         cmdTxd        = sizeof(arry1);  //发几个字节               
  28.                                                         TI = 1;
  29.                                                         break;
  30.                         case 2:  ptrTxd = arry2;
  31.                                                         cmdTxd        = sizeof(arry2);  //发几个字节               
  32.                                                         TI = 1;
  33.                                                         break;
  34.                         case 3:  ptrTxd = arry3;
  35.                                                         cmdTxd        = sizeof(arry3);  //发几个字节               
  36.                                                         TI = 1;
  37.                                                         break;
  38.                         case 4:  ptrTxd = arry4;
  39.                                                         cmdTxd        = sizeof(arry4);  //发几个字节               
  40.                                                         TI = 1;
  41.                                                         break;
  42.                         default: break;
  43.                         }
  44.                         
  45.                 }
  46.         }
  47.         return 0;
  48. }

  49. void ConfigUART(uint baud)
  50. {
  51.         SCON = 0X50;
  52.         TMOD &= 0X0F;
  53.         TMOD |= 0X20;
  54.         //TMOD = 0X20;
  55.         TL1 = TH1 = 256-(11059200/12/2/16)/baud;
  56.         ET1 = 0;  //强调T1做波特率发生器时不能做别的事情
  57.         TR1 = 1;
  58.         ES =1;
  59. }

  60. void interrupttimer() interrupt 4
  61. {
  62.         //static uchar cnt = 0;
  63.         
  64.         if(RI)
  65.         {
  66.                  RI = 0;
  67.                  cmdIndex = SBUF;
  68.                  cmdArrived = 1;
  69.         }
  70.         if(TI)
  71.         {
  72.                 TI = 0;
  73.                 if(cmdTxd > 0)
  74.                 {
  75.                                 SBUF = *ptrTxd;
  76.                                 cmdTxd--;
  77.                                 ptrTxd++;
  78.                 }
  79.                
  80.         }
  81. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:635290 发表于 2019-11-5 08:33 | 只看该作者
BUFF里面一有内容就会产生中断
回复

使用道具 举报

板凳
ID:631219 发表于 2019-11-5 10:10 | 只看该作者
本帖最后由 oldwood_hmgh 于 2019-11-5 11:36 编辑
dcr1105 发表于 2019-11-5 08:33
BUFF里面一有内容就会产生中断

不完全是这样,接收时SBUFF里面有可用的内容就会产生中断,这时RI置位。发送时SBUFF发送完一个字节变成空的时才产生中断,此时TI置位,请求主机继续发送或终止发送。由于发送和接收使用同一个中断号,所以中断服务程序里必须判断是TI置位还是RI置位,作出相应处理。
回复

使用道具 举报

地板
ID:213173 发表于 2019-11-5 11:53 | 只看该作者
用while循环发送数组中字符串是以下标超出为0来判断结束。如果发送不含0的数字串也是可以的,因为遇0就会跳出。要在末尾加0,否则会出错。
程序改这样试试。
  1. #include<reg52.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. uchar arry1[] = "1-HELLO!\r\n";  //文本模式接收
  5. uchar arry2[] = {1,2,0};                        //HEX 模式接收
  6. uchar arry3[] = {1,2,3,4,0};
  7. uchar arry4[] = {1,2,3,4,5,6,7,8,0};

  8. uchar *ptrTxd;
  9. uchar cmdTxd = 0;

  10. void ConfigUART()
  11. {
  12.         SCON = 0x50;
  13.         TMOD = 0x20;
  14.         TH1 = 0xfd;
  15.         TL1 = 0xfd;
  16.         TR1 = 1;
  17.         ET1 = 0;
  18.         EA = 1;
  19.         ES =1;
  20. }

  21. void Send_byte(uchar dat)
  22. {
  23.         SBUF = dat;
  24.         while(!TI);
  25.         TI = 0;
  26. }

  27. void Send_string(uchar *p)
  28. {
  29.         while(*p)
  30.         {
  31.                 Send_byte(*p++);
  32.         }
  33. }
  34. void main(void)
  35. {
  36.         ConfigUART();
  37.         while(1);
  38. }
  39. void interrupttimer() interrupt 4
  40. {
  41.         RI = 0;
  42.         cmdTxd=SBUF;
  43.         switch(cmdTxd)
  44.         {
  45.                 case 1:ptrTxd=arry1;Send_string(ptrTxd);break;
  46.                 case 2:ptrTxd=arry2;Send_string(ptrTxd);break;
  47.                 case 3:ptrTxd=arry3;Send_string(ptrTxd);break;
  48.                 case 4:ptrTxd=arry4;Send_string(ptrTxd);break;
  49.                 default: break;
  50.         }
  51. }
复制代码
回复

使用道具 举报

5#
ID:453144 发表于 2019-11-5 23:17 | 只看该作者
wulin 发表于 2019-11-5 11:53
用while循环发送数组中字符串是以下标超出为0来判断结束。如果发送不含0的数字串也是可以的,因为遇0就会跳 ...

我这里原程序是使用字符串长度作为判断标准的,当长度值减到0时完成发送,我不太明白是if作为一个判断语句,为什么可以让串口把信息都发送出来,不是应该进入一次中断后就只发出一个字节吗
回复

使用道具 举报

6#
ID:213173 发表于 2019-11-6 06:48 | 只看该作者
q977165 发表于 2019-11-5 23:17
我这里原程序是使用字符串长度作为判断标准的,当长度值减到0时完成发送,我不太明白是if作为一个判断语 ...

是因为程序中把本来应该由硬件置1的TI中断请求标志错误的用软件置1导致重复发生中断。
正常操作是:
SBUF = *ptrTxd; //发送一个字节
while(!TI);//等待发送结束,硬件置TI为1
TI = 0;   //软件清0
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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