打印

求助STM32的USART2中断接收死机问题。

[复制链接]
楼主: llycom
手机看帖
扫描二维码
随时随地手机跟帖
21
llycom|  楼主 | 2010-5-4 21:34 | 只看该作者 回帖奖励 |倒序浏览
回香主:
1、楼主位的程序中是没有这段代码,因为加不加都是一样的结果。现在都加了,现象还是如前。
2、死机时就是所有的程序都停了,但晶振还是工作的。因为时间比较长,没有调试运行,各个寄存器的状态无法知道。
3、“而且USART_ClearFlag()不能清除USART_FLAG_ORE。”,请问正确的清除方法是什么?谢谢!

使用特权

评论回复
22
llycom|  楼主 | 2010-5-4 21:37 | 只看该作者
如果是来一次中断一次,那肯定不能接受多个再清了,不然第二次就进不了中断了
yybj 发表于 2010-5-4 20:37

其实是每次都清中断标志的,因为加了延时就可以正常工作了。现在的问题是为什么加了延时就可以工作呢?这个问题显示与时间有关系,而不是与标志位清不清有太大的关系,否则会一直不工作,直到标志被清除。难道延时时间长一点,标志位会自动清除?

使用特权

评论回复
23
香水城| | 2010-5-4 21:55 | 只看该作者
“死机时就是所有的程序都停了”是否可以理解为CPU不运行了?

如果CPU还在运行,停止CPU运行,在调试状态下肯定可以看到寄存器的内容。

如果无法停止CPU运行,则说明程序逻辑出了问题。

使用特权

评论回复
24
llycom|  楼主 | 2010-5-5 08:04 | 只看该作者
本帖最后由 llycom 于 2010-5-5 08:05 编辑

再次请问香主:
1、“而且USART_ClearFlag()不能清除USART_FLAG_ORE。”,请问正确的清除方法是什么?谢谢!
程序里是: USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR其实就是清除标志
                  USART_ReceiveData(USART2);    //读DR

2、目前是加 了延时就可以运行,会不会有什么标志会因为延时后就可以被清除?
谢谢!

使用特权

评论回复
25
香水城| | 2010-5-5 08:17 | 只看该作者
1)正确的清除方法就是先读SD再读DR。
2)延时不会清除任何标志。

使用特权

评论回复
26
denike| | 2010-5-6 09:31 | 只看该作者
问题解决了吗??其实485通信是半双工的 收发要切换时要加个小延时的

使用特权

评论回复
27
llycom|  楼主 | 2010-5-6 12:20 | 只看该作者
谢谢楼上顶贴,问题没有解决,目前还是在计数置位后加延时2MS来工作的。
void USART2_IRQHandler(void){
        //溢出-如果发生溢出需要先读SR,再读DR寄存器则可清除不断入中断的问题
        if(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET)
        {
                  USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR其实就是清除标志
                  USART_ReceiveData(USART2);    //读DR
         }
       
         if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
    {
                Rs485Rx[Rs485Rxcont++]=USART_ReceiveData(USART2);
                if(Rs485Rxcont==7){      
                Usart2_Get_Flag=TRUE;
                Delay(2);                               
                 }

                // Clear the USART2 Receive interrupt
                USART_ClearITPendingBit(USART2,USART_IT_RXNE);        
        }
}
主程序也非常简单:
        while(1)
          {         
       
        if(Usart2_Get_Flag)
                  {GPIO_WriteBit(GPIOC, GPIO_Pin_4, (BitAction)(1));
                                printf("%1c%1c%1c%1c%1c%1c%1c",0x03,0x03,0x02,0x02,0x04,0xC1,0x27);
                                GPIO_WriteBit(GPIOC, GPIO_Pin_4, (BitAction)(0));

                        Rs485Rxcont=0;
                    Usart2_Get_Flag=FALSE;                       
                  }
}
其它设置见楼主位贴,如果不加延时就不能工作,加了就能工作。非常奇怪。       
“半双工的 收发要切换时要加个小延时的”,这点倒是没有问题。

使用特权

评论回复
28
香水城| | 2010-5-6 12:24 | 只看该作者
楼主好像没有回答我在23楼的问题呢?

使用特权

评论回复
29
llycom|  楼主 | 2010-5-6 21:23 | 只看该作者
本帖最后由 llycom 于 2010-5-6 21:24 编辑

回香主:
在单步调试运行时,不加延时,确实发现ORE标志位并没有被清除,虽然上面有读SR,DR的命令。难道这段代码不起作用?

使用特权

评论回复
30
llycom|  楼主 | 2010-5-6 21:48 | 只看该作者
本帖最后由 llycom 于 2010-5-6 22:54 编辑

而且发现,如果不在中断里打断点,单步运行就不能进中断程序,打了断点就可以进入。是否打了断点调试时相当于有了延时的效果呢?

使用特权

