基于STM32HAL库的串口通讯实验(二)串口实现不定长数据收发 (接收中断)

目录

实验:通过串口一使用接收中断实现不定长数据收发

1.头文件内容如下

2.对串口进行初始化

3.在msp函数中对外设gpio口和nvic进行初始化

4.在中断服务函数里面进行数据收发

5.重新定向到串口1中的SR DR 

6.判断数据是否收发完成

7.在每次接收数据时,先将数组里的内容清空,避免出现问题

8.测试函数  如果数据接收完整了就打印出来内容

9.在main函数中实现


实验:通过串口一使用接收中断实现不定长数据收发

1.头文件内容如下

#ifndef __USART_H__
#define __USART_H__

#include "sys.h"

#define UART1_RX_BUF_SIZE  128
#define UART1_TX_BUF_SIZE  64

#define UART_EOK        0
#define UART_ERROR      1
#define UART_ETIMEOUT   2
#define UART_EINVAL     3

void uart1_init(uint32_t baudrate);
void uart1_receiv_test(void);

#endif

在头文件中,我定义了接收数组的长度和发送数组的长度,同时我也定义了一些调试信息

2.对串口进行初始化

uint8_t uart1_rx_buf[UART1_RX_BUF_SIZE];
uint16_t uart1_rx_len = 0;
uint16_t uart1_cnt = 0, uart1_cntPre = 0;


UART_HandleTypeDef uart1_handle = {0};
void uart1_init(uint32_t baudrate)
{
    uart1_handle.Instance = USART1;
    uart1_handle.Init.BaudRate = baudrate;
    uart1_handle.Init.WordLength = UART_WORDLENGTH_8B;
    uart1_handle.Init.StopBits = UART_STOPBITS_1;
    uart1_handle.Init.Parity = UART_PARITY_NONE;
    uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    uart1_handle.Init.Mode = UART_MODE_TX_RX;
    HAL_UART_Init(&uart1_handle);
}

跟上一篇文章里面的初始化内容一样,这里不过多赘述

3.在msp函数中对外设gpio口和nvic进行初始化

msp公用的一个函数这里有三个串口,都会调用msp,所以先进行一个判断

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        __HAL_RCC_USART1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE(); 
        GPIO_InitTypeDef gpio_initstruct;
        
        //调用GPIO初始化函数
        gpio_initstruct.Pin = GPIO_PIN_9;          // 两个LED对应的引脚
        gpio_initstruct.Mode = GPIO_MODE_AF_PP;             // 推挽输出
        gpio_initstruct.Pull = GPIO_PULLUP;                     // 上拉
        gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;           // 高速
        HAL_GPIO_Init(GPIOA, &gpio_initstruct);
        
        gpio_initstruct.Pin = GPIO_PIN_10;          // 两个LED对应的引脚
        gpio_initstruct.Mode = GPIO_MODE_AF_INPUT;             // 推挽输出
        HAL_GPIO_Init(GPIOA, &gpio_initstruct);
        
        HAL_NVIC_EnableIRQ(USART1_IRQn);
        HAL_NVIC_SetPriority(USART1_IRQn, 2, 2);
        
        __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
    }
}

内容与之前的一样,也不过多赘述

4.在中断服务函数里面进行数据收发

void USART1_IRQHandler(void)
{
    uint8_t receive_data = 0;
    if(__HAL_UART_GET_FLAG(&uart1_handle, UART_FLAG_RXNE) != RESET)
    {
        //需要判断数组是否接收完,防止缓冲区被刷爆
        if(uart1_cnt >= sizeof(uart1_rx_buf))
            uart1_cnt = 0;
        HAL_UART_Receive(&uart1_handle, &receive_data, 1, 1000);
        uart1_rx_buf[uart1_cnt++] = receive_data;
    }
}

5.重新定向到串口1中的SR DR 

int fputc(int ch, FILE *f)
{
    while((USART1->SR & 0X40) == 0);
        
    USART1->DR = (uint8_t)ch;
    return ch;
}

6.判断数据是否收发完成

uint8_t uart1_wait_receive(void)
{
    if(uart1_cnt == 0)
        return UART_ERROR;
    
    if(uart1_cnt == uart1_cntPre)
    {
        uart1_cnt = 0;
        return UART_EOK;
    }
    
    uart1_cntPre = uart1_cnt;
    return UART_ERROR;
}

7.在每次接收数据时,先将数组里的内容清空,避免出现问题

void uart1_rx_clear(void)
{
    memset(uart1_rx_buf, 0, sizeof(uart1_rx_buf));
    uart1_rx_len = 0;
}

8.测试函数  如果数据接收完整了就打印出来内容

void uart1_receiv_test(void)
{
    if(uart1_wait_receive() == UART_EOK)
    {
        printf("recv: %s\r\n", uart1_rx_buf);
        uart1_rx_clear();
    }
}

9.在main函数中实现

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"

int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
    led_init();                         /* 初始化LED灯 */
    uart1_init(115200);
		
    while(1)
    { 
        uart1_receiv_test();
        delay_ms(10);
    }
}

10.运行后是这个样子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江桥吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值