首页 > 其他分享 >HAL库教程5:串口数据发送

HAL库教程5:串口数据发送

时间:2023-01-11 12:34:09浏览次数:37  
标签:教程 HAL 函数 引脚 UART 发送 串口


使用CubeMX配置串口1

配置引脚

  我的板子上使用插针引出了串口1,串口1连接PA8与PA9。

HAL库教程5:串口数据发送_串口


HAL库教程5:串口数据发送_引脚_02

配置串口通信参数

  使能串口1,并配置为异步模式,波特率为115200,模式8N1。

HAL库教程5:串口数据发送_教程_03

使能串口中断

HAL库教程5:串口数据发送_引脚_04

查看生成的代码

  引脚与中断的初始化在stm32f4xx_hal_msp.c

HAL库教程5:串口数据发送_HAL库_05


  而通信用到的参数,如波特率校验方式等初始化在main.c。

HAL库教程5:串口数据发送_引脚_06


  同样是串口初始化的代码,为什么要分开写?

  可能是分层思想,换板子的话,只用修改引脚与中断的函数,用户函数不用修改。比如用户关心波特率,不用关心引脚。

按键控制串口发送代码编写

  通过串口打印按键的信息。

//main.c
int main(void)
{
/* USER CODE BEGIN 2 */
u8 UART_BUF[12] = "you press A!";
u8 key;
/* USER CODE END 2 */

while (1)
{
key = KEY_Scan(0);
switch(key)
{
case KEY_A_PRES: UART_BUF[10] = 'A'; break;
case KEY_B_PRES: UART_BUF[10] = 'B'; break;
case KEY_C_PRES: UART_BUF[10] = 'C'; break;
case KEY_D_PRES: UART_BUF[10] = 'D'; break;
default: break;
}
if(key)
{
LED1 = !LED1;
HAL_UART_Transmit(&huart1,UART_BUF,12,0xffff);
}
/* USER CODE END WHILE */

}
}

  HAL_UART_Transmit是HAL库提供的串口发送函数。在HAL库的手册中,或者在代码中跳转到函数可以找到函数的说明信息。

HAL库教程5:串口数据发送_教程_07


  根据说明,这个发送函数是阻塞式的。参数Timeout是超时时间,代表某次执行函数,最多占用串口的时间,单位是毫秒。简单来说,在本次数据发送完之前,不能发送别的数据。所以,调用函数的时候要指明参数,本次发送占用多长时间,在此期间,由于串口资源被独占,不能成功调用发送函数。如果在规定的时间内,数据发送完毕,那就释放占用的串口资源;如果到了时间,即便数据还没有发送完毕,(比如数据量很大),仍需要归还串口资源的控制权,让别人来用。

  在正确连接硬件,并配置串口助手以后,可以看到按键信息如下,说明串口数据发送成功。

HAL库教程5:串口数据发送_教程_08


  需要说明的是,HAL库提供的发送函数不止一个,还有中断方式和DMA方式,这是这个函数用法最简单。

重映射Printf功能

  在刚刚的例子中,需要把字符装填到数组中,再通过数组来发送数据,比较麻烦,能否直接打印字符串?可以通过重映射C语言中的printf函数来实现。
  建立一个UART.c文件,添加到工程中。输入以下代码:

#include "stdio.h"
#include "main.h"

#ifdef __GNUC_
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

//重映射printf的功能
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);

return ch;
}

  注意在适当的地方要有huart1的外部声明。我写在了main.h中
extern UART_HandleTypeDef huart1;
  然后在主函数中可以调用printf。

//main() while(1)
if(key)
{
LED1 = !LED1;
printf("return value is %d! \r\n",key);
HAL_UART_Transmit(&huart1,UART_BUF,12,0xffff); //发送接收到的数据
}

HAL库教程5:串口数据发送_串口_09

引脚复用与功能重映射

  如果在STM32CubeMX中将PB6设置为串口功能,可以发现PA9变为了普通引脚。

HAL库教程5:串口数据发送_HAL库_10


  这说明PA9和PB6都可以作为串口1的TX引脚,但不能同时用。引脚有点像外设的出口,外设可以从前门出,也可以从后门出,但不能同时从前门和后门出去。

  引脚的功能不止一个,我们可以称之为引脚的复用;比如既可以作为普通的IO,用于操作LED或按键,又可以用作串口。

  某个外设不但可以连接到引脚x,也可以用到引脚y,我们称之为重映射。STM32单片机的功能比较强大,有很多外设。外设默认对应某个引脚,可以通过重映射的方法把一个外设映射到其它的引脚上,来充分利用片内资源。

  详细的引脚重映射情况可以查看数据手册表格9。


标签:教程,HAL,函数,引脚,UART,发送,串口
From: https://blog.51cto.com/u_12001544/6002127

相关文章

  • HAL库教程3:引脚输入检测
    使用CubeMX配置输入引脚  本章我们要把按键作为输入源,使用单片机来检测引脚的电平状态。首先要查看原理图,按键与那些引脚相连。  我使用的板子,按键K2-K5分别对应PA4-P......
  • HAL库教程1:STM32Cube的介绍
      使用STM32HAL库已经有了一段时间,觉得相比于标准库,好用了不少。加上STM32CubeMX图形化配置工具的加持,个人认为可以极大提升开发效率。其实关于HAL库的教程已经很多了,关于......
  • HAL库教程7:STM32的时钟系统
      STM32的时钟系统比较复杂,不像51单片机,可能只有一个时钟。原因:1、外设多,不同的外设有不同的时钟要求;2、功耗原因,速度越快,功耗越大,抗电磁干扰能力越弱。此处以STM32F405......
  • HAL库教程4:外部中断
    外部中断机制  本章我们仍然是通过按键来控制LED,只不过实现方式由轮询变为了外部中断。为什么需要外部中断?为了给CPU减轻负担。  举个例子  比如你今天有个快递,快递......
  • HAL库教程8:通用定时器的使用
    定时器溢出时间的计算  关于定时器溢出的时间计算,有个公式:  定时器本质上是一个不断自加的计数器,只不过在自加的时候,能够自动比较计数值跟某个设定值而已。定时器+1用......
  • HAL库教程9:串口接收不定长数据
      串口收到的两组数据之间,往往会有一定的时间间隔。可以判断这个间隔,来实现无需结束符,无需指定长度,串口可接收不定长数据的功能。如果串口在一定的时间内没有收到新的数据......
  • HAL库教程11:定时器的缓冲功能与影子寄存器
      在STM32的定时器中,TIMx_PSC、TIM_ARR两个寄存器加上捕捉比较模块中TIMX_CCR寄存器,它们都可以动态修改。不过他们的修改和生效可能不在同一个时刻,或者说,修改过后立即生......
  • HAL库教程10:定时器的PWM模式应用
      本节通过定时器的PWM模式驱动无源蜂鸣器,来演奏一段音乐。本博客在掌机的系列教程中介绍过蜂鸣器的驱动原理,感兴趣的可以参考​​电子琴​​无源蜂鸣器驱动电路  蜂鸣......
  • 电子设计教程20:晶体管负反馈放大电路的参数设计
    放大倍数的推导  我们假设的电路在没有负反馈的时候,电路增益为A(也称为开环增益,或者裸增益,等于各极增益的乘积)。实际放大倍数A_v可以表示为:  这个公式可以推导出来,但推......
  • 电子设计教程18:射极跟随电路的参数设计
      射极跟随电路的原理图在上一节我们已经通过理论分析大致画了出来。接下来求从“设计的角度”出发,思考射极跟随电路的原理。不但需要计算各器件的参数,还要进行参数调试。......