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

江科大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函数)

相关文章:

  • Python reduce()函数详解:累积计算的艺术
  • 王树森推荐系统公开课 特征交叉01:Factorized Machine (FM) 因式分解机
  • N2语法 逆接
  • C++ 中 std::wstring::c_str() 的潜在风险与安全使用指南
  • Java类中各部分内容的加载执行顺序
  • 【Python Cookbook】迭代器与生成器(四)
  • 【运维实战】定时任务-crontab命令
  • 什么是外键?它的作用与性能影响?
  • 四叉树实现四边形网格
  • MATLAB中的table数据类型:高效数据管理的利器
  • vr中风--模型部署
  • 短视频一键搬运 v1.7.1|短视频无水印下载 一键去重
  • lost connection to mysql server at ‘reading initial communication packet‘
  • 在力扣刷题中触摸算法的温度
  • Java的Object类
  • DeepSeek R1-0528 新开源推理模型(免费且快速)
  • ADC同步采样
  • vue3项目 前端文件下载的两种工具函数
  • OpenCv高阶(二十)——dlib脸部轮廓绘制
  • 大预言模型提示词技巧:释放AI潜力的关键
  • 专注合肥网站建设/专业seo站长工具全面查询网站
  • 网站 免费 托管运营/提升神马seo关键词自然排名
  • 西安优秀的集团门户网站建设/免费seo视频教学
  • 高端网络工作室名字/站群seo技巧
  • 做网站的哪家公司好/我有广告位怎么找客户
  • 如何做企业网站php/百度官网网站首页