OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...
查看: 554|回复: 1

STM8S串口1接受非空中断UART1_IT_RXNE导致程序死机的原因

[复制链接]

  离线 

4

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
306
金钱
306
注册时间
2015-11-12
在线时间
73 小时
发表于 2017-9-30 17:56:30 | 显示全部楼层 |阅读模式
首先声明我使用的是库函数开发,标准库的版本是V2.0.0,我下载的其他的高版本 V2.2.0也出现了同样的情况。我是一个STM8的初学者,之前一直在用STM32。大家说STM8很简单,公司正好也需要开发一款中低端的产品,借此机会,学习一下ST的8位机。
在调试串口的过程中发现串口初始化不能通过,莫名情况下,单片机就死掉了,以下是我串口配置的代码;
void USART1_Init(uint32_t Baudrate)
{


  UART1_DeInit();
  /* UART1 configuration ------------------------------------------------------*/
  /* UART1 configured as follow:
        - BaudRate = 115200 baud  
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Receive and transmit enabled
        - UART1 Clock disabled
  */
  UART1_Init((uint32_t)Baudrate, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO,
                   UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);



  UART1_ITConfig(UART1_IT_RXNE, ENABLE);

  UART1_Cmd(ENABLE);

}

因为配置串口打印数据输出对调试代码有很大的帮助,所以串口的前期阶段我并没有配置中断,并且我打开了void assert_failed(u8* file, u32 line)函数的,方便查看程序错误。
在我把中断加上去之后,串口输出了错误的信息。根据我在STM32串口中的逻辑这样配置是没有问题的,所以我并没有怀疑代码的配置会有任何的问题。随后自己硬件仿真的时候发现程序死在了中断配置这里。很是郁闷,不知道为什么会出现这种情况。检查了无数遍函数和函数的形参,确认没有问题之后,把中断配置这句去掉,再次仿真竟然一切正常。所以断定问题肯定是出现在这里。
当我仔细阅读库函数后同样没有发现问题的所在,无奈之下,结合百度搜索终于发现了问题所在,【敲黑板】
在检查参数函数中:assert_param(IS_UART1_CONFIG_IT_OK(UART1_IT));发现如下的定义:
#define IS_UART1_CONFIG_IT_OK(Interrupt) \
  (((Interrupt) == UART1_IT_PE) || \
   ((Interrupt) == UART1_IT_TXE) || \
   ((Interrupt) == UART1_IT_TC) || \
   ((Interrupt) == UART1_IT_RXNE_OR ) || \
   ((Interrupt) == UART1_IT_IDLE) || \
   ((Interrupt) == UART1_IT_LBDF))

仔细观察发现并没有UART1_IT_RXNE这句话,但是有UART1_IT_RXNE_OR,所以我在想,为什么ST的工程师这样做,在SR寄存器中的标志位也没有UART1_IT_RXNE_OR标志位;至今还没有想明白ST为什么这样做。如有高手指导,欢迎探讨。

两种修改方法:
①:修改标准库:把UART1_IT_RXNE这个加上去,如下所示
#define IS_UART1_CONFIG_IT_OK(Interrupt) \
  (((Interrupt) == UART1_IT_PE) || \
   ((Interrupt) == UART1_IT_TXE) || \
   ((Interrupt) == UART1_IT_TC) || \
   ((Interrupt) == UART1_IT_RXNE_OR ) || \
   ((Interrupt) == UART1_IT_RXNE ) || \      //注意这是自己手动添加的内容
   ((Interrupt) == UART1_IT_IDLE) || \
   ((Interrupt) == UART1_IT_LBDF))


②:把中断配置的形参参数改为UART1_IT_RXNE_OR。


两种方式均可,怎么取舍看自己。
文章中肯定会有表达错误的地方,欢迎大家拍砖,相互交流。792028616@qq.com






回复

使用道具 举报

  离线 

12

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
191
金钱
191
注册时间
2017-4-19
在线时间
30 小时
发表于 2018-1-2 11:37:17 | 显示全部楼层
#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \                                ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \                                ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \                                ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR))
回复 支持 反对

使用道具 举报

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

本版积分规则




关闭

报名原子哥新品发布会&粉丝见面会上一条 /1 下一条

正点原子公众号

QQ|联系我们|手机版|官方淘宝店|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-10-23 18:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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