7700|16

64

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

求教STM32USART高速通讯的怪问题 [复制链接]

俺用的是STM32F103VB,72MHz运行。USART2,半双工通讯,DMA发送,中断接收。在速率为19200、115200时一切正常。

但是项目要求速率达到0.5Mbps,更改波特率设置(用的是FWLib)后,通讯无法进行。示波器查出发送正确。我在接收中断函数

入口处设置一根引线作为探针,发现CPU居然以大约2.5uS的周期反复进入中断程序,因此导致主程序假死。示波器观测,回应信号

基本正确。百思不得其解!

万望高手支援!!
此帖出自stm32/stm8论坛

最新回复

                                 楼上兄弟很细心啊! 1.USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); 这句确实不行,我后来做了特别测试,似乎加上后会清掉RXNE位。 2.temp=*((vu32*)0x40004404);是在反复测试过程中加上的,这句也不严谨,临时忘了注释掉。 3.接收过程没有定时守护程序,因此可能有缓存溢出情况。这段保证溢出部分不影响其它内存。 4.   3.5bytes for recive end是通讯协议的一部分。我采用的是空闲线协议,依此来分组。 5.以下是经过手工代码优化的程序,运行时间缩短到大约2uS。 void USART2_IRQHandler(void)                   // IO Module {           u16 temp=0;       GPIO_SetBits(GPIOC, GPIO_Pin_9);                 // Test   if(USART2->SR & 0x20)                          /* Test RXNE bit */   {              TIM2->DIER &= (u16)~TIM_IT_CC2;                    // TIM_IT_CC2, DISABLE       temp=(u16)(USART2->DR & (u16)0xFF);              // ReceiveData       RxBuff_IO[RxBuffWrPt_IO++]=(u8)temp;       if(RxBuffWrPt_IO>=RX_BUFF_SIZE_IO)          /* Overwrite protect */      {         IO_CommStatus=130;         RxBuffWrPt_IO--;      }      else IO_CommStatus = 4;                                 // Reciving...      temp = TIM2->CNT;     TIM2->CCR2 =  temp + IO_COMM_IDLE;        // 3.5bytes for recive end     TIM2->SR = (u16)~TIM_IT_CC2;     TIM2->DIER |= TIM_IT_CC2;                  // TIM_IT_CC2, ENABLE   }                  USART2->SR=(u16)(~0x0020);                 // Clear RXNE       GPIO_ResetBits(GPIOC, GPIO_Pin_9);         // Test }  详情 回复 发表于 2009-8-12 14:13
点赞 关注
 

回复
举报

94

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
                                 查一查中断使能位和标志位,是不是出现使能了中断,而且标志来了,但没在中断处理程序中清掉的
此帖出自stm32/stm8论坛
 
 

回复

80

帖子

0

TA的资源

一粒金砂(高级)

板凳
 
                                 是否软件响应不够快?为什么接收不用DMA?
此帖出自stm32/stm8论坛
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

4
 
感谢楼上兄弟是我回复。

to 2楼:因为以前115200是没问题的,所以您的说法应当不存在。按照手册上所说,只要读取了DR,即可清除标志。而且我还用库函数再执行了一次。

to 3楼:我也曾经考虑过软件响应速度不够的因素,但我无法解释这样的现象:一旦进入了反复中断的状况,即使撤掉外来的信号,中断也不能退出,而且典型的特征是2.5uS左右的中断周期,十分规律。在这种情况下,只要我用调试停止暂停执行一次,然后恢复运行,中断就不再进入了。
    我在中断函数的开始,禁止本中断,在中断返回时恢复中断,并不能解决问题。后来在不断的测试过程中,我还发现有时125kbps通讯也会有此现象,但经复位能够消除。
   未用DMA是因为沿袭了部分老设计。而且由于接收数量未知, DMA也有些麻烦。多个中断配合不如单一的好做。但无论如何,这种中断无法清除的现象我想不通,十分郁闷啊!
此帖出自stm32/stm8论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

5
 
                                 请问在反复进入中断时,从DR中读出的数据对不对?你有没有查看SR寄存器?是否发生了某些错误没有处理?
此帖出自stm32/stm8论坛
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

6
 
                                 可以肯定数据是不对的,似乎只有两种01和03。SR也曾经看过,RXNE不一定置位。如果说是错误造成的,我曾在中断函数内不管三七二十一所有标志全部清一次。可以肯定,我没有打开除接收中断之外的任何USART中断。而且只要我禁用该中断,就不再反复进入中断函数。
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

7
 
                                 数据传输的另一端是什么设备?数据格式是什么?
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

8
 
另一端是MEGA48+MAX1487,数据格式8,N,1,无校验

“对不起,本站规定会员每小时最多只能发表 5 个帖子。“

二姨不让说话,俺闭嘴了一下:-)
此帖出自stm32/stm8论坛
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

9
 
                                 把你的程序发上来看看。
此帖出自stm32/stm8论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

10
 
                                 对比一下双方的波特率是否相同。是否只是一方改了,另一方没有更改?
此帖出自stm32/stm8论坛
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

11
 
我刚刚改了一下,USART2发,USART3接收,涛声依旧。
0811_152127.GIF
1通道是探针,每次进入USART2中断,反转一次
2是总线数据波形
以下是初始化代码,另一通道一样:
USART_InitStructure.USART_BaudRate = 500000;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART2, &USART_InitStructure);
//  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
  USART_Cmd(USART2, ENABLE);
  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
以下是USART2接收中断代码,3通道类似:
void USART2_IRQHandler(void)         // IO Module
{  
  u16 temp=0;
  USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);           
