如何做一个串口中断接收程序,一次接收一帧数据

[复制链接]
14058|14
 楼主| cyz7799 发表于 2010-1-16 11:20 | 显示全部楼层 |阅读模式
我想请教一下大家,能否做一个串口中断的接收程序,每次进中断后接收一串数据,遇到指定的标志结束。
我搞了几天,当没办法,能否请朋友帮忙指点一下。
BlueBus 发表于 2010-1-22 15:03 | 显示全部楼层
应该可以,接收中断触发后采用查询方式接收
不过不建议这样做,查询方式接收就是等(阻塞),耗时间效率低,影响系统其他工作
建议每次接收中断就处理一个字节,存到数组中,主程序去判断是否收到结束标志
qnmdsb2008 发表于 2010-1-22 15:17 | 显示全部楼层
应该可以,利用switch语句就可以,进中断后用case条件判断
dfsa 发表于 2010-1-22 20:49 | 显示全部楼层
串口通信不是只是半双工的吗
司徒老鹰 发表于 2010-1-22 22:44 | 显示全部楼层
是232还是422还是485?
司徒老鹰 发表于 2010-1-22 22:44 | 显示全部楼层
switch case是可以实现的
有意思 发表于 2010-1-23 12:53 | 显示全部楼层
没必要这样做吧?我一般这样做
在isr中buf[front++]=SBUF;收数据
在主程序中
while (front != rear) {
///根据通讯协议处理数据
   if (crc == true) {
        switch (cmd) {
        }
   }
}
中断中不喜欢处理太多事情
aozima 发表于 2010-1-23 13:17 | 显示全部楼层
本帖最后由 aozima 于 2010-1-23 13:19 编辑

如果发送方发送一个头后,后面的尾迟迟不发(已当机).那么...怎么死的都不知道.
发送倒是可以用DMA一次发帧,因为发送是可控的,主动权在自己,确定他会发送完成.
而接收是被动的.
成成 发表于 2010-1-23 14:32 | 显示全部楼层
本帖最后由 成成 于 2010-1-23 14:39 编辑

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部分替换掉就可以了。
eddy0317 发表于 2010-1-29 10:00 | 显示全部楼层
楼主这种按结束标志结束的方式很好做吧。不需要在中断里面弄,中断不断接收数据写入数组即可,或者用DMA。然后在死循环里面不断读数,读到结束标识就认为结束。如果有超时这个,就加个定时器来定时一下。
mohanwei 发表于 2010-1-29 11:05 | 显示全部楼层
7楼的:buf[front++]=SBUF;
前面一定要加上边界判断,否则一不小心系统怎么死的都不知道……
#define bufLen 32//和你的数据帧最大长度有关
u8 buf[bufLen];
……
中断里:
//先判断是否有未处理的帧,如有,则不可以写缓冲区
……
if(front >= _bufLen)//接着判断缓冲区是否溢出
{
      front =0;//或者用其它方式处理缓冲区溢出
}
buf[front++]=SBUF;//缓冲区未满,才可以把数据放进去
……
stm_zy 发表于 2010-1-29 14:02 | 显示全部楼层
综合利用串口中断和定时器
可以利用定时器,判断超时。如果超时,就把接收计数清零并将接收数组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.         }
 楼主| cyz7799 发表于 2010-1-29 15:07 | 显示全部楼层
我来按照几位高手的指点试一下看,看结果如何
gxgclg 发表于 2010-1-29 18:00 | 显示全部楼层
是的,我也觉得没必要用中断接收
ren0zhe 发表于 2013-10-8 22:39 | 显示全部楼层
大于一个时间间隔没有接收到新的数据,认为是一帧数据的结束。那个时间间隔由波特率决定的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

5

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部