STM32F4工程--串口--配置一个发送函数(详细版)

STM32F4工程--串口--配置一个发送函数(库函数)

  ----芯片:STM32F429IGT6


目录:

一、初始化串口相关的参数

二、初始化串口IO口时钟等参数

三、函数声明

四、主函数(执行函数)

五、补充


一、初始化串口相关的参数

首先在usart.c文件中编写入下代码,稍后为大家解释如何得到的此函数。

#include "usart.h"                 //包含.h函数
UART_HandleTypeDef usrt1_handler;  //定义句柄
void uart1_init(void)              //自定义串口初始化函数
{
    usrt1_handler.Instance=USART1;                     //定义为串口1  
	usrt1_handler.Init.BaudRate=115200;                //波特率为115200
	usrt1_handler.Init.WordLength=UART_WORDLENGTH_8B;  //自长为8
	usrt1_handler.Init.StopBits=UART_STOPBITS_1;       //1位停止位
	usrt1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;  //不设置硬件流
	usrt1_handler.Init.Mode=UART_MODE_TX_RX;           //模式为收发模式
	usrt1_handler.Init.Parity=UART_PARITY_NONE;        //无奇偶检验位
	HAL_UART_Init(&usrt1_handler);                     //使能串口1
}

1、首先需要定义添加usart.h文件,我想这个大家都知道为什么。

#include "usart.h"

2、定义一个串口1初始化函数uart1_init(){},在这里编写一些串口的初始化语句。

在这个函数中,首先需要使能串口1,于是在函数中添加HAL_UART_Init();函数,这个函数声明在stm32f4xx_hal_usart.h,函数在stm32f4xx_hal_usart.c文件中,将.h文件中的HAL_UART_Init函数复制过去。如下图

这个函数的入口函数是一个结构体的指针地址。

#include "usart.h"
void uart1_init(void)
{
	HAL_UART_Init(UART_HandleTypeDef *huart);
}

3、右击HAL_UART_Init(UART_HandleTypeDef *huart);中的UART_HandleTypeDef,点击Go To Definition Of"......."

来找到这个结构体的定义。

4、这样我们就找到了这个结构体,结构体在stm32f4xx_hal_usart.h文件的第116行,这里定义的变量有很多,其中我们这次只用到其中的一部分。结构体如下图:

 这个结构体的 USART_TypeDef   *Instance;定义串口的基地址。UART_InitTypeDef     Init;  这个为定义串口初始化结构体,其余的为串口的收发以及DMA等的配置,在本例程中用不到,就先不解释了。

5、UART_HandleTypeDef usrt1_handler;

这个函数的意思是使用串口初始化结构体定义usrt1_handler变量。我们把它定义为全局变量。一般外设函数都有一个结构体指针,这个叫句柄,其他地方也会引用,故定义为全局变量。

#include "usart.h"

UART_HandleTypeDef usrt1_handler;
void uart1_init(void)
{
	HAL_UART_Init(UART_HandleTypeDef *huart);
}

6、HAL_UART_Init入口参数为指针类型,入口是一个地址,我们就将结构体的地址值赋给他,因为入口参数为一个地址,所以要在usrt1_handler前加取地址符号&。

#include "usart.h"

UART_HandleTypeDef usrt1_handler;
void uart1_init(void)
{
	HAL_UART_Init(&usrt1_handler);
}

7、现在我们只是定义了结构体,但是没有对结构体的成员变量进行初始化。下面我们将对串口结构体进行初始化。

首先是  usrt1_handler.Instance,Instance为USART_TypeDef结构体定义的变量。

右键点击USART_TypeDef,点击Go To Definition Of".......",寻找到他的定义。

好像也看不出什么。

快捷键Ctrl+F,在寻找USART_TypeDef还定义过那些,我们发现了USART1等等。我们将USART1赋值给Instance

于是有了

#include "usart.h"

UART_HandleTypeDef usrt1_handler;
void uart1_init(void)
{
	usrt1_handler.Instance=USART1;
	
	HAL_UART_Init(&usrt1_handler);
}

8、选好了串口1.我们将对串口1进行初始化,方法为:usrt1_handler.Init.=?,init为结构体UART_InitTypeDef所定义的变量,UART_InitTypeDef结构体的定义如下:

结构体中定义了波特率、字长、停止位、模式、硬件流控制、过采量等等,这才是串口外设的一些特性参数。

那么我们应该如何写来定义这些参数呢。

首先定义的为波特率,一般我们使用的为115200、9600都可以。这里使用的是115200.

其次定义的是字长,我们选择的是八位,那我们usrt1_handler.Init.WordLength=8;    我们这样直接等于8?这样合适吗,很显然是不正确的。

我们使用Ctrl+F快捷键,在stm32f4xx_hal_usart.c中搜索WordLength,我们可以搜索到如下语句。

我们查看一下IS_UART_WORD_LENGTH的定义,我们可以看到如下

这里我们可以看到我们可以选择UART_WORDLENGTH_8B和UART_WORDLENGTH_9B,我们这里选择的是UART_WORDLENGTH_8B

