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

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

[复制链接]
stmcuman 发布时间:2016-5-10 21:49
在main.c里- h4 ]. P+ D+ [9 ?
  /* USER CODE BEGIN PV *// U5 D# V7 B5 w( J9 X+ O0 z( }; [; h
/* Private variables ---------------------------------------------------------*// J) B% R4 \4 ~7 z1 o
uint8_t transmit[3] ={1,2,3};      //定义8位数组,3个字节大小    7 e. d  u9 k% H% r
uint16_t len =3;
: r- _. m' ~- n& ^% t0 Nuint32_t timeout =10;
7 j1 z: i3 k/ f% V1 Y' O4 _2 t/* USER CODE END PV */
& R2 n1 W5 q0 x9 {/ }$ T* k$ I/ V
main(){
0 u7 V) I3 }# Y   HAL_UART_Transmit(&huart1, transmit,len, timeout);
  I# x3 O8 P# q1 J8 ?* G- h  while (1)
  l0 |; F. K2 ~  B2 n  {}7 K# @4 t$ h4 O7 \- Q3 J4 h9 f5 x
}2 v7 Q: K" {/ L% ]

# h4 M/ Z* c4 I复位键启动程序,上位机接收到01 02 036 b) p/ M, r' ]' p8 k6 u0 C

