当前位置: 首页 > backend >正文

江科大UART串口通讯hal库实现

hal库相关库函数

初始化结构体

typedef struct
{uint32_t BaudRate;                  /*波特率设置*/uint32_t WordLength;                /*字长设置*/uint32_t StopBits;                  /*停止位设置 */uint32_t Parity;                    /*奇偶校验位设置*/uint32_t Mode;                      /*接受发送模式设置*/uint32_t HwFlowCtl;                 /*硬件流控制设置*/uint32_t OverSampling;              /*采样速度设置*/
} UART_InitTypeDef;
typedef struct __UART_HandleTypeDef
{USART_TypeDef                 *Instance;        /*选择的串口外设地址*/UART_InitTypeDef              Init;             /*串口初始化*/const uint8_t                 *pTxBuffPtr;      /*发送数据的缓冲区*/uint16_t                      TxXferSize;       /*发送数据大小*/__IO uint16_t                 TxXferCount;      /*用于记录还剩余的要发送的数据量*/uint8_t                       *pRxBuffPtr;      /*接收数据缓冲区*/uint16_t                      RxXferSize;       /*接收数据大小*/__IO uint16_t                 RxXferCount;      /*用于记录还剩余的要接收的数据量*/__IO HAL_UART_RxTypeTypeDef ReceptionType;      /*标识当前 UART 接收模式的成员变量。它决定了 UART 如何处理接收到的数据,比如说中断处理或者DMA处理*/__IO HAL_UART_RxEventTypeTypeDef RxEventType;   /*接收事件类型*/DMA_HandleTypeDef             *hdmatx;          /*发送功能DMA句柄*/DMA_HandleTypeDef             *hdmarx;          /*接受功能DMA句柄*/HAL_LockTypeDef               Lock;             /*状态锁存*/__IO HAL_UART_StateTypeDef    gState;           /*它的主要作用是存储当前 UART 的状态,方便在程序的不同部分查询 UART 的工作状态global state */__IO HAL_UART_StateTypeDef    RxState;          /*接收状态*/__IO uint32_t                 ErrorCode;        /*错误标志位*/#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart);        /*!< UART Tx Half Complete Callback        */void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Tx Complete Callback             */void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart);        /*!< UART Rx Half Complete Callback        */void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Rx Complete Callback             */void (* ErrorCallback)(struct __UART_HandleTypeDef *huart);             /*!< UART Error Callback                   */void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart);         /*!< UART Abort Complete Callback          */void (* AbortTransmitCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Transmit Complete Callback */void (* AbortReceiveCpltCallback)(struct __UART_HandleTypeDef *huart);  /*!< UART Abort Receive Complete Callback  */void (* WakeupCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Wakeup Callback                  */void (* RxEventCallback)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< UART Reception Event Callback     */void (* MspInitCallback)(struct __UART_HandleTypeDef *huart);           /*!< UART Msp Init callback                */void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart);         /*!< UART Msp DeInit callback              */
#endif  /* USE_HAL_UART_REGISTER_CALLBACKS */} UART_HandleTypeDef;

 FE帧错误,ORE过载错误,NE噪声错误

初始化相关函数

初始化,半双工,初始化 LIN 外设,多进程,恢复缺省配置

HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength);
HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod);
HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart);
void HAL_UART_MspInit(UART_HandleTypeDef *huart);
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart);

发送接收相关函数 ,普通收发,中断收发,DMA收发,以及DMA暂停,DMA恢复,DMA停止

其中DMAResume得在DMAPause后面.

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
扩展部分
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,uint32_t Timeout);
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

 扩展部分是串口不断接收数据,直到空闲状态,有三种不同的接受方式

串口接收的事件获取

串口中止 UART 通信的函数,它可以同时中止发送和接收操作。

串口中止发送,中止接收,中止中断,中止发送中断,中止接受中断。

HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart);

串口的收发

根据江科大的串口设计来配置我们的CubeMX

首先使用UART1,波特率为9600,非硬件流控制,发送接收模式都要,一位停止位,八位字长,不需要奇偶校验位,开启中断,抢占优先级和响应优先级都为1,

创建完成后我们就可以完成串口的收发了,我们使用正点原子的串口调试工具

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

 这两个代码在while循环里面轮询收发数据,比如接收发送3位数据abc,你会发现少接收了一位a只接收到bc且发送的也是bc,数组里面a的位置我们显示出来是0D,也就是回车键的ascll码值。

这是什么原因呢?

原因在这里,他加入了回车换行导致我们的代码a变成了回车

