|
在main.c里6 T, d, n {/ |* o6 i3 O, w( r0 @ /* USER CODE BEGIN PV */' ~$ r) P5 g' w9 s( h /* Private variables ---------------------------------------------------------*/ uint8_t transmit[3] ={1,2,3}; //定义8位数组,3个字节大小 uint16_t len =3;3 l( F y: K9 A" r uint32_t timeout =10;9 ~+ ?/ f9 W# _4 N /* USER CODE END PV */7 ~1 G& J$ y( B main(){ HAL_UART_Transmit(&huart1, transmit,len, timeout); while (1) {}8 y' l( Y& M; j" _& \6 ?( M Y7 I }0 @$ \( p8 }( `6 K/ }, m 复位键启动程序,上位机接收到01 02 037 Z6 j& q1 Q1 h: @ " K& G- ^% Z( r, k! c 关于timeout,它在HAL_UART_Transmit()里和uwTick做比较( D& e# J' N( @9 ] uwTick是全局变量,在中断函数SysTick_Handler()里一直循环递增, Q9 I7 k7 B* \& E( O$ h/ S( [' J$ E 可在main.c>>SystemClock_Config(void)里找到HCLK/1000' {% A3 D: q7 D R B HCLK/1000就是中断进SysTick_Handler()的次数 你的CPU有1000分之一时间都在做uwTick++;5 m# G; L- q" z% X+ M HCLK是什么?请看附件图 $ O1 d$ k/ I3 G timeout的意义: timeout就是等待上一字符发送完毕,或异常退出 0 C: \+ g& o+ Y$ e7 `& G uint8_t string[123] ={0}; //这个数组很长 HAL_UART_Transmit(&huart1, transmit,len, timeout); //假设timeout=10;顺利从UART1发出 HAL_UART_Transmit(&huart2, transmit,len, timeout); //timeout=10;够长,顺利从UART2发出 $ Z# K: x% y: K8 I0 |4 x4 K+ c 5 w6 e E: a1 K% n 关于传送完毕,有人用如下方法等待传送完毕 虽然方案可行 while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout)); # u8 z* b5 E& N9 x6 `# e 这容易卡死,卡死都不知道6 L3 ?; k, I) M. B 做产品应该尽量避免错误4 o( C" z7 X, {% T) u; h 3 g4 b; T. J$ i: E' { }. m 很明显timeout提供一种方法(针对所有用到timeout的函数)# I/ d% s9 l. g. ]" n 根据数组长度,根据波特率大小,根据处理器速度,根据中断资源的支配/ v' O, Y) N9 ]) q. \ 适当增加timeout ,或减小timeout 会节约系统开支或保证系统运行的稳定性 不会丢数据& \6 \1 a0 R' N- S$ ` 使用while有几个弊端,不仅程序写的难看 万一,HAL_UART_Transmit()返回的不是HAL_OK而是HAL_TIMEOUT,程序卡死在这里都不知道4 M5 u1 P; L: g& ^. ?; R 作为程序员,自己写的程序的运行次数和运行时间一定要牢记在心的 HAL_UART_Transmit()用起来简单,全局可用/ h. p2 [0 k4 W3 t! {( a7 a7 x 只是编程思想上要和HAL库统一起来( Q& [9 z3 v* B0 ]# J uint32_t transmit[3] ={1,2,3}; //发送的数组最好不要像这样定义成32位的 根据C语言,名字"transmit"就是32位指针 uint8_t transmit[3] ={1,2,3}; //定义成这样8位的 根据C语言,名字"transmit"就是8位指针对应于形参uint8_t *pData' a* }" s; [3 f7 N) T5 k4 [ HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size, uint32_t Timeout) , L. a7 P$ R' x& f+ h7 }8 y 0 e; I- ?6 t6 ?+ i( |- N$ }: C) x stm32cubemx很重要的思想就是:/*USER CODE BEGIN*/ 。。。//在KEIL中编辑 /*USER CODE END*/) T' N7 o) q/ n. j1 Q 代码一定!!!要放在这之间,可以用MDK和cubeMX两个软件同时!!!对代码进行更新+ K% n6 P! N" P) J/ p1 ]9 }6 w5 l3 U 假设当你程序写UART完了,又需要添加新外设TIM1时可以用CUBEMX添加新外设9 F$ }+ r) Y5 z) {' h! N; @ 在CUBEMX软件中点击Project Generate Code CUBEMX软件不会改变/*USER CODE BEGIN*/ 到 /*USER CODE END*/之间的代码 2 s- p1 ?5 j- l- r+ e0 | 环境:STM32CUBEMX,MDK-46 d! ?8 ^) e" f# |+ f! w( x 硬件:STM32F405RGTx,LQFP64封装0 S0 k, Z# z0 {+ y' L UART1:A9和A10% b! g+ J9 q# A0 l( O, y; q 简单的UART代码就没必要上传了吧 # h' B2 \3 H" Z |
HCLKå¨cubemxéæçè§
微信公众号
手机版
(0)你的数组长度有上限,每组数组传输时间应该也有上限
(1)假设你在main()函数中有用hal_uart_transmit()传数组,这时来了一个更高级的中断(或者某个异常),如果这个中断(或异常)耗时太长,timeout太短就会丢数据。timeout够长,ha_uart_transmit()就会等待等到中断函数(或异常)结束,再继续传数据,所以timeout和你的中断耗时(异常耗时)有一定关系,timeout其实就是“等待”的意思.
(2)如果你传递任意长数组,每一组数传递时间间短(在ms级别)的话,可以考虑加大(如timeout =100000;)6 D0 ?& W7 t/ Y" z! Q& g
用公式 等待时长 =timeout/(hclk/1000)单位秒 计算你需要的时长(timeout最大0xffff ffff 42亿多)
(4)建议按照严格的传输协议传数据,不要写容易卡死的程序,写能处理异常的程序才是好程序
不会去用这句话吧?官方的demo是这样的+ }6 _. m0 p! K' Q* V7 j
if(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout))
{1 f( o5 t8 @, p! N5 z
....................
}
我觉得 不会有人去那么白痴的去写while的、