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

【经验分享】STM32L476G-Discovery 串口接收

[复制链接]
STMCU小助手 发布时间:2022-5-27 21:19
小D研究了如何通过串口模块(CH340)进行数据的发送。在本篇笔记中,我们会尝试从电脑发送数据到开发板。并通知电脑已经收到数据。
) {* y5 g% O* e
2 X0 C9 H: {' ?! j
一、发送数据的扩展——实现printf

1 X- t0 ~& |8 q4 J, ^5 G( m
printf是一个小D非常喜欢的调试工具。而在前面的代码编写中,我发现这玩意写进去好像没有什么卵用。于是查了一下资料。原来在单片机中,printf是要自己通过串口发送来实现的(实际上输出的内容会出现在sscom软件中。)至于原理是怎么样的,现在不去深究。直接把代码贴进自己项目先用着。在此感谢各位前辈的无私奉献。

( W6 G% a) K  J) @5 ^/ ^" D
首先,需要进行一个函数声明(可以直接写在main.c中)

/ ~( N% K5 j$ r: h5 j& t6 B3 s
int fputc(int ch,FILE *f);

/ g4 U9 q. O4 C% ~- m1 l) B; E
然后,进行函数实现:

' _/ ~, e6 J0 {% f# F
int fputc(int ch,FILE *f)
{
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart2,temp,1,2);
}
3 A1 I+ f$ `! U. `8 w9 e
从代码中不难看出,其实就是通过HAL库的发送方法,将信息通过UART2发送出去。如果你的项目里使用的是其他串口,请注意修改。
) |4 G% V" F4 r
现在,只需要正常的使用printf,在SSCOM软件中就可以看到输出了。可以开心的用printf调试啦。

$ x; ~$ z% I0 c
二、一个小技巧
0 e1 O$ G0 Z0 Q+ ?8 x
仔细观察STMCube帮我们生成的代码,小D发现,注释中标明了用户自己编写代码的区域。例如:
2 J& ^/ i0 W1 ^! }/ t& J8 {
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
" R0 L% @- N" l2 y( R
/* USER CODE END PV */

8 r2 G3 l3 x& u
或者
( N8 V8 d' U. U' N# X
/* USER CODE BEGIN 1 */
! _; u6 |4 ^) \! H: _
/* USER CODE END 1 */

  r" `7 _( {, t- m7 `
因为我们经常需要在后期通过STMCubeMX修改项目配置,进而重新生成代码。此时,写在这些注释中间的代码,是不会被替换掉的。所以,养成好的习惯很重要。记得把自己的代码写在这些注释块中间,可以省掉不少重复敲代码的时间呢。
8 d$ x! k* X/ J! u4 z
三、进入正题

" Z* a1 \. p% F) K' g  s( p
在翻阅网上的资料后,小D决定使用来HAL_UART_Recive_IT来进行接收。于是冒冒失失就按照例子把代码敲进去了。结果调试发现,并没有什么卵用。传说中的HAL_UART_RxCpltCallback方法根本不会运行。那么,到底是为什么呢?

% \& @- l4 @2 d# f: I' m9 d
HAL_UART_Recive_IT并不会影响主程序的运行,而是在收到规定长度的数据后,再通过HAL_UART_RxCpltCallback进行回调。那么,应该是中断没有被触发。经过多方查证,终于发现。中断模式必须要自己在STMCubeMX中配置,才会被启用。很多的新手引导贴都忽略了这个环节(估计是因为太基础了吧)。
6 m" t1 A4 g* _" w
打开STMCubeMX,通过Open Project打开自己的项目(啥?你不知道怎么打开,可以直接找到项目的保存目录,里面有一个.ioc的文件,双击,或打开项目时选择它都可以)。

7 e. b; L$ G) C/ D5 a
然后到配置界面(Configration)中,点击对应的串口,例如我的是USART2,然后找到中断设置(NVIC Setting),设置为允许中断(打勾即可)。如下图:
" h$ l- E8 ?, a. ?8 X

3 ]+ a( o- j8 ]! x; ?, ^
设置好后,重新生成代码。
* F# \8 Z- N- r' `3 U
首先,我们需要一个用来接收数据的缓冲区。因此,在全局变量中,我们声明了buffer,用来接收数据:

4 @3 M# h7 J  v" ]7 n" r
uint8_t buffer[512] = "";

$ P6 i9 F9 j, g6 ]
然后,回到MDK中,打开main.c。在main函数中的while循环前,加入以下代码:
9 U- G7 d# K  \3 ~  h
if(HAL_UART_Receive_IT(&huart2,(uint8_t *)&buffer,1)!=HAL_OK)
  {
    printf("Recived error.");
  }

9 [. C! p% Z% O4 |1 `
然后,实现HAL_UART_RxCpltCallback方法:
/ ~/ ?8 y( h- b
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
    printf("Recived data.");
    HAL_UART_Receive_IT(&huart2,(uint8_t *)&buffer,1);
}

% ]' Q7 g, m% U1 T
当收到数据的时候,打印Recived data。

4 y$ @! t+ ?: B: @" D1 P, d
编译并上传入开发板,然后运行。每次在SSCOM中点击发送数据。就会收到开发板返回来的打印信息了。如下图:
4 h) y: \" e1 p0 c. N
7YGBKI7[X]RP]VM_GD]WY_R.png

& U7 H; m0 H& r& l
说明开发板已经收到我们的数据了。并且还给出了响应。不过每次只收1个字节这种事情的确比较蛋疼。在实际的通讯中肯定不方便。原来在开发游戏的时候,我们一般都会采用自己的二进制协议来传输数据。那么,能不能把这些协议在单片机上实现呢?动手研究一下吧。

- W) ~2 n0 C+ Y: U
赞 收藏 评论0 发布时间:2022-5-27 21:19

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版