STM32F4工程--串口--配置一个发送函数(库函数)
一、初始化串口相关的参数
首先在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(),求字符串的长度。
(写此文章远远比想象的难,可能还有一些地方说的不是很清楚,非常欢迎私信和留言进行交流,如果对大佬您有帮助的话,还希望能给点个赞)
STM32F4工程--串口--配置一个发送函数(库函数)
一、初始化串口相关的参数
首先在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(),求字符串的长度。
(写此文章远远比想象的难,可能还有一些地方说的不是很清楚,非常欢迎私信和留言进行交流,如果对大佬您有帮助的话,还希望能给点个赞)
举报