GPIO_WriteBit(GPIOC, GPIO_Pin_9, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_9)));
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET
  /*&& USART_GetFlagStatus(USART2, USART_FLAG_ORE) == RESET
  && USART_GetFlagStatus(USART2, USART_FLAG_NE) == RESET
  && USART_GetFlagStatus(USART2, USART_FLAG_FE) == RESET */ )
  {
temp=*((vu32*)0x40004404);
TIM_ITConfig(TIM2, TIM_IT_CC2, DISABLE);
temp=USART_ReceiveData(USART2);
/* Overwrite protect */
RxBuff_IO[RxBuffWrPt_IO++]=(u8)temp;
if(RxBuffWrPt_IO>=RX_BUFF_SIZE_IO)
{
   IO_CommStatus=130;
   RxBuffWrPt_IO--;
}
else IO_CommStatus = 4;        // Reciving...
temp = TIM_GetCounter(TIM2);      // Wait for Slave
    TIM_SetCompare2(TIM2, temp + IO_COMM_IDLE);   // 3.5bytes for recive end
TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
  }  
  USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}
接收方USART3未见回应。

!真心感谢楼上兄弟!
此帖出自stm32/stm8论坛
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

12
 
1)这句话做什么的?  temp=*((vu32*)0x40004404);

2)RxBuff_IO有多大,是否溢出了?

3)请在中断函数开始和结尾各翻转I/O一次,这样可以看到中断函数的执行时间。

4)每次进中断都有这个条件吗?USART_IT_RXNE
此帖出自stm32/stm8论坛
 
 
 

回复

16

帖子

0

TA的资源

一粒金砂(初级)

13
 
to 香主:
  1: 如果不错的话那是DR寄存器地址;
  2:RxBuff SIZE 为 12字节,所要接收的数据只有8字节;
  3:在250kbps下,能够测到处理时间约2.5uS,在500kbps下似乎中断从未返回,感谢您的提醒。
  4:很难满足RXNE条件。

我想我明白问题所在了,十分感谢您的帮助,我会尝试用DMA接收的!再次感谢!
此帖出自stm32/stm8论坛
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

14
 
                                 把中断里这一行去掉:USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
此帖出自stm32/stm8论坛
 
 
 

回复

49

帖子

0

TA的资源

一粒金砂(初级)

15
 
                                 这一句本来是没有的。如果波特率低——19200试过,似乎加也无妨。
此帖出自stm32/stm8论坛
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

16
 
再次详读你的代码,有如下之不解?望解惑!

void USART2_IRQHandler(void)         // IO Module
{  
  u16 temp=0;
  USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);           
GPIO_WriteBit(GPIOC, GPIO_Pin_9, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_9)));
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET
  /*&& USART_GetFlagStatus(USART2, USART_FLAG_ORE) == RESET
  && USART_GetFlagStatus(USART2, USART_FLAG_NE) == RESET
  && USART_GetFlagStatus(USART2, USART_FLAG_FE) == RESET */ )
  {
temp=*((vu32*)0x40004404);           ->已经读取了串口的数据了
TIM_ITConfig(TIM2, TIM_IT_CC2, DISABLE); ->定时器的意欲何为?
temp=USART_ReceiveData(USART2);   ->为何二进宫,再次读取串口数据?
/* Overwrite protect */                        ->防范接收溢出乎?大惑!
RxBuff_IO[RxBuffWrPt_IO++]=(u8)temp;
if(RxBuffWrPt_IO>=RX_BUFF_SIZE_IO)
{
   IO_CommStatus=130;
   RxBuffWrPt_IO--;
}
else IO_CommStatus = 4;        // Reciving...
temp = TIM_GetCounter(TIM2);      // Wait for Slave
    TIM_SetCompare2(TIM2, temp + IO_COMM_IDLE);   // 3.5bytes for recive end   ->3.5个字节?不解之?
TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
  }  
  USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}
此帖出自stm32/stm8论坛
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

17
 
楼上兄弟很细心啊!
1.USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); 这句确实不行,我后来做了特别测试,似乎加上后会清掉RXNE位。
2.temp=*((vu32*)0x40004404);是在反复测试过程中加上的,这句也不严谨,临时忘了注释掉。
3.接收过程没有定时守护程序,因此可能有缓存溢出情况。这段保证溢出部分不影响其它内存。
4.   3.5bytes for recive end是通讯协议的一部分。我采用的是空闲线协议,依此来分组。
5.以下是经过手工代码优化的程序,运行时间缩短到大约2uS。
void USART2_IRQHandler(void)                   // IO Module
{        
  u16 temp=0;
   
  GPIO_SetBits(GPIOC, GPIO_Pin_9);                 // Test

  if(USART2->SR & 0x20)                          /* Test RXNE bit */
  {       
      TIM2->DIER &= (u16)~TIM_IT_CC2;                    // TIM_IT_CC2, DISABLE
      temp=(u16)(USART2->DR & (u16)0xFF);              // ReceiveData
      RxBuff_IO[RxBuffWrPt_IO++]=(u8)temp;
      if(RxBuffWrPt_IO>=RX_BUFF_SIZE_IO)          /* Overwrite protect */
     {
        IO_CommStatus=130;
        RxBuffWrPt_IO--;
     }
     else IO_CommStatus = 4;                                 // Reciving...
     temp = TIM2->CNT;
    TIM2->CCR2 =  temp + IO_COMM_IDLE;        // 3.5bytes for recive end
    TIM2->SR = (u16)~TIM_IT_CC2;
    TIM2->DIER |= TIM_IT_CC2;                  // TIM_IT_CC2, ENABLE
  }               
  USART2->SR=(u16)(~0x0020);                 // Clear RXNE
   
  GPIO_ResetBits(GPIOC, GPIO_Pin_9);         // Test
}
此帖出自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
快速回复 返回顶部 返回列表