基于stm32的HAL库的串口实现不定长数据收发(三)(接收中断)

串口实现不定长数据收发(接收中断)


1头文件

cpp 复制代码
#include "uart1.h"
#include "string.h"
#include "stdio.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);


//接收来的数据保存到数组里面

uint8_t uart1_rx_buf[UART1_RX_BUF_SIZE];
uint16_t uart1_rx_len = 0;//数组长度
uint16_t uart1_cnt    = 0,uart1_cntPre = 0;//会正常一些 需要判断计数器有无变化

2初始化函数

cpp 复制代码
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;//字长参数列表用的8位
        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);

}

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

cpp 复制代码
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
   判断是否为USART1
    if(huart->Instance == USART1)
    {
    //使能USART1,GPIO时钟
    __HAL_RCC_USART1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef gpio_initstruct;
    //配置TX
    gpio_initstruct.Pin  = GPIO_PIN_9;//数据手册
    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);
    
    //配置RX
    gpio_initstruct.Pin  = GPIO_PIN_10;
    gpio_initstruct.Mode = GPIO_MODE_AF_INPUT;//复用推完输入和输入模式一样

    //NVIC
    HAL_NVIC_EnableIRQ(USART1_IRQn);      //使能NVIC中断
    HAL_NVIC_SetPriority(USART1_IRQn,2,2);//设置中断优先级
    //确定RXNE被置为1 __HAL_UART_ENABLE_IT()

    __HAL_UART_ENABLE_IT(huart,UART_IT_RXNE);
    
}
}

4中断服务函数--数据收发

cpp 复制代码
void UASRT1_IRQHandler(void)
{
    uint8_t receive data = 0;
    //判断什么时候数据的收发 如何判断是否收到数据  看RXNE  RDR接收数据寄存器内不为空 就会触发一个        
    //中断就可以进行一个操作
	//判断是否为RXNE触发的中断
    if(__HAL_UART_GET_FLAG(&uart1_handle,UART_FLAG_RXNE) != RESER)//被置1不为RESET
    {
    		//需要判断数组是否接收完,防止缓冲区被刷爆
            if(uart1_cnt >= sizeof(uart1_rx_buf))
            uart1_cnt = 0;
            //进行接收
		    //接收的位置,接收的数据,接受的长度,超时时间
            HAL_UART_Receive(&uart1_handle,&receive_data,1,1,1000);
            //接收到的数据保存到数组中
            uart1_rx_buf[uart1_cnt++] = receive_data;
            
}
}

5重定向到串口1中SR ? DR? ch 将fputc 定向到printf中

cpp 复制代码
int fputc(int ch,FILE *f)??
{
    while((USART1->SR & 0x40) == 0);//一直卡住  判断是否为1
    
    USART1->DR = (uint8_t)ch;//将dr的值赋到ch中,要勾选魔术棒中的Micro
    return ch;   
}

6需要判断数组是否接收完

cpp 复制代码
uint8_t uart1_wait_receive(void)
{
    if(uart1_cnt == 0)
    return UART_ERROR;
    if(uart_cnt == uart1_cntPre)//数据接收完毕 计数器无变化
    return UART_EOK;
    
    //以上条件都不满足
    uart1_cntPre = uart1_cnt;
    return UART_ERROR;
    
}

7将BUF清空以便于下一次的接收,如果上一次的数据在里面会造成不必要的问题

cpp 复制代码
void uart1_rx_clear(void)
{
    //对接收寄存器进行清空
    memset(&uart1_rx_buf,0,sizeof(uart1_rx_buf));
    uart1_rx_len = 0;
}

8测试函数

cpp 复制代码
void uart1_receiv_test(void)
{
    //在while中一直调用该函数
	//数据接收完整就打印出来
	//重定向fputc
    if(uart1_wait_receive() == UART_EOK)
    {
    printf("recv: %s\r\n", uart1_rx_buf);
    uart1_rx_clear();    
}
}

9 main函数

cpp 复制代码
int main(void)
{
    HAL_Init();                     /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9);/* 设置时钟, 72Mhz */
    uart1_init(115200);            /* LED初始化 */
    
    while(1)
    {
    uart1_receiv_test();

    delay_ms(10)
}
}

10 运行结果

相关推荐
炸膛坦客17 小时前
单片机开发工具篇:(九)MCU 芯片包的安装
单片机·嵌入式硬件
智者知已应修善业1 天前
【51单片机实现初始化数码管不显示按启动从0秒计时到60按暂停一次显示当前秒按2次恢复原始状态】2024-6-11
c语言·c++·经验分享·笔记·嵌入式硬件·算法·51单片机
电气_空空1 天前
基于LabVIEW的数据采集系统设计与实现
单片机·嵌入式硬件·labview
caimouse1 天前
ReactOS BootCD 光盘布局完整深度分析
单片机·reactos
zlinear数据采集卡1 天前
从万用表的6步调零到硅片级微秒自校准:硬核拆解LHAMP188的宽压轨到轨与零漂移实战
arm开发·stm32·单片机·嵌入式硬件·fpga开发
三品吉他手会点灯1 天前
嵌入式机器学习 - 学习笔记1.2.3 - 机器学习软件框架
人工智能·笔记·嵌入式硬件·学习·机器学习
国科安芯1 天前
ASC8T245S 8通道电平转换设计实战:从系统架构到QFN24 Layout再到量产测试
网络·单片机·物联网·安全·fpga开发·系统架构
云栖梦泽1 天前
将RAW打包成MIPI CSI2
linux·人工智能·嵌入式硬件
伟大的前程1 天前
us级开定时器中断,单片机的开销大,改用轮询的方式
单片机·嵌入式硬件
ACP广源盛139246256732 天前
IX8024@ACP# 搭配此芯 AI 服务器 + 爱芯元智产品完整方案
大数据·运维·服务器·人工智能·分布式·嵌入式硬件