. B7 I* n8 i# @9 m
STM32CubeMX是一款非常方便的工具软件。但是在使用时也会存在一些问题。比如,最近调试昆仑通态触摸屏与单片机的串口通讯,波特率为9600,数据位8位,偶校验,1位停止位。使用STM32CubeMx设置参数如下: 需要注意的是,STM32的数据位是包含校验位的,所以数据位要选择9位。 生成代码后,添加相关的接收中断程序,参考《STM32CubeMX之串口通信》。但实际测试时,发现接收的第一个字节总是0。经过单步调试跟踪发现,串口接收发生了Over-Run错误,进入了以下程序,导致接收错误。 之后改为自己写的中断接收程序后,没有出现错误,说明该软件生成的代码还是有一定的局限性的。自己编写的代码如下: 首先,初始化完成后,打开串口接收中断: - __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//打开接收中断
复制代码
6 F% a3 P7 M: i. }' m 然后,在串口中断中,屏蔽软件生成的中断函数,添加自己的中断程序: - void USART1_IRQHandler(void)
1 A9 |6 n, O; Z$ @ - {: P }/ j5 X+ |6 k* |
- /* USER CODE BEGIN USART1_IRQn 0 */
. f9 h: N3 | i: N/ V T; ] - 2 T; @7 S& ^3 I( ]. g1 n
- /* USER CODE END USART1_IRQn 0 */3 j4 J7 z% R6 Q2 k- }5 U# T
- //HAL_UART_IRQHandler(&huart1);//屏蔽系统生成的中断函数7 ~" y' p+ G, z; ]) `& `1 [. E/ s
- /* USER CODE BEGIN USART1_IRQn 1 */0 X6 d8 ? {/ Q
- uint32_t isrflags = USART1->SR;0 Z* ]4 @( v, N! Z
- uint32_t cr1its = USART1->CR1;
5 C' W" {, P5 W) V; z) e* w k -
9 F6 n5 d- Z. R' C. O0 ?3 g - if(USART1->SR & UART_IT_RXNE)//串口接收中断& @+ c9 X1 ?$ F. k6 p: ]
- {- n8 e. t( I" y; l) |8 ?0 e
- __HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_RXNE);
% }- W3 C, t' F! |; Q - if(Uart1.RxFlag!=2)
- s |9 j) C* p( b3 s - {
) ]' V n4 v6 f, }: A - Uart1.RxBuf[Uart1.RxCnt]=USART1->DR;8 d; V" ~! _* `3 T$ t6 Z
- Uart1.RxCnt++;
z+ t6 A: l3 J& G" r - if(Uart1.RxCnt>300)
?* E# K% Q4 e3 f5 [; j/ }1 V - {1 o/ m: a3 m ~3 d& t
- Uart1.RxCnt=299;
' Z) ~/ i% q P" G9 f% v - }" J& K6 p0 A" S4 L( m& w* K' M1 K
- Uart1.RxFlag=1;
* ]: [0 n( U' }. H% ^ - Uart1.uart_tick=0;9 a3 ~7 o2 T2 h. L. @
- }6 {2 Y4 s0 O1 ^$ K2 e3 N- m; H3 q# o
- }4 y& k! ?9 i8 q
- if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))//发送中断4 v) X. V d$ ?, B9 J: {3 _7 @
- {
! P# J- w! o) h" v) c9 l2 _ - USART1->DR = Uart1.TxBuf[Uart1.TxCnt];
; U* ?2 M/ ~+ W X" j! V, B0 u& | - Uart1.TxCnt++;; r) ]; M( Y2 v2 h7 d- y
- if(Uart1.TxCnt == Uart1.TxNum). Q. f v" L) K, o( [
- {* K3 D% B; s9 v9 I8 W2 G
- Uart1.TxCnt=0;
: N- d. r$ J% ^& F1 r @$ S - __HAL_UART_DISABLE_IT(&huart1, UART_IT_TXE);9 e; ]# R4 |# {# \) j8 n9 l
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);
' s1 H* T3 d( J- s4 B5 J) p' G - }/ ]* ]1 m) Q/ b
- }! g Q! l6 {- N9 ]# z
- if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))//发送完成中断
7 t. W! e9 K2 B - {8 e+ S9 y* N5 H
- __HAL_UART_DISABLE_IT(&huart1, UART_IT_TC);
k6 v+ R+ l* R% I+ [1 \2 S" F - Uart1.TxFlag = 0;8 ?. _8 `3 B! {- Q: ~
- CLR_DE1;
0 h1 e& Y- n5 ~' V5 B - }
/ H5 F) t: N; } - /* USER CODE END USART1_IRQn 1 */
& _7 w! A( h' W1 M) V, Y! X - }
复制代码
" r9 d) t8 l! q+ L 中断函数中包含了发送中断部分,需要中断发送数据时,将数据放在Uart1.TxBuf中,设置发送长度Uart1.TxNum,并使能串口发送中断即可: - Uart1.TxNum = 10;
0 d! l- M$ \! f- R - __HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE);
复制代码
1 D( b% a* k7 b# P6 n% R STM32CubeMx生成的程序通过牺牲效率而尽可能实现不同系列芯片的通用性,相比而言,自己编写中断程序效率要高很多,当系统资源有限或者需要单片机低速运行时,就需要自己编写相关程序,以实现程序的高效运行。 文章出处: 嵌入式技术开发 U9 J6 `( L* @$ K7 `5 M8 T- v
|