STM32H743多路串口调试经验总结(HAL库)

STM32H743多路串口调试经验总结(HAL库)

一、硬件基础

1、STM3H743核心板
2、自制串口拓展板(控制485收发使用的TDHx01D485H2隔离模块,该模块EN为低电平是发送,高电平接收)在这里插入图片描述

3、485串口模块

二、软件基础

从正点原子官方下载hal库例程,移植485.c文件,进行适当修改,我一共配置6个串口,以UART5对应的485_5.h和485_5.c为例进行配置:

1、RS485_5.h

#ifndef __RS485_5_H
#define __RS485_5_H
#include "sys.h"
extern u8 RS485_5_RX_BUF[64]; 		/接收缓冲 可自己定义
extern u8 RS485_5_RX_CNT;   			//接收数据长度

//如果想串口中断接收,设置EN_UART5_RX为1,否则设置为0
#define EN_UART5_RX 	1			//0,不接收    1,接收

void RS485_5_Init(u32 bound);
void RS485_5_Send_Data(u8 *buf,u8 len);
void RS485_5_Receive_Data(u8 *buf,u8 *len);	
#endif

2、RS485_5.c

 2.1  首先是控制RS485芯片的发送使能
/*  控制RS485芯片发送使能 */
#define RS485_TXEN_5_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOH_CLK_ENABLE()
#define RS485_TXEN_5_GPIO_PORT              GPIOA
#define RS485_TXEN_5_PIN                    GPIO_PIN_7

#define RS485_RX_EN_5()	RS485_TXEN_5_GPIO_PORT->BSRRL = RS485_TXEN_5_PIN
#define RS485_TX_EN_5()	RS485_TXEN_5_GPIO_PORT->BSRRH = RS485_TXEN_5_PIN
 2.2 然后配置UART5中断函数
void UART5_IRQHandler(void)
{
    u8 res;	  
    if(__HAL_UART_GET_IT(&UART5_RS485Handler,UART_IT_RXNE)!=RESET)  //接收中断
	{	 	
        HAL_UART_Receive(&UART5_RS485Handler,&res,1,1000);
		if(RS485_5_RX_CNT<64)
		{
			RS485_5_RX_BUF[RS485_5_RX_CNT]=res;		//记录接收的值
			RS485_5_RX_CNT++;						//接收数据增加1 
		} 
	} 
}  
2.3 然后进行485初始化配置
void RS485_5_Init(u32 bound)
{
    //GPIO端口设置
	GPIO_InitTypeDef GPIO_Initure;
	__HAL_RCC_GPIOA_CLK_ENABLE();			//使能GPIOA时钟
	__HAL_RCC_GPIOB_CLK_ENABLE();			//使能GPIOB时钟
	__HAL_RCC_GPIOD_CLK_ENABLE();			//使能GPIOB时钟
	__HAL_RCC_UART5_CLK_ENABLE();			//使能UART5时钟
	
	GPIO_Initure.Pin=GPIO_PIN_6; //PB6
	GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
	GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
	GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;//高速
	GPIO_Initure.Alternate=GPIO_AF14_UART5;	//复用为UART5 TX
	HAL_GPIO_Init(GPIOB,&GPIO_Initure);	   	//初始化PB6
	
  	GPIO_Initure.Pin=GPIO_PIN_2; //PD2
	GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
	GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
	GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;//高速
	GPIO_Initure.Alternate=GPIO_AF8_UART5;	//复用为UART5 RX
	HAL_GPIO_Init(GPIOD,&GPIO_Initure);	   	//初始化PD2
	
  GPIO_Initure.Pin=GPIO_PIN_7; //PA7
	GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;		//推挽输出
	GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;//高速
	HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA7
    //UART5初始化设置
	UART5_RS485Handler.Instance=UART5;			        //UART5
	UART5_RS485Handler.Init.BaudRate=bound;		        //波特率
	UART5_RS485Handler.Init.WordLength=UART_WORDLENGTH_8B;	//字长
	UART5_RS485Handler.Init.StopBits=UART_STOPBITS_1;		//一个停止位
	UART5_RS485Handler.Init.Parity=UART_PARITY_NONE;		//无奇偶校验位
	UART5_RS485Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;	//无硬件流控制
	UART5_RS485Handler.Init.Mode=UART_MODE_TX_RX;		    //收发模式
	HAL_UART_Init(&UART5_RS485Handler);			        //HAL_UART_Init()会使能UART5
    
    __HAL_UART_CLEAR_IT(&UART5_RS485Handler,UART_CLEAR_TCF);
#if EN_UART5_RX
	__HAL_UART_ENABLE_IT(&UART5_RS485Handler,UART_IT_RXNE);//开启接收中断
	HAL_NVIC_EnableIRQ(UART5_IRQn);				        //使能UART5中断
	HAL_NVIC_SetPriority(UART5_IRQn,3,3);			        //抢占优先级3,子优先级3
#endif	
   // RS485_RX_EN_5();  
RS485_TX_EN_5();	 //设置为接收模式
}

