|
在main.c里8 Z8 D% I9 [" g8 | /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ uint8_t transmit[3] ={1,2,3}; //定义8位数组,3个字节大小 uint16_t len =3;/ N& O# z1 O# |0 l1 S( g1 |$ a uint32_t timeout =10;3 [3 {6 c' h5 V/ w( V" X" M6 r /* USER CODE END PV */ 6 ]: B9 ~. l9 t- _3 Z) u; q" s, q- t9 P main(){ HAL_UART_Transmit(&huart1, transmit,len, timeout); while (1)& B" m; X7 H* A7 O: v) ` {} } 复位键启动程序,上位机接收到01 02 03 关于timeout,它在HAL_UART_Transmit()里和uwTick做比较 uwTick是全局变量,在中断函数SysTick_Handler()里一直循环递增# t- q. \* v/ L% b; a8 u4 B2 n 5 `: ^( k( r: H# P 可在main.c>>SystemClock_Config(void)里找到HCLK/1000 HCLK/1000就是中断进SysTick_Handler()的次数 你的CPU有1000分之一时间都在做uwTick++;4 h: h5 ?. E1 ?: D1 z( ]9 z8 y7 ]3 y HCLK是什么?请看附件图( }% N* M$ R9 n) c; E: e timeout的意义:4 y5 `0 R" d0 p: f0 a timeout就是等待上一字符发送完毕,或异常退出 uint8_t string[123] ={0}; //这个数组很长 HAL_UART_Transmit(&huart1, transmit,len, timeout); //假设timeout=10;顺利从UART1发出3 |! Y `8 S* p6 C2 `! }: ?. I HAL_UART_Transmit(&huart2, transmit,len, timeout); //timeout=10;够长,顺利从UART2发出 关于传送完毕,有人用如下方法等待传送完毕 虽然方案可行6 w z- E! O$ J( o5 I ? while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout)); 这容易卡死,卡死都不知道+ Q- |% X+ s& K! z/ P" n8 d: p 做产品应该尽量避免错误 很明显timeout提供一种方法(针对所有用到timeout的函数)5 N2 E; l2 }2 u 根据数组长度,根据波特率大小,根据处理器速度,根据中断资源的支配7 u+ e0 G; n3 C/ `: |1 t 适当增加timeout ,或减小timeout 会节约系统开支或保证系统运行的稳定性# ?% x9 P7 F' z( T! W* u3 K 不会丢数据 使用while有几个弊端,不仅程序写的难看: _* |$ ^: i& P4 N" y+ m0 h# A P 万一,HAL_UART_Transmit()返回的不是HAL_OK而是HAL_TIMEOUT,程序卡死在这里都不知道 作为程序员,自己写的程序的运行次数和运行时间一定要牢记在心的 HAL_UART_Transmit()用起来简单,全局可用7 Y6 V7 N" x8 V! x0 g 只是编程思想上要和HAL库统一起来& w9 Q8 d0 C6 p5 A2 e$ I1 o! N; g6 T) i2 v 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 HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size, uint32_t Timeout) , M' G- M5 ] W v % B6 o' U/ X: \. f6 D1 Y' y# n+ k stm32cubemx很重要的思想就是:/*USER CODE BEGIN*/2 f! J4 |$ {' A! T( x( F 。。。//在KEIL中编辑4 a4 y7 m# D: n' b% h9 z /*USER CODE END*/ 代码一定!!!要放在这之间,可以用MDK和cubeMX两个软件同时!!!对代码进行更新 假设当你程序写UART完了,又需要添加新外设TIM1时可以用CUBEMX添加新外设/ i3 r, ^( L _+ h4 [6 S( [6 Q( {/ A 在CUBEMX软件中点击Project Generate Code: c8 H# C( J) c6 H( C+ w' D5 g CUBEMX软件不会改变/*USER CODE BEGIN*/ 到 /*USER CODE END*/之间的代码% ]* X( b) x* _' s4 V% } 8 M: t* r6 _' C |9 u$ |: M* f # h" ~2 F- t' x' s7 d" n 环境:STM32CUBEMX,MDK-4 硬件:STM32F405RGTx,LQFP64封装 UART1:A9和A10 简单的UART代码就没必要上传了吧 : b$ ^, {3 U+ f" v9 | |
HCLKå¨cubemxéæçè§
微信公众号
手机版
(0)你的数组长度有上限,每组数组传输时间应该也有上限
(1)假设你在main()函数中有用hal_uart_transmit()传数组,这时来了一个更高级的中断(或者某个异常),如果这个中断(或异常)耗时太长,timeout太短就会丢数据。timeout够长,ha_uart_transmit()就会等待等到中断函数(或异常)结束,再继续传数据,所以timeout和你的中断耗时(异常耗时)有一定关系,timeout其实就是“等待”的意思.. c m3 Q# ~8 X9 k4 U4 A: T, v
(2)如果你传递任意长数组,每一组数传递时间间短(在ms级别)的话,可以考虑加大(如timeout =100000;)
用公式 等待时长 =timeout/(hclk/1000)单位秒 计算你需要的时长(timeout最大0xffff ffff 42亿多)
(4)建议按照严格的传输协议传数据,不要写容易卡死的程序,写能处理异常的程序才是好程序
不会去用这句话吧?官方的demo是这样的
if(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout))
{- ~, z( n0 d- ~+ u8 M' [7 F9 b
....................
}
我觉得 不会有人去那么白痴的去写while的、