( l9 ?2 U2 C: h8 j关于timeout,它在HAL_UART_Transmit()里和uwTick做比较, L* v! c7 x) [6 T% Y
uwTick是全局变量,在中断函数SysTick_Handler()里一直循环递增
) r) f% w+ c9 J5 t5 ^
, m: B$ K; H6 B' ^& s可在main.c>>SystemClock_Config(void)里找到HCLK/1000+ o$ b8 S& A, p( _! {8 p: d" Z
HCLK/1000就是中断进SysTick_Handler()的次数  你的CPU有1000分之一时间都在做uwTick++;
- }9 ~3 B. y$ [: C- }HCLK是什么?请看附件图: @/ ]5 J3 h+ [( }3 ?
! d8 A7 I' P& c4 C  N
timeout的意义:
; S0 J4 b# W3 i$ mtimeout就是等待上一字符发送完毕,或异常退出  . N& ]; K1 |8 V; q# }2 n
uint8_t string[123] ={0};   //这个数组很长/ ^- k8 T  O$ j1 E# W
HAL_UART_Transmit(&huart1, transmit,len, timeout);                  //假设timeout=10;顺利从UART1发出% S; R9 `& j$ g/ B$ v  i3 z
HAL_UART_Transmit(&huart2, transmit,len, timeout);                   //timeout=10;够长,顺利从UART2发出
; K/ I! P" n: E7 P. L5 F* Q2 G/ L" i0 {, `4 v
关于传送完毕,有人用如下方法等待传送完毕0 ]5 _& A, w( T7 I  a! d
虽然方案可行) x) m; }) p( k( i  l
while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout));     
# Y+ F- D. c1 Q+ [2 S6 i: k这容易卡死,卡死都不知道8 {4 O7 q+ l6 p$ z) I% U
做产品应该尽量避免错误
3 q: v4 }& n" w# Y, z$ m) P5 V. q" I' j  H. b$ g0 r. L! I
很明显timeout提供一种方法(针对所有用到timeout的函数)
( r: E6 h. D& A( h& v0 r2 c0 e: A根据数组长度,根据波特率大小,根据处理器速度,根据中断资源的支配# s" \6 R8 r- p; j
适当增加timeout ,或减小timeout 会节约系统开支或保证系统运行的稳定性: J; p& i6 z  X7 M7 S% H4 S
不会丢数据- M; h' O9 `  }/ U% T8 Q' G
使用while有几个弊端,不仅程序写的难看
: J3 ]5 b' e2 F, d- X$ O万一,HAL_UART_Transmit()返回的不是HAL_OK而是HAL_TIMEOUT,程序卡死在这里都不知道
7 E' G9 y* i0 V# M/ x6 A作为程序员,自己写的程序的运行次数和运行时间一定要牢记在心的 9 U' F* I7 i! N' }7 q
/ p( M- N9 }* h& E) n* x. E
HAL_UART_Transmit()用起来简单,全局可用  U% C0 X1 I, c% _6 [, d
只是编程思想上要和HAL库统一起来' w8 ?: x. K8 D( e- ?: k
uint32_t transmit[3] ={1,2,3};     //发送的数组最好不要像这样定义成32位的  根据C语言,名字"transmit"就是32位指针. B9 H. t+ N+ Z
uint8_t transmit[3] ={1,2,3};      //定义成这样8位的   根据C语言,名字"transmit"就是8位指针对应于形参uint8_t *pData
+ N$ d6 I1 y) b$ J9 b HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size, uint32_t Timeout)
6 h* R8 n7 n5 z, Q2 ?( t5 f; j3 R( ?- [6 b  a; ?0 ~# Y

: U5 w. ^8 f; |8 L+ p" Jstm32cubemx很重要的思想就是:/*USER CODE BEGIN*/
( n9 D4 F. s- }1 Y- U4 @                                                               。。。//在KEIL中编辑* [0 R: N, B/ Z7 i, ~; }% ^
                                                     /*USER CODE END*/
5 c& r% V; V' ^9 {5 O代码一定!!!要放在这之间,可以用MDK和cubeMX两个软件同时!!!对代码进行更新" U  T' a4 v& J
假设当你程序写UART完了,又需要添加新外设TIM1时可以用CUBEMX添加新外设
' V# t7 c- \* A在CUBEMX软件中点击Project Generate Code
, v2 n, [5 `. K' `" LCUBEMX软件不会改变/*USER CODE BEGIN*/ 到 /*USER CODE END*/之间的代码
  y( W1 P8 m  b' }9 B6 d3 L( F8 G5 ^7 w
$ m! j2 t, k, w; H" Z/ s: i' _
) u5 ?8 g3 N1 E0 I3 v* P2 H环境:STM32CUBEMX,MDK-4
  D4 [8 r/ u7 h: n: M3 I  r8 J硬件:STM32F405RGTx,LQFP64封装
- L+ k0 g9 @) m& k+ w/ a$ IUART1:A9和A10
5 x% X' L6 T; ]* n! q& k简单的UART代码就没必要上传了吧, f5 E  U7 s+ g' m$ C( g+ y4 d
0 ?0 m) r4 X' Z, o; d

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 编辑 ; i+ b9 I+ I& @) k& o" S% c( \
MCU之路 发表于 2016-5-11 16:404 M+ f9 l( ]. O/ Y
你好  楼主 请问如果我不知道收到的数组有多少  只是知道一个上限,比如说我收到的数组是0-500的中的一个, ...
8 T1 [+ i' ~& d" @: N
(0)你的数组长度有上限,每组数组传输时间应该也有上限
1 z8 o5 i8 f9 v1 i" Q# l7 [, b" s(1)假设你在main()函数中有用hal_uart_transmit()传数组,这时来了一个更高级的中断(或者某个异常),如果这个中断(或异常)耗时太长,timeout太短就会丢数据。timeout够长,ha_uart_transmit()就会等待等到中断函数(或异常)结束,再继续传数据,所以timeout和你的中断耗时(异常耗时)有一定关系,timeout其实就是“等待”的意思.* ^" R2 `1 V5 G( J; p
(2)如果你传递任意长数组,每一组数传递时间间短(在ms级别)的话,可以考虑加大(如timeout =100000;)  n% H% S4 w7 Q/ I
用公式  等待时长 =timeout/(hclk/1000)单位秒   计算你需要的时长(timeout最大0xffff ffff 42亿多)
: P% o: t: P4 A+ a9 a(4)建议按照严格的传输协议传数据,不要写容易卡死的程序,写能处理异常的程序才是好程序
david2016 回答时间:2016-5-12 17:35:22
while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout));   关于这一点。。。 8 e) u' t, T, }9 Z) m
不会去用这句话吧?官方的demo是这样的
3 ]5 q, n% {* R( }8 t3 z8 _! Aif(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout))
% B2 v" s# H. Q: K3 ]- w% S+ D# t( g+ }{- A, U+ Y6 \; l
....................
& ^* D0 f1 X: ]9 L  b; J}   3 A" A6 @5 G: t6 O5 h6 U
我觉得 不会有人去那么白痴的去写while的、
david2016 回答时间:2016-5-12 17:36:29
另外 一般是采用中断发送。

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版