AT串口抽象层的设计思路及代码实现
文章目录
- 1 AT串口抽象层的设计思路及代码实现
- 1.1 AT串口抽象层的设计思路
- 1.2 AT串口抽象层的代码实现
1 AT串口抽象层的设计思路及代码实现
1.1 AT串口抽象层的设计思路
我们先来看下AT串口的发送模型和AT串口接收模型:
下面看一下发送流程、接收流程及中断处理流程:
1.2 AT串口抽象层的代码实现
at_uart_hal.h:
#ifndef __AT_UART_HAL_H
#define __AT_UART_HAL_H#include <stdbool.h>bool at_uart_init(void);
bool at_uart_deinit(void);
uint32_t at_uart_send(const void *pdata, uint32_t size, uint32_t timeout);
uint32_t at_uart_receive(void *pdata, uint32_t expect_size,uint32_t timeout);
void at_uart_irq_handler(void);#endif
at_uart_hal.c:
#include <stdbool.h>
#include "main.h"
#include "usart.h"
#include "app_debug.h"#include "FreeRTOS.h"
#include "stream_buffer.h"#define AT_UART huart4
#define AT_UART_SEND_BUF_SIZE 300
#define AT_UART_RECV_BUF_SIZE 300 static StreamBufferHandle_t stream_send=NULL;
static StreamBufferHandle_t stream_recv=NULL;
static bool is_inited=false;bool at_uart_deinit(void)
{DEBUG("at uart deinit");is_inited=false;__HAL_UART_DISABLE_IT(&AT_UART,UART_IT_RXNE);__HAL_UART_DISABLE_IT(&AT_UART,UART_IT_TXE);if(stream_send!=NULL){vStreamBufferDelete(stream_send);}if(stream_recv!=NULL){vStreamBufferDelete(stream_recv);}return true;
}bool at_uart_init(void)
{if(is_inited)return true;DEBUG("at uart init!");do{stream_send=xStreamBufferCreate(AT_UART_SEND_BUF_SIZE,1);if(stream_send==NULL)break;stream_recv=xStreamBufferCreate(AT_UART_RECV_BUF_SIZE,1);if(stream_recv==NULL)break;__HAL_UART_ENABLE_IT(&AT_UART,UART_IT_RXNE);is_inited=true; DEBUG("at uart init ok!"); return true;} while (0);at_uart_deinit();return false;
}uint32_t at_uart_send(const void *pdata, uint32_t size, uint32_t timeout)
{uint32_t write_len;if(is_inited==false)return 0;write_len=xStreamBufferSend(stream_send,pdata,size,timeout);__HAL_UART_ENABLE_IT(&AT_UART,UART_IT_TXE);return write_len;
}
uint32_t at_uart_receive(void *pdata, uint32_t expect_size,uint32_t timeout)
{uint32_t read_len;if(is_inited==false)return 0;read_len=xStreamBufferReceive(stream_recv,pdata,expect_size,timeout);return read_len;
}
void at_uart_irq_handler(void)
{uint8_t ch;BaseType_t xHigherPriorityTaskWoken = pdFALSE;if ((__HAL_UART_GET_IT(&AT_UART,UART_IT_TXE))&&(__HAL_UART_GET_IT_SOURCE(&AT_UART,UART_IT_TXE)!=RESET)){if(xStreamBufferReceiveFromISR(stream_send,&ch,1,&xHigherPriorityTaskWoken)==1){AT_UART.Instance->TDR=ch;}else{__HAL_UART_DISABLE_IT(&AT_UART,UART_IT_TXE); }}if ((__HAL_UART_GET_IT(&AT_UART,UART_IT_RXNE))&&(__HAL_UART_GET_IT_SOURCE(&AT_UART,UART_IT_RXNE)!=RESET)){ch=(uint8_t)(AT_UART.Instance->RDR&0xff);xStreamBufferSendFromISR(stream_recv,&ch,1,&xHigherPriorityTaskWoken);}portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
中断中需加入如下代码:
/*** @brief This function handles USART4 and USART5 interrupt.*/
void USART4_5_IRQHandler(void)
{/* USER CODE BEGIN USART4_5_IRQn 0 */extern void at_uart_irq_handler(void);at_uart_irq_handler();/* USER CODE END USART4_5_IRQn 0 *//* USER CODE BEGIN USART4_5_IRQn 1 *//* USER CODE END USART4_5_IRQn 1 */
}
测试代码如下:
/* USER CODE BEGIN Header_StartDefaultTask */
/*** @brief Function implementing the defaultTask thread.* @param argument: Not used* @retval None*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */float temp,humi;uint8_t write_buf[]="1234567890";uint8_t read_buf[20];uint16_t read_len;#define TEST_NAME 0X0001uint8_t buf[5];debug_init();led_init();key_init();led_blink(2,5);sht30_init();at_uart_init();for(;;){if(at_uart_receive(buf,1,1000)){DEBUG("-%c-",buf[0]);}//at_uart_send("12345\r\n",7,1000);// storage_write(TEST_NAME,sizeof(write_buf),write_buf);// memset(read_buf,0,20);// read_len=20;// if(storage_read(TEST_NAME,&read_len,read_buf))// {// DEBUG("------%s-----",read_buf);// }// if(sht30_get_temp_humi(&temp,&humi))// {// DEBUG("temp=%f,humi=%f",temp,humi);// }osDelay(1);}/* USER CODE END StartDefaultTask */
}
AT串口抽象层的设计思路及代码实现相关推荐
- 普歌-允异团队-【Java实例】一起做一个简单的王者荣耀RPG吧!从设计思路到代码实现一条龙!-登录与注册(IO流)/记录时间/属性面板呈现
[Java实例]-王者荣耀RPG-从设计思路到代码实现 前言 一.案例分析 1. 设计理念 2. 功能设计 (1)登录与注册 (2)游戏时间记录 (3)选择游戏模式 (4)游戏地图 (5)生物属性 二 ...
- python+unittest框架 UI自动化设计思路以及代码剖析,增加易用性
前言 学习UI自动化的同学都应该知道PO模式,PO共分为三层,分别是页面定位层,页面对象层,业务逻辑层. po模式有以下几个优点: 1.易读性好 2.扩展性高 3.复用性强 4.维护性好 5.代码冗余 ...
- ML之分类预测:机器学习中多分类预测数据集可视化(不同类别赋予不同颜色)设计思路及代码实现
ML之分类预测:机器学习中多分类预测数据集可视化(不同类别赋予不同颜色)设计思路及代码实现 目录 机器学习中多分类预测数据集可视化(不同类别赋予不同颜色)设计思路及代码实现 代码实现
- 【三子棋小游戏的设计思路以及代码实现】
目录 一,设计思路 二, 代码实现 首先,欢迎各位点进我的文章.话不多说,正如标题一样,接下来,我来给大家讲解三子棋小游戏的设计思路以及代码实现. 一,设计思路 一. 大家应该都 ...
- 教你快速高效接入SDK——SDK接入抽象层的设计
小黑终于有了自己的家:http://www.uustory.com/,欢迎来坐坐. 题记:很多做游戏开发的人,估计都或多或少地接过渠道SDK,什么UC,当乐,91,小米,360......据统计国内市 ...
- 手机号码归属地 API 实现防止骚扰电话,看这一篇就够了(内附设计思路和代码)
在当今时代,骚扰电话已经成为了很多人日常生活中的一个常见问题,严重影响了人们的工作和生活. 为了避免这种情况的发生,企业和机构可以采用手机号码归属地 API,以提供更好的电话服务,减少骚扰电话的出现. ...
- 密保问题数据库设计思路和代码实现
用户注册时设置三个密保问题方便用户找回. 数据库设计思路: 用户一张表,用户密保问题答案一张表,密保问题单独一张表.这样做的好处是满足三范式,条理清晰,跟重要的是方便后期更改维护密保问题,比如增加删除 ...
- 程控电源CANoe上位机面板(CAN\ETH测试、RS232串口通信、编写设计思路)
程控电源CANoe上位机面板 编写此面板的目的 编写思路 一.通讯方式 1.RS232串口连接 2.CANoe与RS232串口相关的函数 3.帧格式命令字 4.校验码 二.面板设计 1.所需文件说明 ...
- java表盘时钟的设计思路_java代码实现时钟
实现效果如图: Java代码: 文件一:ClockPanel.java importstaticjava.util.Calendar.HOUR;importstaticjava.util.Calend ...
最新文章
- 时间序列数据的预处理
- GDCM:转储GEMS Ultrasound MovieGroup的测试程序
- Metalink使用指南
- Windows 10配置VS Code C++环境(超详细,面向小白以及大佬们)
- VLAN访问控制列表(VACL)的配置方法
- 14--用两个栈实现队列
- idea 安装php插件_免费版的 IDEA 为啥不能使用 Tomcat ?
- Python文件练习
- arcx函数js_抖音的这个JS,怎么能运行,获取到用户的加载信息
- 处理器管理与进程调度
- 学习JSON的神级网站www.bejson.com
- 开源微服务框架 汇总
- FTP,SFTP,FTPS,TF区别
- 放量跌与缩量跌的区别是什么?
- VMware VSphere Client克隆虚拟机
- python函数装饰器一篇入魂
- 【转】 机器学习入门——浅谈神经网络
- VSCode图片预览插件 Image preview
- 2019,2021非科班生的Android面试之路
- [other]毕业一年同学聚会
热门文章
- 虚拟化四路服务器,专为虚拟化设计 戴尔R905四路服务器评测
- 一阶系统单位阶跃响应的特点_第八讲 系统的时域响应
- 【控制】《多智能体机器人系统信息融合与协调》范波老师-第4章-基于证据推理的多 Agent 分布式决策
- 2.3 Logistic 回归损失函数-深度学习-Stanford吴恩达教授
- 一起学nRF51xx 12 - flash
- STM32 基础系列教程 19 – WWDG
- Ubuntu apt-get 源详解
- 每天学习python 30分钟 -了解python - 看懂#!/usr/bin/python
- 关于U盘安装ubuntu-18.04安装时候出现的grub-efi-amd64-signed的问题。
- 函数防抖Debounce和函数节流Throttle