迅维网

查看: 1945|回复: 0
打印 上一主题 下一主题

F412ZG串口通信代码框架生成分析+代码移植+通信实验实现

[复制链接]
跳转到指定楼层
1#
发表于 2017-2-18 16:02:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 来自: 山东青岛 来自 山东青岛

马上注册,获取阅读精华内容及下载权限

您需要 登录 才可以下载或查看,没有帐号?注册

x
本次帖子主要是对STM32CubeMX生成的串口通信框架进行分析。
一、硬件分析。
1.    对于STM32F412来说一共有USART1,USART2,USART3,USART6四个同步异步通信接口,接口引脚定义如下:

                               
登录/注册后看高清大图
因为串口1和串口3默认已经被使用,因此本次使用串口6进行通信实验。首先打开上一次新建的STM32CubeMX的工程。使能USART6模块。如下图所示:

                               
登录/注册后看高清大图
时钟设置上一次评测也已经详细分析过,这里不做介绍。

                               
登录/注册后看高清大图
串口参数设置:115200波特率,8数据位,1停止位,无校验。

                               
登录/注册后看高清大图
开启串口6全局中断。

                               
登录/注册后看高清大图
NVIC中断向量控制器设置:设置串口6的抢占优先级和次优先级都为0.

                               
登录/注册后看高清大图
把上次评测写好的SYSTICK延时函数添加到现有工程中来,编译之后没有错误,下面是生成的框架结构。

                               
登录/注册后看高清大图

二、生成的代码框架分析。
1.      重要结构体说明:首先对HAL中关于串口的主要结构体变量进行说明。首先对UART_HandleTypeDef这个结构体。其中的红框中的qian2两个主要是这次初始化时的重点之处。

                               
登录/注册后看高清大图
Instance处主要存放的是寄存器基地址参数,类似于Windows编程中的实例句柄。当定义了UART_HandleTypeDef结构体变量,并对其中的Instance赋值某一个串口之后,以后对该串口的操作都可以通过对定义的UART_HandleTypeDef结构体变量进行操作来实现。
UART_InitTypeDef结构体主要是对串口进行初始化的相关参数设置,其中就包括我们经常设置的波特率,起始位停止位之类的。

                               
登录/注册后看高清大图
2.    框架分析。
STM32CubeMX生成的函数中重要的一个函数是  MX_USART6_UART_Init();该函数主要是对串口的参数进行设置。下面是这个函数的主要内容。

                               
登录/注册后看高清大图
该函数中的参数设置与我们之前使用STM32CubeMX生成代码时选择的设置是一样的。这里面主要重要的是这个函数: HAL_UART_Init(&huart6);进入该函数查看,其中有这样一句话:

                               
登录/注册后看高清大图
If中的判断语句主要是判断相关串口是否已经被初始化。如果没有被初始化就会执行if语句中的代码。

                               
登录/注册后看高清大图
If语句中的函数HAL_UART_MspInit(huart);也是由STM32CubeMX生成的代码。如下图所示,这个函数主要是初始化与串口使用的硬件相关的GPIO口,这样写的好处是便于以后进行移植。

                               
登录/注册后看高清大图
到此处就已经把串口相关的参数就已经初始化完成了。下面来看看中断响应函数如何对中断进行响应。
STM32CubeMX生成的文件中,stm32f4xx_it.c文件中就定义了串口6的中断响应函数。

                               
登录/注册后看高清大图
函数内部执行的函数  HAL_UART_IRQHandler(&huart6);主要是对发生的中断类别进行分辨,这样就确定调用哪一个中断相应函数。对于此我们比较关注的是UART_Receive_IT(huart);这个函数,用来进行中断接收响应的。
最终会执行我们自己写的HAL_UART_RxCpltCallback(huart);用来对接收中断进行处理。
3.    代码框架移植:为了提高代码的移植性,下面对整体生成的框架进行移植。代码移植之后主要添加了bsp_usart.c,bsp_usart.h文件,代码如下所示。
  • //bsp_usart.h文件内容
  • //串口初始化说明
  • #ifndef __USART__
  • #define __USART__
  • /* 包含头文件 ----------------------------------------------------------------*/
  • #include "stm32f4xx_hal.h"
  • extern UART_HandleTypeDef huart6;//存放串口6相关的参数
  • extern uint8_t rxbuf;//用于存放串口接收的数据
  • //对于想使能串口接收中断使用函数 HAL_UART_Receive_IT()即可
  • void MX_USART6_UART_Init(void);//串口6的初始化函数声明
  • #endif


