搜索
bottom↓
回复: 8

求关注,Uart中断处理层的问题

[复制链接]

出340入0汤圆

发表于 2013-1-28 08:43:26 | 显示全部楼层 |阅读模式
本帖最后由 ajfan 于 2013-1-28 08:47 编辑

原来普通帖子发过,无奈关注的人不多,只好用悬赏看是否可以有大侠能帮忙解答下

请教各位关于UART接收到串口发出的字符后中断处理的问题:
第1个问题,
   每接收到一个字节后的中断是从语句1开始,然后关中断,只执行一次  if(RI0),然后再开中断,然后第2个字符,重新开始执行中断处理,直到接收完所有的字符?
   或是接收到一个字节后中断从语句1开始,然后关中断,然后执行N次 if(RI0),直到接收完所有字符后退出循环,再开中断,然后退出中断处理?
void UART0_ISR (void) interrupt 4
{
  语句1;
语句2;
  EA=0;  //关中断
  if(RI0)
    {
      RI0=0;
      UART0_Buffer[com_dat] = SBUF0;    //把从串口读出的字符存到数组
    com_dat++;
     }
   EA=1;           
}

第2个问题,如果用8051f的USB调试器硬件仿真uart程序,是不是调试时不能响应UART中断?
谢谢。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-1-28 11:09:30 | 显示全部楼层
定义一个数组,长度》=最大字符串长度,定义全局变量n,用于指向数组中的位置,
开串口,开中断,每次串口中断把收到的字符保存在数组第n位,然后n++;
接收完成后n=0;

必须区别不同符串,防止接收到的多个字符串连在一起:
可以接收一个字节后开定时器,等接收下一个字节时读出间隔时间然后清除定时重新计时,如果超时,处理当前自符串,准备接收下一个字符串;
或者字符串中加入启始标志和结束标志;
或使用固定长度字符串;

你看着写程序吧

出0入0汤圆

发表于 2013-1-28 14:17:26 | 显示全部楼层
void UART0_ISR (void) interrupt 4
{
  语句1;
语句2;
//  EA=0;  //关中断
  if(RI0)
    {
      RI0=0;
      if( com_dat>=sizeof(UART0_Buffer))
     {
            com_dat=0;//或者使用其他方式处理缓冲区溢出
     }
      UART0_Buffer[com_dat] = SBUF0;    //把从串口读出的字符存到数组
    com_dat++;
     }
//  EA=1;           
}

出340入0汤圆

 楼主| 发表于 2013-1-28 15:02:42 | 显示全部楼层
谢谢楼上2位,估计我没有说明白
实际上我想了解,UART中断处理是怎么执行的?是每接收到一个字节就中断一次然后处理,还是中断一次,然后通过  if(RI0)
将所有字节收到后再退出中断?

出0入0汤圆

发表于 2013-1-28 15:06:44 | 显示全部楼层
一个字节中断一次

出340入0汤圆

 楼主| 发表于 2013-1-28 16:12:01 | 显示全部楼层
进入中断后把总中断关掉
然后
  if(RI0)
    {
      RI0=0;
      UART0_Buffer[com_dat] = SBUF0;    //把从串口读出的字符存到数组
    com_dat++;
     }
是否可以将传输的字节通过  if(RI0)一次全部读出而不是每个字节进入一次中断?

出0入0汤圆

发表于 2013-1-28 16:26:10 | 显示全部楼层
一次中断只发送或接收一个数据。
其实一次中断里面可以接收很多字节。但是这样会引起混乱。比方把之前的数据覆盖。这时我一般就在接收到一个数据后用return语句;
比如:if(RI0)
    {
      RI0=0;
      UART0_Buffer[com_dat] = SBUF0;    //把从串口读出的字符存到数组
    com_dat++;
      return;//这个return执行后就返回了。不再继续给数。下次再进入再给数。
     }
希望对你有帮助

出0入0汤圆

发表于 2013-1-28 08:43:27 | 显示全部楼层
本帖最后由 flywater 于 2013-1-28 17:24 编辑

//每次中断只接收一个数据;
void UART0_ISR (void) interrupt 4
{
  if(RI0)  //是接收中断;
  {
      RI0=0;
      UART0_Buffer[com_dat] = SBUF0;    //把从串口读出的字符存到数组
      com_dat=( com_dat < sizeof(UART0_Buffer)-1 ) ? (com_dat+1) :  (sizeof(UART0_Buffer)-1);
  }
  else        //是发送中断;
  {
        TI0=0;
        .......
   }
}

//然后在主程序中调用串口数据处理函数;
void DoSerial()
{
    if(com_dat<SetNum)        //数据未收够,退出;
        return;
    if(UART0_Buffer[0]!=Header)        //命令头不正确,数据无效,扔掉退出  (可选,也可根据情况再增加数据完整性校验 CRC等)
    {
           com_dat=0;
           return;
    }
           ...............数据校验

    //数据接收正确,开始处理
    switch(UART0_Buffer[1])        //处理相应命令;
    {
        case COMMAND1:
           ........
        break;
        case COMMAND2:
           ........
        break;
    }
    //命令处理完成,复位接收缓冲;
    com_dat=0;
}
  

出0入0汤圆

发表于 2013-11-20 15:39:57 | 显示全部楼层
学习了,一次中断只发送或接收一个数据。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 16:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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