在main.c里& O$ t5 [. v$ ^3 D$ k+ j /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/6 q$ P$ d. E1 F+ ~/ i" Z [ uint8_t transmit[3] ={1,2,3}; //定义8位数组,3个字节大小 1 Q2 Z' W3 L5 Z- j, v uint16_t len =3;. G1 l6 p$ B1 C o# a uint32_t timeout =10; /* USER CODE END PV */ main(){ HAL_UART_Transmit(&huart1, transmit,len, timeout); while (1)9 g2 |( w" ~6 s% o2 D# \$ K {} } 复位键启动程序,上位机接收到01 02 03& S3 t3 x h2 d! S% r 关于timeout,它在HAL_UART_Transmit()里和uwTick做比较3 D& l+ |1 K; H! ?' B V6 o uwTick是全局变量,在中断函数SysTick_Handler()里一直循环递增5 R8 X J# z C* Y! R | 可在main.c>>SystemClock_Config(void)里找到HCLK/1000+ w- U0 ?% D" t HCLK/1000就是中断进SysTick_Handler()的次数 你的CPU有1000分之一时间都在做uwTick++;4 Z! _& w f0 v/ y HCLK是什么?请看附件图 3 Z/ w" S3 P$ q, F f ^ timeout的意义:7 A' E8 H- c' v0 s timeout就是等待上一字符发送完毕,或异常退出 uint8_t string[123] ={0}; //这个数组很长 HAL_UART_Transmit(&huart1, transmit,len, timeout); //假设timeout=10;顺利从UART1发出; }/ z; N# G. w1 m3 Q% k HAL_UART_Transmit(&huart2, transmit,len, timeout); //timeout=10;够长,顺利从UART2发出 * S! Z- d4 O, N; X0 Y/ ]8 C' J' I 关于传送完毕,有人用如下方法等待传送完毕 虽然方案可行4 {: e3 F6 w5 J while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout)); % J8 s: ]! f1 R$ z6 _+ D 这容易卡死,卡死都不知道 做产品应该尽量避免错误 # z5 ~( {3 f O/ M) B7 { 很明显timeout提供一种方法(针对所有用到timeout的函数) 根据数组长度,根据波特率大小,根据处理器速度,根据中断资源的支配 适当增加timeout ,或减小timeout 会节约系统开支或保证系统运行的稳定性 不会丢数据; J+ b; s( c- ^/ i 使用while有几个弊端,不仅程序写的难看 万一,HAL_UART_Transmit()返回的不是HAL_OK而是HAL_TIMEOUT,程序卡死在这里都不知道 作为程序员,自己写的程序的运行次数和运行时间一定要牢记在心的 HAL_UART_Transmit()用起来简单,全局可用" Y" |( g1 {3 x7 K. D h c 只是编程思想上要和HAL库统一起来 uint32_t transmit[3] ={1,2,3}; //发送的数组最好不要像这样定义成32位的 根据C语言,名字"transmit"就是32位指针7 T$ G0 s; t' b uint8_t transmit[3] ={1,2,3}; //定义成这样8位的 根据C语言,名字"transmit"就是8位指针对应于形参uint8_t *pData HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size, uint32_t Timeout) " a" H( T( e6 ]+ O stm32cubemx很重要的思想就是:/*USER CODE BEGIN*/ 。。。//在KEIL中编辑 \- P+ {3 a! P /*USER CODE END*// x+ P3 Q" C5 Y. P 代码一定!!!要放在这之间,可以用MDK和cubeMX两个软件同时!!!对代码进行更新, ?% f8 B( r! T, B' b0 f# y 假设当你程序写UART完了,又需要添加新外设TIM1时可以用CUBEMX添加新外设3 |6 Y! K5 N: ]7 |& a. m5 K2 @( |, Q 在CUBEMX软件中点击Project Generate Code CUBEMX软件不会改变/*USER CODE BEGIN*/ 到 /*USER CODE END*/之间的代码( D. D. e X; Z. J2 h : n$ t9 i* P% q# |4 J7 P . ?; y, o; c3 F 环境:STM32CUBEMX,MDK-4 硬件:STM32F405RGTx,LQFP64封装 UART1:A9和A10 简单的UART代码就没必要上传了吧" n9 o5 u$ |& Z% U n# V3 k- B6 d1 Y( F9 @3 q |
HCLKå¨cubemxéæçè§
(0)你的数组长度有上限,每组数组传输时间应该也有上限3 R+ T2 K) g7 I4 W3 J P5 F! w7 a. a
(1)假设你在main()函数中有用hal_uart_transmit()传数组,这时来了一个更高级的中断(或者某个异常),如果这个中断(或异常)耗时太长,timeout太短就会丢数据。timeout够长,ha_uart_transmit()就会等待等到中断函数(或异常)结束,再继续传数据,所以timeout和你的中断耗时(异常耗时)有一定关系,timeout其实就是“等待”的意思.2 { ^3 O1 k# ?$ ?. u- y
(2)如果你传递任意长数组,每一组数传递时间间短(在ms级别)的话,可以考虑加大(如timeout =100000;)7 [: j$ c' n. v- Q% Q; ~
用公式 等待时长 =timeout/(hclk/1000)单位秒 计算你需要的时长(timeout最大0xffff ffff 42亿多)
(4)建议按照严格的传输协议传数据,不要写容易卡死的程序,写能处理异常的程序才是好程序
不会去用这句话吧?官方的demo是这样的
if(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout))
{5 d- d) F3 A: @, T: C, h" D6 [
....................
} 3 W* R$ a; {. g6 O9 q! Y
我觉得 不会有人去那么白痴的去写while的、