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

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

[复制链接]
stmcuman 发布时间:2016-5-10 21:49
在main.c里
! e: H; o. H5 k( F2 m# e0 S" o  /* USER CODE BEGIN PV */
* _& n" M6 c) R$ C" Q, @5 P/ J  `/* Private variables ---------------------------------------------------------*/# E+ a: q7 J6 j, e
uint8_t transmit[3] ={1,2,3};      //定义8位数组,3个字节大小   
  j3 `4 K, K9 Tuint16_t len =3;+ Z) ~3 m, B; b8 Y
uint32_t timeout =10;$ q! \+ o. |! ]% \+ O# H  O3 G
/* USER CODE END PV */  w7 T. q6 y: J; b2 a

# d- G5 E- G8 m; B( t% U" {main(){: z* V* j) t4 q; l2 u, [+ Z& I
   HAL_UART_Transmit(&huart1, transmit,len, timeout); 5 [" {1 b6 |: C3 E) f
  while (1)
: s. b* A  b- ~* h# v- {! \  {}
+ s& @5 m* d1 Z6 Q' H" R: q}: x; `2 O9 p3 i9 X/ i
/ q; a  B9 p* e8 |" O! L
复位键启动程序,上位机接收到01 02 03
) m4 H+ d5 H+ h6 d/ o+ z  W1 G9 K+ R: @, x' F
关于timeout,它在HAL_UART_Transmit()里和uwTick做比较8 W! ~4 I/ s' ~, s! x
uwTick是全局变量,在中断函数SysTick_Handler()里一直循环递增; j5 O+ A6 O0 z; ^7 }6 L
) s2 Y9 s. h6 ]9 F: b" q( {
可在main.c>>SystemClock_Config(void)里找到HCLK/1000" R) ]  r9 d/ B, p* q. {) Q0 ~% F
HCLK/1000就是中断进SysTick_Handler()的次数  你的CPU有1000分之一时间都在做uwTick++;
9 R5 ?4 B  q6 M8 p# i! @HCLK是什么?请看附件图  y6 @* B9 o) _
- V2 i! `$ }4 `. N7 z2 ]
timeout的意义:& Z- i8 b' a( J/ S: f+ J; L3 X5 \
timeout就是等待上一字符发送完毕,或异常退出  , c: T* ]6 e  V; O3 ]
uint8_t string[123] ={0};   //这个数组很长3 N6 t1 B8 y! B
HAL_UART_Transmit(&huart1, transmit,len, timeout);                  //假设timeout=10;顺利从UART1发出
7 H+ G) Z0 W: x/ n$ _! w0 [HAL_UART_Transmit(&huart2, transmit,len, timeout);                   //timeout=10;够长,顺利从UART2发出 4 ~( T' s" D* I5 g# n' w/ k% b

. k/ s& e" n) ^1 Q- x关于传送完毕,有人用如下方法等待传送完毕; o- _8 D2 E* Z0 ?. E+ s7 G
虽然方案可行
1 w* n0 o  v5 ?9 I  w. d" {) Qwhile(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout));     
2 x  h& }1 B( m& r3 z4 b$ n& m这容易卡死,卡死都不知道2 Q3 i* H5 g# P& [$ \8 r3 j+ R
做产品应该尽量避免错误, a: m3 i# N8 I7 D3 I
" ^9 }1 M- n8 Z9 b/ S
很明显timeout提供一种方法(针对所有用到timeout的函数)
3 U* W8 @# o+ t' c根据数组长度,根据波特率大小,根据处理器速度,根据中断资源的支配. s, a- \, J7 W! R8 x# p  Q! ?: [
适当增加timeout ,或减小timeout 会节约系统开支或保证系统运行的稳定性- A3 i$ x0 |/ E: E
不会丢数据
" M5 g0 ]+ n5 M/ ~! a使用while有几个弊端,不仅程序写的难看1 _: ?& `& l4 K* h. X2 b( B
万一,HAL_UART_Transmit()返回的不是HAL_OK而是HAL_TIMEOUT,程序卡死在这里都不知道1 g" d" A+ r3 u9 y, v; A1 k1 C
作为程序员,自己写的程序的运行次数和运行时间一定要牢记在心的
# k* l7 a8 A6 y. r
' u8 H5 F8 X/ G( |  y  l6 b( EHAL_UART_Transmit()用起来简单,全局可用! @% w+ h/ s. @1 D; f0 c2 T- g
只是编程思想上要和HAL库统一起来
2 j" C: N: L: b" G; ^; m& ]. O% R8 tuint32_t transmit[3] ={1,2,3};     //发送的数组最好不要像这样定义成32位的  根据C语言,名字"transmit"就是32位指针% c, F" @6 W# z  g1 X  A. |1 o& p
uint8_t transmit[3] ={1,2,3};      //定义成这样8位的   根据C语言,名字"transmit"就是8位指针对应于形参uint8_t *pData
& c1 V3 Q, @' N; w HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size, uint32_t Timeout)
2 N3 ?( W$ K" l8 w5 J/ @
% z/ j* U( i4 E& J% S& A+ }$ C* s- Y1 T1 d& b
stm32cubemx很重要的思想就是:/*USER CODE BEGIN*/
" |9 b( z$ j  t$ G- [                                                               。。。//在KEIL中编辑
/ P: s% D5 y& G                                                     /*USER CODE END*/8 s9 |  ~+ ^5 P$ t# ]
代码一定!!!要放在这之间,可以用MDK和cubeMX两个软件同时!!!对代码进行更新
. K- \5 {4 h  t假设当你程序写UART完了,又需要添加新外设TIM1时可以用CUBEMX添加新外设
$ K0 R: k$ Z# _! ^4 D. _" k在CUBEMX软件中点击Project Generate Code0 _# ~" X2 g7 Q5 _! b3 e$ M
CUBEMX软件不会改变/*USER CODE BEGIN*/ 到 /*USER CODE END*/之间的代码! B" Z9 n, P3 F1 {& q
- @2 B0 ?$ }4 Y

( i4 {& q7 C' I" V0 f" L3 p  f% w环境:STM32CUBEMX,MDK-4" }+ i9 j! H3 f7 S
硬件:STM32F405RGTx,LQFP64封装
( B7 g4 Q; n) [( BUART1:A9和A10, k# V* j: F: a5 T/ F7 [
简单的UART代码就没必要上传了吧
8 ~5 n4 U, }( C0 \- j% L% c  `/ i7 B: p5 q1 Q

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 编辑
5 |! p, A0 H; d) b8 {) _
MCU之路 发表于 2016-5-11 16:40# L' T& \6 q7 ^" n3 O# q+ [3 Y
你好  楼主 请问如果我不知道收到的数组有多少  只是知道一个上限,比如说我收到的数组是0-500的中的一个, ...

: ?3 r4 O' r" D1 [# ^% y0 o1 `(0)你的数组长度有上限,每组数组传输时间应该也有上限& d. s; q5 k( M, `" v0 l
(1)假设你在main()函数中有用hal_uart_transmit()传数组,这时来了一个更高级的中断(或者某个异常),如果这个中断(或异常)耗时太长,timeout太短就会丢数据。timeout够长,ha_uart_transmit()就会等待等到中断函数(或异常)结束,再继续传数据,所以timeout和你的中断耗时(异常耗时)有一定关系,timeout其实就是“等待”的意思.$ u1 ~/ a: I+ L
(2)如果你传递任意长数组,每一组数传递时间间短(在ms级别)的话,可以考虑加大(如timeout =100000;)
0 H* E3 @$ P) s8 m5 d, Y5 ]8 B用公式  等待时长 =timeout/(hclk/1000)单位秒   计算你需要的时长(timeout最大0xffff ffff 42亿多)9 O: {( y( b0 N7 q$ ~
(4)建议按照严格的传输协议传数据,不要写容易卡死的程序,写能处理异常的程序才是好程序
david2016 回答时间:2016-5-12 17:35:22
while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout));   关于这一点。。。 / Z0 d. v* Z- d3 m4 J& R
不会去用这句话吧?官方的demo是这样的3 s9 L! c& j: n  j" w4 w
if(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout))% g- A5 H1 \$ @+ w  h
{
* O+ K& W+ c; X; i' f ....................3 @; Y7 c5 h* e1 ~0 @4 f3 t
}   & j2 ]) C  K5 R9 R
我觉得 不会有人去那么白痴的去写while的、
david2016 回答时间:2016-5-12 17:36:29
另外 一般是采用中断发送。

所属标签

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