查看: 1594|回复: 0

NUCLEO-L432 usart串口驱动分享

[复制链接]

该用户从未签到

发表于 2017-9-8 08:48:28 | 显示全部楼层 |阅读模式
分享到:
hello大家好,我又来了~ 因为最近工作忙,项目比较紧张,抽出时间来和大家分享一下关于l4的串口底层驱动。
针对于STM32系列单片机,本人是不推荐使用寄存器来进行开发的,开发的效率太低了。在ST官方可以看到一系列的STD标准库与HAL库,使用这一套标准,不仅刚接触该类单片机入手快,而且在ST的芯片与芯片的程序移植中非常吃香(从F1移植至F4库)。
本人是原本是偏爱STD库的,但是在接触F7的HAL库后(据我所知F7没有STD库),再使用STM32CubeMX工具,就对HAL无法自拔了!
终其原因如下:
1. 从F1开始一直覆盖至F7都有相对应的HAL库
2. HAL库所对应的串口、adc等各种句柄都非常简介明朗,配置起来甚至比STD库还要方便
3. STM32CubeMx可以直接生成代码
当然,令人迷恋的终究还是第三点。
废话说了一箩筐,咱们现在开始分享一下关于STM32L432的HAL库串口底层驱动方法,通过重定义绑定printf打印方法,来实现串口数据的输出。
首先打开STM32CubeMX工具,新建工程,选择STM32L432KC芯片。

进入工程之后,在Pinout中,使能串口2,同时在工具栏中打开Project项中的setting,如图
本人使用的开发工具是keil,版本号是5.21,所以在IDE选项中选择MDK-ARM V5,各位小伙伴选择相对应的环境就好,接着设置好项目名字(project name),项目位置(project location)即可。

接着在代码通用配置上(Code Generator),找到文件设置(Generated files),选中第一项,这样就可以独立生成对应的.c和.h文件了。这样咱们工程就配置好了,接着点击OK。
这是在工具栏上点击Project,下拉菜单选择Generate Code,等待进度条走完,提示Code success即可,如图
这样就可以直接打开项目工程了,保存在咱们刚刚在setting里面设定的位置(project location)里面。
打开工程后可以看到咱们新建立的工程目录非常清晰明朗,代码的条目也非常的清晰,简直太棒了
接下来咱们找到user目录,里面有main,gpio,usart等c和h文件,咱们现在要写的是串口底层,所以需要关注的是main文件和usart文件,现在打开main函数,可以看到里面已经将串口配置好了
int main(void){  /* USER CODE BEGIN 1 */  /* USER CODE END 1 */  /* MCU Configuration----------------------------------------------------------*/  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */  HAL_Init();  /* USER CODE BEGIN Init */  /* USER CODE END Init */  /* Configure the system clock */  SystemClock_Config();  /* USER CODE BEGIN SysInit */  /* USER CODE END SysInit */  /* Initialize all configured peripherals */  MX_GPIO_Init();  MX_USART2_UART_Init();  /* USER CODE BEGIN 2 */  /* USER CODE END 2 */  /* Infinite loop */  /* USER CODE BEGIN WHILE */  while (1)  {  /* USER CODE END WHILE */  /* USER CODE BEGIN 3 */  }  /* USER CODE END 3 */}在main函数里面可以看到有用的这么几句话:
MX_GPIO_Init();
  MX_USART2_UART_Init();
其他的关于时钟配置并不需要我们额外的关心,这时候咱们进入usart文件,可以观察一下串口的配置函数以及句柄
UART_HandleTypeDef huart2;/* USART2 init function */void MX_USART2_UART_Init(void){  huart2.Instance = USART2;  huart2.Init.BaudRate = 115200;  huart2.Init.WordLength = UART_WORDLENGTH_7B;  huart2.Init.StopBits = UART_STOPBITS_1;  huart2.Init.Parity = UART_PARITY_NONE;  huart2.Init.Mode = UART_MODE_TX_RX;  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;  huart2.Init.OverSampling = UART_OVERSAMPLING_16;  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;  if (HAL_UART_Init(&huart2) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }}void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle){  GPIO_InitTypeDef GPIO_InitStruct;  if(uartHandle->Instance==USART2)  {  /* USER CODE BEGIN USART2_MspInit 0 */  /* USER CODE END USART2_MspInit 0 */    /* USART2 clock enable */    __HAL_RCC_USART2_CLK_ENABLE();      /**USART2 GPIO Configuration        PA2     ------> USART2_TX    PA3     ------> USART2_RX     */    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;    GPIO_InitStruct.Pull = GPIO_PULLUP;    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);  /* USER CODE BEGIN USART2_MspInit 1 */  /* USER CODE END USART2_MspInit 1 */  }}void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle){  if(uartHandle->Instance==USART2)  {  /* USER CODE BEGIN USART2_MspDeInit 0 */  /* USER CODE END USART2_MspDeInit 0 */    /* Peripheral clock disable */    __HAL_RCC_USART2_CLK_DISABLE();      /**USART2 GPIO Configuration        PA2     ------> USART2_TX    PA3     ------> USART2_RX     */    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);  /* USER CODE BEGIN USART2_MspDeInit 1 */  /* USER CODE END USART2_MspDeInit 1 */  }} 需要关注的有三个函数:1. MX_USART2_UART_Init ()
2. HAL_UART_MspInit ()
3. HAL_UART_MspDeInit ()
第一个函数为串口初始化函数,调用这个函数即可完成串口的通用配置,第二个函数为串口的底层初始化,主要是gpio的配置,第三个函数为串口的重复位,主要是禁用时钟和引脚的重新复位。第三个函数基本用不到,咱们只需用到前两个函数即可完成串口的调配。
从代码上可以看到,咱们串口的波特率是115200,包括停止位,起始位以及校验位都已经配置好了,就缺一个写函数了,这时候咱们找一个串口写函数来~~~
void uart_write (USART_TypeDef *uart, uint8_t ch) {        while((uart->ISR&0X40)==0);        uart->TDR=ch;   }好的,现在咱们有初始化配置函数以及写函数,接下来咱们重定义一下printf的输出函数就好啦。int fputc (int ch, FILE *f) {        uart_write (USART2, ch);        return ch;}        这样咱们关于串口的所有配置就好了,接下来咱们写好main函数,就可以使用串口自由的打印数据了。void delay_ms () {        uint32_t val = 0x1FFF;                while (val--);}int main(void){        HAL_Init();        SystemClock_Config();        MX_GPIO_Init();        MX_USART2_UART_Init();        while (1)        {                printf ("Hello world \r\n");                delay_ms ();        }}把没用的注释都删了,保留有用的代码,在自写一个延时函数,咱们的代码部分就全部完成了,接下来就是令人兴奋的试验阶段了按F7将代码编译,然后按F8将代码骚录进去,打开串口调试助手,可以看到咱们想要的数据就来了
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /2 下一条

手机版|小黑屋|与非网

GMT+8, 2024-4-19 20:52 , Processed in 0.124530 second(s), 18 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.