#include "usart.h"

UART_HandleTypeDef usrt1_handler;
void uart1_init(void)
{
	usrt1_handler.Instance=USART1;
	usrt1_handler.Init.BaudRate=115200;
	usrt1_handler.Init.WordLength=UART_WORDLENGTH_8B;
	HAL_UART_Init(&usrt1_handler);
}

9、我们可以用同样于字长定义的方法将下面一些参数进行定义,就可以得到本节最开始的那个函数。


二、初始化串口IO口时钟等参数

usart.c文件中编写入下代码

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
		GPIO_InitTypeDef GPIO_Initure;
    if(huart->Instance==USART1)
    {
			__HAL_RCC_GPIOA_CLK_ENABLE();			//使能GPIOA时钟
			__HAL_RCC_USART1_CLK_ENABLE();			//使能USART1时钟
		
			GPIO_Initure.Pin=GPIO_PIN_9;			//PA9
			GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
			GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
			GPIO_Initure.Speed=GPIO_SPEED_HIGH;		//高速
			GPIO_Initure.Alternate=GPIO_AF7_USART1;	//复用为USART1
			HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA9

			GPIO_Initure.Pin=GPIO_PIN_10;			//PA10
			HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA10
		}
}

1、这个函数我想大家都能看懂,但是大家可能想为什么使用这个函数名,因为这个函数在stm32f4xx_hal.c函数中有定义,并定义为__weak函数

在hal库中这个函数被HAL_UART_Init();函数所调用。

2、也正是因为被HAL_UART_Init函数所调用,于是我们在函数内添加了 if(huart->Instance==USART1) 来判断是否是串口1,如果是串口1,才会执行下面的IO等参数的初始化。


三、函数声明

usart.h文件中编写入下代码,来进行函数声明和句柄的引用。

#ifndef _USART_H
#define _USART_H
#include "sys.h"
#include "stdio.h"	

extern UART_HandleTypeDef usrt1_handler;
void uart1_init(void);
#endif

四、主函数(执行函数)

在main.c文件中加入如下代码

/**************************************************************************
**作者:        小丁工程               
**时间:        2020.10.19
***************************************************************************/
#include "sys.h"
//---------------------主函数-------------------------------------------------


int main(void)
{
    u8 p[]="test";
    HAL_Init();//========================初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);//======设置时钟,180Mhz
    delay_init(180);//===================初始化延时函数
    uart1_init();	
    while(1)
    {			
			HAL_UART_Transmit(&usrt1_handler,p,sizeof(p),1000 );
			delay_ms(300);	
		}
}
//---------------------end-----------------------------------------------------

HAL_UART_Transmit();函数为发送函数,入口参数有四个,基地址、数据、数据长度、最大等等时间。


五、补充

1、__weak函数为弱函数,意义为在没有用户函数的情况下执行此函数,当有用户定义此函数时,__weak函数视为没有。两个不冲突。

2、sizeof(),求字符串的长度。


(写此文章远远比想象的难,可能还有一些地方说的不是很清楚,非常欢迎私信和留言进行交流,如果对大佬您有帮助的话,还希望能给点个赞)(侵删)

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
将RT-Thread和LwIP移植到STM32F4平台需要一些步骤,下面是一个简单的指南: 1.下载RT-Thread源代码和LwIP源代码。可以从官方网站获取最新本。 2.将RT-Thread和LwIP源代码添加到您的工程中。可以直接将源代码文件复制到您的工程目录中,也可以在工程中创建一个新的文件夹,并将源代码添加到该文件夹中。 3.根据您的硬件配置,对STM32F4的寄存器和外设进行初始化。通常,您需要根据硬件手册编写一些初始化代码,以使STM32F4与RT-Thread和LwIP兼容。 4.配置LwIP选项。通过修改lwipopts.h文件,您可以配置LwIP的各种选项,例如IP地址、子网掩码、网关等。 5.在RT-Thread的配置文件rtconfig.h中启用LwIP组件。找到RT-Thread中的lwip组件选项,并确保它被启用。 6.修改RT-Thread的初始化代码,以初始化并启动LwIP。在RT-Thread的应用程序入口函数中,添加初始化LwIP的代码。这包括为LwIP创建一个线程,并为网络接口分配内存等。 7.根据您的需求配置LwIP和RT-Thread的线程、任务和堆栈大小。这些参数的默认值可能不适合您的应用,您可以根据需要进行调整。 8.编译并烧录您的应用程序到STM32F4上。使用合适的编译工具和烧录器,将代码编译成二进制文件,并烧录到STM32F4上。 9.测试和调试。在STM32F4上运行您的应用程序,并使用适当的工具(例如串口终端)检查网络连接。您还可以使用调试器来调试您的应用程序,并解决可能遇到的问题。 这只是一个初步指南,具体的移植过程可能因个人需求和硬件平台的差异而有所不同。对于更深入的了解,建议参考LwIP和RT-Thread的官方文档和社区讨论。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值