[color=rgb(51, 102, 153) !important]复制代码

  • //bsp_usart.c文件内容
  • #include "bsp_usart.h"
  • UART_HandleTypeDef huart6;//存放串口1相关的参数
  • uint8_t rxbuf;//用于存放串口接收的数据
  • /* USART6 init function */
  • void MX_USART6_UART_Init(void)
  • {
  •   huart6.Instance = USART6;
  •   huart6.Init.BaudRate = 115200;
  •   huart6.Init.WordLength = UART_WORDLENGTH_8B;
  •   huart6.Init.StopBits = UART_STOPBITS_1;
  •   huart6.Init.Parity = UART_PARITY_NONE;
  •   huart6.Init.Mode = UART_MODE_TX_RX;
  •   huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  •   huart6.Init.OverSampling = UART_OVERSAMPLING_16;
  •         HAL_UART_Init(&huart6);
  • }
  • //串口相关GPIO口初始化操作 该函数是弱函数不需要进行声明
  • void HAL_UART_MspInit(UART_HandleTypeDef* huart)
  • {
  •    GPIO_InitTypeDef GPIO_InitStruct;
  •   if(huart->Instance==USART6)
  •   {
  •   /* USER CODE BEGIN USART6_MspInit 0 */
  •   /* USER CODE END USART6_MspInit 0 */
  •     /* Peripheral clock enable */
  •     __HAL_RCC_USART6_CLK_ENABLE();
  •     /**USART6 GPIO Configuration
  •     PC6     ------> USART6_TX
  •     PC7     ------> USART6_RX
  •     */
  •     GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
  •     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  •     GPIO_InitStruct.Pull = GPIO_PULLUP;
  •     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  •     GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
  •     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  •     /* Peripheral interrupt init */
  •     HAL_NVIC_SetPriority(USART6_IRQn, 0, 0);
  •     HAL_NVIC_EnableIRQ(USART6_IRQn);
  •   /* USER CODE BEGIN USART6_MspInit 1 */
  •   /* USER CODE END USART6_MspInit 1 */
  •   }
  • }
  • /**
  •   * 函数功能: 串口硬件反初始化配置
  •   * 输入参数: huart:串口句柄类型指针
  •   * 返 回 值: 无
  •   * 说    明: 该函数被HAL库内部调用
  •   */
  • void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
  • {
  •   if(huart->Instance==USART6)
  •   {
  •   /* USER CODE BEGIN USART6_MspDeInit 0 */
  •   /* USER CODE END USART6_MspDeInit 0 */
  •     /* Peripheral clock disable */
  •     __HAL_RCC_USART6_CLK_DISABLE();
  •     /**USART6 GPIO Configuration
  •     PC6     ------> USART6_TX
  •     PC7     ------> USART6_RX
  •     */
  •     HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6|GPIO_PIN_7);
  •     /* Peripheral interrupt DeInit*/
  •     HAL_NVIC_DisableIRQ(USART6_IRQn);
  •   }
  •   /* USER CODE BEGIN USART6_MspDeInit 1 */
  •   /* USER CODE END USART6_MspDeInit 1 */
  • }
  • //中断响应回调函数的定义
  • void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  • {
  •         if(huart->Instance==USART6)//串口6的接收中断
  •         {
  •                 HAL_UART_Transmit(&huart6,&rxbuf,1,0);
  •                 HAL_UART_Receive_IT(&huart6,&rxbuf,1);
  •         }
  • }


[color=rgb(51, 102, 153) !important]复制代码


主函数代码:
  • int main(void)
  • {
  •   /* USER CODE BEGIN 1 */
  •   uint8_t txbuf[50];
  •   /* USER CODE END 1 */
  •   /* MCU Configuration----------------------------------------------------------*/
  •   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  •   HAL_Init();
  •   /* Configure the system clock */
  •   SystemClock_Config();
  •   /* Initialize all configured peripherals */
  •   MX_GPIO_Init();
  •   MX_USART6_UART_Init();
  •   /* USER CODE BEGIN 2 */
  •         delay_init(100);
  •         memcpy(txbuf,"串口中断接收返回的通信实验",100);
  •   HAL_UART_Transmit(&huart6,txbuf,strlen((char *)txbuf),1000);
  •         /* 使能接收,进入中断回调函数 */
  •   HAL_UART_Receive_IT(&huart6,&rxbuf,1);
  •   /* USER CODE END 2 */
  •   /* Infinite loop */
  •   /* USER CODE BEGIN WHILE */
  •   while (1)
  •   {
  •                 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
  •                 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET);
  •                 delay_ms(500);
  • //                HAL_Delay(200);
  •                 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);
  •                 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);
  • //                HAL_Delay(200);
  •                 delay_ms(500);
  •   /* USER CODE END WHILE */
  •   /* USER CODE BEGIN 3 */
  •   }
  •   /* USER CODE END 3 */
  • }

[color=rgb(51, 102, 153) !important]复制代码


三、通信实验
1.    STM32F412的硬件原理图

                               
登录/注册后看高清大图
2.    因为串口6是直接引出来的,其中没有串口转USB接口,因此我就用手头的一块开发板做转接。硬件图如下所示:

                               
登录/注册后看高清大图
连接关系一一对应即可。
3.    实际开发板连接图。

                               
登录/注册后看高清大图
4.    通信测试。
开发板上电之后,串口接收到数据。跟发送的数据是一样的。

                               
登录/注册后看高清大图
因为这个软件不是很好用,下面更换为我自己写的软件,并将端口号改为COM2。

                               
登录/注册后看高清大图
接收情况如下:

                               
登录/注册后看高清大图
程序能够正常运行。
四、总结
本次主要对生成的串口框架进行了分析,并将相关函数进行了移植,重新写了相关函数,下载到单片机中后能够很好的实现相应的功能。



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

本版积分规则

快速回复 返回顶部 返回列表
附近
店铺
微信扫码查看附近店铺
维修
报价
扫码查看手机版报价
信号元
件查询
点位图 AI维修
助手



芯片搜索

快速回复