你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

经验分享STM32CUBEMX,UART_Transmit()及timeout参数的意义

[复制链接]
stmcuman 发布时间:2016-5-10 21:49
在main.c里8 Z8 D% I9 [" g8 |
  /* USER CODE BEGIN PV */
9 V1 w& y, L+ R6 I/* Private variables ---------------------------------------------------------*/
- Z; c- q3 P" ?% \* r: auint8_t transmit[3] ={1,2,3};      //定义8位数组,3个字节大小   
5 f8 B: D/ Z: _1 {9 v! v* Vuint16_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 */
2 h, P, [3 K+ U" l2 q8 O/ a% q6 ]: B9 ~. l9 t- _3 Z) u; q" s, q- t9 P
main(){
3 r2 s6 v, M+ S   HAL_UART_Transmit(&huart1, transmit,len, timeout);
( {: D+ u* p$ L7 D2 B% Z2 e& R  while (1)& B" m; X7 H* A7 O: v) `
  {}
* V+ k7 @/ R/ ]( Q1 H# `}
9 ]+ E0 S$ q! w$ a5 [& H) i+ e
4 t0 h% ?  x' o! K% u! U; w) n复位键启动程序,上位机接收到01 02 03
% h4 R9 e' {5 K; t* F
, t; B4 D  [: B7 n( m5 |' [# H关于timeout,它在HAL_UART_Transmit()里和uwTick做比较
: D$ g& W7 ~; R4 J5 `uwTick是全局变量,在中断函数SysTick_Handler()里一直循环递增# t- q. \* v/ L% b; a8 u4 B2 n
5 `: ^( k( r: H# P
可在main.c>>SystemClock_Config(void)里找到HCLK/1000
/ \3 G! J+ i. a: M* JHCLK/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

  x' b  g; \$ itimeout的意义:4 y5 `0 R" d0 p: f0 a
timeout就是等待上一字符发送完毕,或异常退出  
/ R- v- }+ I: T0 Duint8_t string[123] ={0};   //这个数组很长
$ J# G1 k, \! V/ e* C" v' xHAL_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发出
, f2 ]0 |3 w% r7 d" K
2 b" q( A, Q7 R+ f2 _关于传送完毕,有人用如下方法等待传送完毕
3 T6 \5 N$ f& x: x0 A* @虽然方案可行6 w  z- E! O$ J( o5 I  ?
while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout));     
& i5 f6 G! Q: k8 x- I. C这容易卡死,卡死都不知道+ Q- |% X+ s& K! z/ P" n8 d: p
做产品应该尽量避免错误
6 j; I+ }1 V. u7 \9 R& E
, E( A$ i4 i! r+ [: C很明显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
不会丢数据
# z4 ]+ j, @$ r( |使用while有几个弊端,不仅程序写的难看: _* |$ ^: i& P4 N" y+ m0 h# A  P
万一,HAL_UART_Transmit()返回的不是HAL_OK而是HAL_TIMEOUT,程序卡死在这里都不知道
) I, z2 a6 h# H# @  ?3 M作为程序员,自己写的程序的运行次数和运行时间一定要牢记在心的
4 \4 V7 m' P/ g5 _( u7 G
& M/ c, P, [# e+ B/ V0 MHAL_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位指针
$ y: o4 J- ]: A" ^0 g2 m5 Cuint8_t transmit[3] ={1,2,3};      //定义成这样8位的   根据C语言,名字"transmit"就是8位指针对应于形参uint8_t *pData
4 \& j9 O! L8 q" B) D9 v HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size, uint32_t Timeout)
6 E6 `/ A8 v/ M6 T4 j, \, 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*/
& Q2 k4 i2 s# v# P% P4 O! p代码一定!!!要放在这之间,可以用MDK和cubeMX两个软件同时!!!对代码进行更新
. Z; @. s. |. Y/ Q# H假设当你程序写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
, J% _  [: y5 C硬件:STM32F405RGTx,LQFP64封装
; I3 w/ L, k; I4 |3 v) l: _UART1:A9和A10
: x4 L2 l3 u9 A$ k2 ?简单的UART代码就没必要上传了吧
# F* s& L9 O$ y. ?3 S: b$ ^, {3 U+ f" v9 |

HCLK在cubemx里有看见

HCLK在cubemx里有看见
赞 收藏 1 评论8 发布时间:2016-5-10 21:49

举报

8个回答
leochen2019 回答时间:2019-11-12 09:27:49
楼主文章不错!新手学习啦!
chenbourne 回答时间:2016-5-11 09:15:29
谢谢 分享 昨天向楼主提的问题 没想到今天就写好了
沐紫 回答时间:2016-5-11 09:24:01
支持!谢谢分享
wofei1314 回答时间:2016-5-11 13:17:40
谢谢经验分享!
MCU之路 回答时间:2016-5-11 16:40:28
你好  楼主 请问如果我不知道收到的数组有多少  只是知道一个上限,比如说我收到的数组是0-500的中的一个,这个用这个timeout能实现吗
stmcuman 回答时间:2016-5-12 14:01:01
本帖最后由 0721de 于 2016-5-12 14:03 编辑
) a* c0 [+ N1 d
MCU之路 发表于 2016-5-11 16:40
& |% }" c" B4 K' Z% f- ~你好  楼主 请问如果我不知道收到的数组有多少  只是知道一个上限,比如说我收到的数组是0-500的中的一个, ...
" X2 F* U7 O) x6 j5 n
(0)你的数组长度有上限,每组数组传输时间应该也有上限
1 U. }. L3 b0 |# W7 A(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;)
( ~: d/ V: N. o2 ]- W用公式  等待时长 =timeout/(hclk/1000)单位秒   计算你需要的时长(timeout最大0xffff ffff 42亿多)
6 C* {! A& p5 |& }3 b9 t, ^0 K(4)建议按照严格的传输协议传数据,不要写容易卡死的程序,写能处理异常的程序才是好程序
david2016 回答时间:2016-5-12 17:35:22
while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout));   关于这一点。。。 ( h0 e8 z. a# F! F, ?  H- {
不会去用这句话吧?官方的demo是这样的
' |- \# `, U5 fif(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout))
- V8 Y7 K$ D* M( v& ]  F) e- T3 ?1 u{- ~, z( n0 d- ~+ u8 M' [7 F9 b
....................
) ~: w8 {" _/ u& x8 g& [5 O}   
) v) J1 D$ j; p% r$ `我觉得 不会有人去那么白痴的去写while的、
david2016 回答时间:2016-5-12 17:36:29
另外 一般是采用中断发送。
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版