评论回复
31
skyfight| | 2010-5-7 08:57 | 只看该作者
我们的做法是这样的,一帧数据为16个字节,进中断,初始化TIME2 接收到第一个字节数据,在中断中清除中断标志,开启一个定时器TIME2退出中断,开始下一次中断接收下一个字节,初始化定时器TIM2,  用定时器的目的就是判断如果接收两个相邻数据之间的间隔时间超过5ms ,则判断为第二个数据为下一帧数据。

使用特权

评论回复
32
skyfight| | 2010-5-7 09:01 | 只看该作者
16# llycom

void USART2_IRQHandler(void)
{
  if(RxBufferLength>15)
  RxBufferLength=0;
  RxBuffer[RxBufferLength++]=USART_ReceiveData(USART2);
  USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
  TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
  TIM2->CNT = 0;
  TIM_Cmd(TIM2, ENABLE);
  
}

使用特权

评论回复
33
香水城| | 2010-5-7 09:54 | 只看该作者
而且发现,如果不在中断里打断点,单步运行就不能进中断程序,打了断点就可以进入。是否打了断点调试时相当于有了延时的效果呢?
llycom 发表于 2010-5-6 21:48


对不起,我还是没有明白“死机”是什么意思,“死机”之后CPU是否还能被停止还是已经停止了,“死机”之后程序运行的现场是什么。

--------

你的上述描述也不清楚,没办法知道发生什么。
1)中断里哪里有断点?
2)单步运行就不能进中断程序,打了断点就可以进入。是单步进入的还是连续运行进入的?
3)是否打了断点调试时相当于有了延时的效果呢?单步运行与连续运行的时序根本不一样,不能这样简单对比。

使用特权

评论回复
34
llycom|  楼主 | 2010-5-7 10:33 | 只看该作者
我们的做法是这样的,一帧数据为16个字节,进中断,初始化TIME2 接收到第一个字节数据,在中断中清除中断标志,开启一个定时器TIME2退出中断,开始下一次中断接收下一个字节,初始化定时器TIM2,  用定时器的目的就 ...
skyfight 发表于 2010-5-7 08:57

谢谢您提供的方法,有空试一下!

使用特权

评论回复
35
llycom|  楼主 | 2010-5-7 11:34 | 只看该作者
再回香主:
1、还是没有明白“死机”是什么意思,“死机”之后CPU是否还能被停止还是已经停止了,“死机”之后程序运行的现场是什么。
-----------------
死机的意思是程序不动了,但CPU在调试状态下还可以被终止。程序的现场好像都与发送有关?这点不是很确定,下面贴两个图上来看一下。

2、你的上述描述也不清楚,没办法知道发生什么。中断里哪里有断点?
--------------------------
中断里的断点就是在接收数据的地方设一个断点,29楼里的图上红色行那里。

3、单步运行就不能进中断程序,打了断点就可以进入。是单步进入的还是连续运行进入的?
---------------
是打了断点后,连续运行才能进中断,单步进不了中断。

使用特权

评论回复
36
llycom|  楼主 | 2010-5-7 11:40 | 只看该作者
本帖最后由 llycom 于 2010-5-7 11:46 编辑

发三张程序“死机”时的状态,好像都与发送数据有关的命令。程序里的发送都是用printf函数的,是不是与它有关呢?发送中断没有开启。还有一个疑问,因为485通讯不是全双工的,如果STM32在发送数据时,正好有接收的数据要进来,会不会引起冲突?看下面这张图,接收的计数值为9,而中断程序里如果大于7就置位,然后到主程序里清零,但在没有清零之前,此数值又加大了,应该是再接收到了数据。再次感谢香主的热心。

----------------------------------------------
以下三张是程序“死机”后的停止位置。



使用特权

评论回复
37
笑苍天| | 2010-5-8 01:07 | 只看该作者
我真看不下去了,多动手搜搜看先
请看本版精华帖
主题:关于USART接收中断的BUG和注意事项
https://bbs.21ic.com/frame.php?fr ... om/iclist-49-1.html

使用特权

评论回复
38
llycom|  楼主 | 2010-5-8 08:32 | 只看该作者
我真看不下去了,多动手搜搜看先
请看本版精华帖
主题:关于USART接收中断的BUG和注意事项
https://bbs.21ic.com/frame.php?frameon=yes&referer=http%3A//bbs.21ic.com/iclist-49-1.html ...
笑苍天 发表于 2010-5-8 01:07

楼上的,请你看一下前面的内容。关于你说的这个帖子的内容这在里有讨论过,而且根据其内容修改过程序。没有作用。

使用特权

评论回复
39
zjswuyunbo| | 2010-5-8 23:08 | 只看该作者
怎么说呢,是否考虑下收发的控制?比如收的时候不发,发的时候不收?

使用特权

评论回复
40
dfsa| | 2010-5-9 15:19 | 只看该作者
个人觉得串口接收没必要用中断

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则