STM32CubeMX使用教程——使用485总线接收变送器数据

本文介绍如何使用STM32CubeMX配置STM32F407ZG芯片,实现通过485总线接收变送器数据的过程。包括引脚配置、时钟树配置、DMA与中断的设置,并给出了代码示例。

一、要使用的外设

  1. USART1(引脚PA9、PA10)用于打印信息
  2. USART2(引脚PA2、PA3)用于接收485总线上的数据,使能PG8用于控制485收发。
  3. 灯(引脚PF9、PF10)点灯用于程序调试查看运行状态。

二、使用STM32CubeMX生成工程

1、先打开MCU选择器
在这里插入图片描述
2、选择芯片,在搜索框里输入STM32F407ZG就会弹出STM32F407ZGT6,双击。
在这里插入图片描述
3、 进入配置界面。
上面有四栏,主要用的是引脚配置、时钟配置、工程管理。
左边有8栏,分别是内核、模拟量、定时器、通信、多媒体等相关的外设。
在这里插入图片描述

引脚配置

1、内核方面配置两个东西:RCC、SYS
时钟源的配置选择外部时钟
在这里插入图片描述
调试选项配置选SW
在这里插入图片描述
2、通信方面配置两个串口USART1、USART2
串口1用于打印信息,只修改模式为异步的,然后直接照着原理图在右边把引脚修改成USART1的复用模式。其它参数默认。
在这里插入图片描述
串口2用于接收SP3485传过来的信号,故要配置4个东西。
一是在右边修改引脚复用。不仅要设置PA9、PA10的复用,还要设置PG8为GPIO_Output,用于SP3485的收发控制。
在这里插入图片描述

二是参数设置里要修改波特率与变送器一致。
在这里插入图片描述
三是在NVIC里使能串口2的中断。
在这里插入图片描述
四是在DMA设置里添加引脚的DMA收发。
在这里插入图片描述

时钟树配置

开发板上外部晶振为8MHz
STM32F407ZGT6的最高主频到168M,使HCLK = 168Mhz即可:
在这里插入图片描述

工程管理

项目里设置名称、位置、IDE
在这里插入图片描述
代码生成器设置里设置生成独立的初始化文件:
在这里插入图片描述

生成项目

在这里插入图片描述

三、代码编辑

1、打开生成的项目如下:
在这里插入图片描述
2、主要在main.c文件里写

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
//相关文件的生成与头文件的包含都是自动生成的
#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>//自行包含头文件,为了使用prinrf()函数
#include <string.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t USART2_buff[10]={
   
   0};//定义一个接收缓存区
uint8_t USART2_RXbuff[10]={
   
   0};//定义一个正真的接收数组
uint8_t USART2_cut[2]={
   
   0};//后面会用到该数组存放响应指令截取后的两个字节

int Usart_Flag=1;//设置一个标志,外部硬件触发中断执行,中断回调函数的执行通过标志位触发主函数的执行

int val = 0;//这两个是用于拼接字符串并转换成int类型
char *pBuf = (char*)&val;

uint8_t stress_send[8]={
   
   0x01,0x03,0x00,0x04,0x00,0x01,0xC5,0xCB};  //485发送指令,读取压力值
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
extern DMA_HandleTypeDef hdma_usart2_rx;
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//定义中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{
   
   
	if(huart->Instance == USART2)  //如果是串口2中断
	 {
   
   	
			if((__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE) != RESET))//如果是接收完成中断,idle标志被置位
			{
   
    
				huart2.Instance->SR;                       //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
				huart2.Instance->DR;                       //读取数据寄存器中的数据
				
				HAL_UART_DMAStop(&huart2); //关DMA
				
				hdma_usart2_rx.Instance->NDTR;            // 获取DMA中未传输的数据个数
				memcpy(USART2_RXbuff,USART2_buff,sizeof(USART2_RXbuff));//将USART2_buff中的数据复制到USART2_RXbuff
				//printf("复制前的数组为%d\r\n",USART2_buff[0]);
				//printf("复制后的数据为%d\r\n",USART2_RXbuff[0]);
				//printf("串口2接收数据:%s\r\n",USART2_RXbuff);//打印接收长度
				//printf("进入中断\r\n");
				memset(USART2_buff,0,sizeof(USART2_buff));    //清空缓存区
				__HAL_UART_CLEAR_IDLEFLAG(&huart2);               //清除标志位
				Usart_Flag = 1;//标志置1,启动后台程序
				
				HAL_UART_Receive_DMA(&huart2,USART2_buff,sizeof(USART2_buff));  //开DMA接收,数据存入rx_buffer数组中。
			}
	 }
 }
/* USE
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值