17416|14

74

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

如何做一个串口中断接收程序,一次接收一帧数据 [复制链接]

我想请教一下大家,能否做一个串口中断的接收程序,每次进中断后接收一串数据,遇到指定的标志结束。
我搞了几天,当没办法,能否请朋友帮忙指点一下。
此帖出自stm32/stm8论坛

最新回复

                                 是的,我也觉得没必要用中断接收  详情 回复 发表于 2010-1-29 18:00
点赞 关注
 

回复
举报

58

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
应该可以,接收中断触发后采用查询方式接收
不过不建议这样做,查询方式接收就是等(阻塞),耗时间效率低,影响系统其他工作
建议每次接收中断就处理一个字节,存到数组中,主程序去判断是否收到结束标志
此帖出自stm32/stm8论坛
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
                                 应该可以,利用switch语句就可以,进中断后用case条件判断
此帖出自stm32/stm8论坛
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

4
 
                                 串口通信不是只是半双工的吗
此帖出自stm32/stm8论坛
 
 
 

回复

90

帖子

0

TA的资源

一粒金砂(初级)

5
 
                                 是232还是422还是485?
此帖出自stm32/stm8论坛
 
 
 

回复

92

帖子

0

TA的资源

一粒金砂(初级)

6
 
                                 switch case是可以实现的
此帖出自stm32/stm8论坛
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

7
 
没必要这样做吧?我一般这样做
在isr中buf[front++]=SBUF;收数据
在主程序中
while (front != rear) {
///根据通讯协议处理数据
   if (crc == true) {
        switch (cmd) {
        }
   }
}
中断中不喜欢处理太多事情
此帖出自stm32/stm8论坛
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

8
 


如果发送方发送一个头后,后面的尾迟迟不发(已当机).那么...怎么死的都不知道.
发送倒是可以用DMA一次发帧,因为发送是可控的,主动权在自己,确定他会发送完成.
而接收是被动的.
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

9
 


to aozima:
你说的这个问题是超时,实现的方式也简单。
如果你的系统有操作系统,在设计任务的时候加入一个超时等待处理;
/* pBuf --------- 接收数据的缓冲区指针
   Timeout  ----- 报文超时的时间(或者是操作系统心跳数目)
   Length ------- 任务所期望接收的数据长度
*/
ReceiveData(UINT8 *pBuf, UINT16 Timeout, UINT8 Length, ......)
{
      ……
   RxByteNum = 0;
   while(1){
         RxByteNum  += ReadRxBuf() ;
      if(RxByteNum < Length)
            TaskDelay(Timeout);    // 也可以把这个值设置为1,然后加一个计数器,可以实现最短的等待时间
   }
   ……
}
如果你的系统没有操作系统,只能用一个定时器作为计数操作,
把上面的程序TaskDelay部分替换掉就可以了。
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

10
 
                                 modbus 的接收程序就是这样做的,因为modbus判断两个char之间的延时是3.5个char的时候认为一帧结束,开始唤醒接收任务处理一帧数据.,这需要一个定时器配合工作.
此帖出自stm32/stm8论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

11
 
                                 楼主这种按结束标志结束的方式很好做吧。不需要在中断里面弄,中断不断接收数据写入数组即可,或者用DMA。然后在死循环里面不断读数,读到结束标识就认为结束。如果有超时这个,就加个定时器来定时一下。
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

12
 
7楼的:buf[front++]=SBUF;
前面一定要加上边界判断,否则一不小心系统怎么死的都不知道……
#define bufLen 32//和你的数据帧最大长度有关
u8 buf[bufLen];
……
中断里:
//先判断是否有未处理的帧,如有,则不可以写缓冲区
……
if(front >= _bufLen)//接着判断缓冲区是否溢出
{
      front =0;//或者用其它方式处理缓冲区溢出
}
buf[front++]=SBUF;//缓冲区未满,才可以把数据放进去
……
此帖出自stm32/stm8论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

13
 
综合利用串口中断和定时器
可以利用定时器,判断超时。如果超时,就把接收计数清零并将接收数组index清零,重新开始新一轮接收。
以下是部分代码(有点乱,慢慢看):
  1. vu8 tim4_overrun = (u8)0x00;

  2. vu8 tim4_of_10ms = (u8)0x00;//tim4_overrun_flag 10ms

  3. @far @interrupt void TIM4_IR(void)
  4. {
  5.         TIM4->SR1 &= ~TIM4_SR1_UIF;
  6.         if (++tim4_overrun > (u8)10)
  7.         {
  8.                 tim4_of_10ms |= (u8)0x01;
  9.                 tim4_overrun &= (u8)0x00;
  10.         }
  11.         return;       
  12. }



  13. @far @interrupt void USART_RX(void)
  14. {
  15.         u8 dummy;
  16.        
  17.         //如果没有通讯错误,且接收寄存器非空
  18.         if (!(UART1->SR & 0X0f))
  19.         {
  20.                 TIM4->CNTR &= (u8)0x00;
  21.                 tim4_overrun &=(u8)0x00;
  22.                 if (tim4_of_10ms)
  23.                 {
  24.                         RxCounter &= (u8)0x00;
  25.                         tim4_of_10ms &= (u8)0x00;
  26.                 }
  27.                 TxBuffer[RxCounter++] = UART1->DR;
  28.                
  29.                 if (RxCounter >= BufferSize)
  30.                 {
  31.                         while((UART1->SR & 0x20))//等待接收标志清空
  32.                         {
  33.                                 dummy =  UART1->DR;
  34.                         }
  35.                         RxCounter = 0;
  36.                 }
  37.         }
  38.        
  39.         else//如果有通讯错误
  40.         {
  41.                 LEDS_PORT->ODR ^= 0x40;
  42.                
  43.                 RxCounter = 0;
  44.                
  45.                 dummy = UART1->SR;
  46.                
  47.                 dummy = UART1->DR;
  48.         }
  49.         return;       
  50. }



  51. //void main(void)中
  52.         while (1)                                                //等待中断
  53.         {
  54.                 if (tim4_of_10ms)
  55.                 {
  56.                         RxCounter = 0;
  57.                         tim4_of_10ms = 0;
  58.                 }
  59.         }
复制代码
此帖出自stm32/stm8论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

14
 
                                 我来按照几位高手的指点试一下看,看结果如何
此帖出自stm32/stm8论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

15
 
                                 是的,我也觉得没必要用中断接收
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表