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

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

[复制链接]
stmcuman 发布时间:2016-5-10 21:49
在main.c里& O$ t5 [. v$ ^3 D$ k+ j
  /* USER CODE BEGIN PV */
: Y+ x2 i: V: j1 l# M- {* G" J/* 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;
6 d7 |7 X; N3 s7 z2 t! G+ E+ c/* USER CODE END PV */
2 p% q7 c& f3 L4 D: \
/ X$ m9 j4 l% T) @8 Zmain(){
) ^6 ~, e' G0 z$ [   HAL_UART_Transmit(&huart1, transmit,len, timeout);
# W7 k  ?* N; o/ R* e2 d  P  while (1)9 g2 |( w" ~6 s% o2 D# \$ K
  {}
" M% H9 Z0 n( J9 n+ ?4 ^. x4 ^}
: Z, Z/ G% [! O. {. D% Q* H1 p
8 I8 w; p6 H9 E+ a$ d复位键启动程序,上位机接收到01 02 03& S3 t3 x  h2 d! S% r

" ~! r& O8 [; T" ?$ ~& V1 ~+ 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  |

6 I5 o4 _: L* J' P+ w/ J% w$ }$ V3 W可在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是什么?请看附件图
  ]5 U: p8 o0 V3 c; @) D2 `3 Z/ w" S3 P$ q, F  f  ^
timeout的意义:7 A' E8 H- c' v0 s
timeout就是等待上一字符发送完毕,或异常退出  
3 X. k! H) K9 e- X6 O0 ]% iuint8_t string[123] ={0};   //这个数组很长
" T. R$ j! J! @8 k" i0 u0 W6 sHAL_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发出
% I/ O+ D7 ?5 q6 [4 D* S! Z- d4 O, N; X0 Y/ ]8 C' J' I
关于传送完毕,有人用如下方法等待传送完毕
7 X% s6 u# F: w( f, W0 A. @4 W* G虽然方案可行4 {: e3 F6 w5 J
while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout));     % J8 s: ]! f1 R$ z6 _+ D
这容易卡死,卡死都不知道
8 A# y2 H) s2 K做产品应该尽量避免错误
/ V8 c; G# P: ~5 ^# z5 ~( {3 f  O/ M) B7 {
很明显timeout提供一种方法(针对所有用到timeout的函数)
9 `3 y! T% L4 b7 t根据数组长度,根据波特率大小,根据处理器速度,根据中断资源的支配
# X( M! d( ^+ ~1 r$ x# \适当增加timeout ,或减小timeout 会节约系统开支或保证系统运行的稳定性
2 x' u0 O, e( ?, d0 w+ X8 H不会丢数据; J+ b; s( c- ^/ i
使用while有几个弊端,不仅程序写的难看
  N1 t0 E$ K, x0 n6 R  Z5 f万一,HAL_UART_Transmit()返回的不是HAL_OK而是HAL_TIMEOUT,程序卡死在这里都不知道
1 Z* Y* e3 R9 A- T$ a. F作为程序员,自己写的程序的运行次数和运行时间一定要牢记在心的
; C9 s% ]+ q, x' {3 U& @$ ^$ n
  r# i8 P2 h* F2 y8 e0 D3 y" o/ y. r; ?; {HAL_UART_Transmit()用起来简单,全局可用" Y" |( g1 {3 x7 K. D  h  c
只是编程思想上要和HAL库统一起来
' E; X( q$ N& S& E% T1 `  o* Zuint32_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
( ?9 [3 x; W; z; _7 j HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size, uint32_t Timeout)
  z1 _+ `$ F& b, D0 H1 E# U2 T" a" H( T( e6 ]+ O

7 m" @9 g  l% f' e5 ]# Rstm32cubemx很重要的思想就是:/*USER CODE BEGIN*/
( E( e7 t; y& p: a                                                               。。。//在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
0 J6 C5 i. |; b6 PCUBEMX软件不会改变/*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
$ U9 d! X3 _0 o9 Y$ M8 M硬件:STM32F405RGTx,LQFP64封装
0 o8 f+ Q5 Z. d0 Z& `$ j/ `UART1:A9和A10
' G' d2 T( w. c! S6 q9 B简单的UART代码就没必要上传了吧" n9 o5 u$ |& Z% U
  n# V3 k- B6 d1 Y( F9 @3 q

HCLK在cubemx里有看见

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

举报

8个回答
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 R5 S# e) F4 L& ?# q
MCU之路 发表于 2016-5-11 16:40
$ _) R' x3 V, s% h% n你好  楼主 请问如果我不知道收到的数组有多少  只是知道一个上限,比如说我收到的数组是0-500的中的一个, ...

5 v1 d5 |. ?* C$ w5 L(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亿多)
' D0 S6 b8 M7 _(4)建议按照严格的传输协议传数据,不要写容易卡死的程序,写能处理异常的程序才是好程序
david2016 回答时间:2016-5-12 17:35:22
while(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout));   关于这一点。。。
) C0 v6 K# d$ `7 \8 w不会去用这句话吧?官方的demo是这样的
2 t7 @- g% n  B: R% q. V* x% a' Uif(HAL_OK !=HAL_UART_Transmit(&huart2, transmit,len, timeout))
3 t) \! O+ t' E# o{5 d- d) F3 A: @, T: C, h" D6 [
....................
. v0 @  \  Z- @8 f9 f}   3 W* R$ a; {. g6 O9 q! Y
我觉得 不会有人去那么白痴的去写while的、
david2016 回答时间:2016-5-12 17:36:29
另外 一般是采用中断发送。
leochen2019 回答时间:2019-11-12 09:27:49
楼主文章不错!新手学习啦!

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版