波特率要改为9600
数据的传输并非二进制数,而是 ASCII 值
1. 串口接收中断程序的配置(HAL库)
(1)首先要去配置串口相关的参数(确定USARTx口、配置波特率、字节长度······),并且要使能串口(调用函数HAL_UART_lnit();)
例如:
void uart1_init()
{
usart1_handler.Instance=USART1; //USART1
usart1_handler.Init.BaudRate=115200; //波特率
usart1_handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
usart1_handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
usart1_handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
usart1_handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&usart1_handler); //HAL_UART_Init()会使能UART1
}
(2)在HAL_UART_Msplnit 中调用 HAL_GPIO_lnit()来进行相关io口的复用配置,同时不要忘记使能USARTx通道,并且配置中断优先级。
串口接收中中断优先级函数配置: HAL_NVIC_SetPriority(USART1_IRQn,3,3); //抢占优先级3,子优先级3
以及串口USARTx通道的使能函数:HAL_NVIC_EnableIRQ(USART1_IRQn); //使能USART1中断通道
串口设置的一般步骤:
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_Initure;
if(huart->Instance==USART1) //如果是串口1,进行串口1 MSP初始化
{
__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_FREQ_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
HAL_NVIC_EnableIRQ(USART1_IRQn); //使能USART1中断通道
HAL_NVIC_SetPriority(USART1_IRQn,3,3); //抢占优先级3,子优先级3
}
}
(3)编写中断服务函数
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&usart1_handler); //开启串口USARTx的中断服务
while (HAL_UART_GetState(&usart1_handler) != HAL_UART_STATE_READY); //等待就绪
while(HAL_UART_Receive_IT(&usart1_handler, (u8 *)rdata, 1) != HAL_OK);
}
(4)可以调用串口接收中断函数:HAL_UART_Receive_IT(&usart1_handler, (u8 *)rdata, 1);
rdata:指的是一个存放接收大的数据的数据的数组,可以声明为:u8 rdata[1];
如果要进行数据的运算或处理,不要忘记是ASCII 值,要做 x=rdata[0]-‘0’; 这一步处理才能进行正确运算;
1:是指传输数据的大小,此处指的是数据在一位一位的传输;
使用串口接收中断函数,在整个数据被一位一位接收直到结束后会开启中断,停止继续传输相同的内容。
注意:如果在stm32中遇到代码中中断接受函数是如下图我标注的,接收中断收到的数据末尾就需要以0x0d 0x0a结尾,则需要添加 printh 0D 0A 来发送两个十六进制数。这段代码在f429中被注释了所以串口屏中不需要添加 printh 0D 0A 这个了
以下是我所使用的代码,实测可用,要注意的是要将串口通信实验中的 uart.c 源文件删去以免产生影响,所以无法使用显示屏
所以使用 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 这个回馈函数将数据在传输到电脑串口用原子的 XCOM V2.0 软件来读取值。
#include "sys.h"
#include "delay.h"
u8 rdata[1];
UART_HandleTypeDef usart1_handler; //UART句柄
void uart_init()
{
usart1_handler.Instance=USART1; //USART1
usart1_handler.Init.BaudRate=9600; //波特率
usart1_handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
usart1_handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
usart1_handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
usart1_handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&usart1_handler); //HAL_UART_Init()会使能UART1
usart2_handler.Instance=USART2; //USART2
usart2_handler.Init.BaudRate=9600; //波特率
usart2_handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
usart2_handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
usart2_handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
usart2_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
usart2_handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&usart2_handler); //HAL_UART_Init()会使能UART2
}
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_Initure;
if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
{
__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_FREQ_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
HAL_NVIC_EnableIRQ(USART1_IRQn); //使能USART1中断通道
HAL_NVIC_SetPriority(USART1_IRQn,3,3); //抢占优先级3,子优先级3
}
if(huart->Instance==USART2)//如果是串口1,进行串口1 MSP初始化
{
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
__HAL_RCC_USART2_CLK_ENABLE(); //使能USART2时钟
GPIO_Initure.Pin=GPIO_PIN_2; //PA2
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //高速
GPIO_Initure.Alternate=GPIO_AF7_USART2; //复用为USART2
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA2
GPIO_Initure.Pin=GPIO_PIN_3; //PA3
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA3
HAL_NVIC_EnableIRQ(USART2_IRQn); //使能USART2中断通道
HAL_NVIC_SetPriority(USART2_IRQn,3,3); //抢占优先级3,子优先级3
}
}
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&usart1_handler);
while (HAL_UART_GetState(&usart1_handler) != HAL_UART_STATE_READY);//等待就绪
while(HAL_UART_Receive_IT(&usart1_handler, (u8 *)rdata, 1) != HAL_OK);
}
void USART2_IRQHandler(void)
{
HAL_UART_IRQHandler(&usart2_handler);
while (HAL_UART_GetState(&usart2_handler) != HAL_UART_STATE_READY);//等待就绪
while(HAL_UART_Receive_IT(&usart2_handler, (u8 *)rdata, 1) != HAL_OK);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
u8 rec;
if(huart->Instance==USART2)//如果是串口12
{
rec=*(--(huart->pRxBuffPtr));
HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
}
}
int main(void)
{
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
delay_init(180);
uart_init();//初始化串口参数
HAL_UART_Receive_IT(&usart2_handler,rdata, 1);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
while(1);
}