之所以讲UART5初始化,是因为该函数有个特殊的地方,有部分STM32H743开发板使用PC12作为UART5的TX,部分电路板使用PB6,这里需要看手册,手册中可得知,PC12复用UART5的TX是AF8,PB6复用UART5的TX是AF14,没有养成看手册的习惯,这里坑了我一天,请大家注意。

2.4 发送函数
void RS485_5_Send_Data(u8 *buf,u8 len)
{
	RS485_TX_EN_5();			//低电平设置为发送模式,在上面有定义
	delay_ms(1);
    HAL_UART_Transmit(&UART5_RS485Handler,buf,len,1000);//串口2 发送数据
	RS485_5_RX_CNT=0;	  
	RS485_RX_EN_5();			//设置为接收模式
	delay_ms(1);
}

有很多人会奇怪为什么会加delay_ms(1),此处也是一个坑,由于H743处理速度太快,当波特率设置过高时,会出现丢数据情况,越高丢的越多,因为管脚状态切换反应不过来,所以加一个1ms延时,该延时可根据具体情况自行修改,一般115200bps及以下不需要加该延时。

 2.5. 接收函数
void RS485_5_Receive_Data(u8 *buf,u8 *len)
{
	u8 rxlen=RS485_5_RX_CNT;
	u8 i=0;
	*len=0;				
	delay_ms(10);		
	if(rxlen==RS485_5_RX_CNT&&rxlen)
	{
		for(i=0;i<rxlen;i++)
		{
			buf[i]=RS485_5_RX_BUF[i];	
		}		
		*len=RS485_5_RX_CNT;	
		RS485_5_RX_CNT=0;		
	}
} 

3.mian.c

int main(void)
{
	u8 rs485sendbuf5[5] = {0x51,0x53,0x55,0x58,0xff};
	u8 rs485recivebuf5[5];
	u8 length5;
	Cache_Enable();                			//打开Li - cache
	HAL_Init();				        		//初始化HAL库
	Stm32_Clock_Init(160,5,2,4);  		    //设置时钟,400M
	delay_init(400);						

	//RS485_1_Init(1000000);		        		
	//RS485_2_Init(1000000);		        		
	//RS485_3_Init(1000000);		        		
	//RS485_4_Init(1000000);		        		
	RS485_5_Init(1000 000);		        		
	//RS485_6_Init(1000000);		        		
 									  	  
	while(1)           
	{	
		RS485_5_Send_Data(rs485sendbuf5,5);	
		delay_ms(200);
		RS485_5_Receive_Data(rs485recivebuf5,&length5);
	}	     
}

三、心得

我的工程书如下图所示:
在这里插入图片描述
大拿可以将六个串口整合到一块,但是我是初学者,还有待提升,大佬勿喷,这是我做的项目的一个分支,从对STM32不太熟悉,两个礼拜一直从STM32F103学习到STM32F407,再到STM32H743,从标准库到HAL库,可能还比较笼统,没有养成看手册习惯,调试没有配合硬件一起调的习惯,继续努力改进吧。希望这篇文章中关于STM32H743的串口配置和需要注意的地方能帮助到大家。

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值