所以对于串口工具的了解也是有必要的。

但是这是阻塞式的收发,超时时间都是1s,也就是我不发生数据,就会在接受数据函数这里卡住整整1s的时间,这对于我们的单片机程序是致命的,1s可以让他做非常多的事情了。所以我们通常使用中断收发模式。

HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

只有触发中断,才进行一次数据的接受和发送,这样就能大大的减少我们在串口收发里面花费的时间,且主程序还能正常运行,不被干扰。

我们在while循环前面进行中断的接收打开,当串口助手发送数据的时候,触发接收中断,接收到数据并进入接收中断函数里面,如果还要继续接收别的数据,我们就得在接受中断函数里面再次开启接受中断。对于接受和发送,我们得对他们进行分离处理,让他们各司其职,比如说最好不要在接收中断函数里面进行数据发送,数据发送不出来且可能和接收函数有冲突导致二者都不能正常工作。

__HAL_UART_GET_FLAG()

我们可以通过get_flag宏定义来判断中断标志位,也可以和江科的代码大一样实现串口的收发,但是那个收发函数太麻烦了,还需要我们手动判断标志位,清除标志位,发送函数也是由一位字长数据发送函数嵌套得到的字符串发送函数。而hal库直接给我们提供好了这么多便捷的串口收发函数,比如轮询式最普通的收发函数,还给我们添加了超时保护,所以我觉得在hal库这里对于江科大的串口收发函数的复现是意义不大的。

uint8_t zfc[20];//收发数组
int main(void)
{OLED_Init();//初始化OLED显示屏HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();OLED_ShowString(1, 1, "RxData:");HAL_UART_Receive_IT(&huart1,zfc,3);//开启中断接受while (1){OLED_ShowHexNum(1,8,zfc[0],2);//显示接收到的值OLED_ShowHexNum(1,11,zfc[1],2);OLED_ShowHexNum(1,14,zfc[2],2);HAL_UART_Transmit(&huart1,zfc,3,1000);//发送接收到的值HAL_Delay(1000);//延时1s,不然会眼花缭乱的}
}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){if(huart == &huart1){
//        OLED_ShowString(2,1,"success");//测试中断是否成功接收HAL_UART_Receive_IT(&huart1,zfc,3);//重新启动中断接受}
}

CubeMx创建的文件注释部分太多了,我把注释部分删掉了,这样所有先关代码就能全部显示在一个界面上了。

我这里是固定长度的收发,如果要实现字符串收发,也可以用字符串相关函数,把固定长度修改成字符串的长度即可(应该是str_len函数)

http://www.xdnf.cn/news/9982.html

相关文章:

  • 【大模型/MCP】MCP简介
  • 哈希之旅:从使用到底层建设
  • CCPC shandong 2025 G
  • 【数据集】中国日尺度1 km全天候地表温度数据集(2000-2022)
  • 尚硅谷redis7 74-85 redis集群分片之集群是什么
  • 【区间dp】-----例题5【田忌赛马】(暂时只会贪心解法)
  • Chuanpai、Nihongo wa Muzukashii Desu、K-skip Permutation
  • 3340. 检查平衡字符串
  • 【2025文博会现场直击】多图预警
  • One Year~
  • WES(三)——变异检测
  • Pix4d航测软件正射影像生产流程(一)项目创建及快速空三
  • Baklib企业知识激活解决方案
  • MySQL 数据库中的主键、超键、候选键、外键是什么?
  • vue3 driverjs
  • 车载摄像头选型相关
  • 初识JAVA:Java异常种类
  • Blaster - Multiplayer P117-PXXX: 匹配状态
  • 项目使用富文本编辑器发送邮件,邮箱无法预览
  • Parasoft C++Test软件单元测试_常见问题及处理
  • MySQL 8.0中的mysql.ibd文件
  • 深度学习目标检测实战——YOLOv8从入门到部署
  • linux 1.0.3
  • 【android bluetooth 协议分析 02】【bluetooth hal 层详解 6】【bt_vendor_opcode_t 介绍】
  • oracle 导入导出 dmp 数据文件实战
  • 树型表查询方法 —— SQL递归
  • RockyLinux9安装Docker
  • 进阶智能体实战八、需求分析助手(基于qwen多模态大模型对图文需求文档分析)(帮你生成 模块划分+页面+表设计、状态机、工作流、ER模型)
  • 摄像头模块的镜头类型
  • Git 全平台安装指南:从 Linux 到 Windows 的详细教程