ARM32开发——串口库封装(初级)

🎬 秋野酱:《个人主页》
🔥 个人专栏:《Java专栏》《Python专栏》

⛺️心若有所向往,何惧道阻且长

文章目录

    • 开发流程
      • 分组创建
    • 接口定义
    • 完整代码

开发流程

  1. 在文件系统中,创建库目录Library
  2. 在keil工程中,创建分组管理库Library
  3. 编写中间件逻辑
  4. 使用中间件
    文件目录创建
    在工程根目录,创建Library目录,在这个目录中,创建具体的功能目录,当前是做串口功能,我们新建usart。
    在这里插入图片描述

分组创建

  1. 创建Library分组。右键进入Manage Project Items
    在这里插入图片描述
    右键创建头文件和c文件
    在这里插入图片描述
    添加include引入
    在这里插入图片描述

接口定义

初始化及发送功能定义

void USART0_init(void);// 发送1个byte数据
void USART0_send_byte(uint8_t byte);// 发送多个byte数据
void USART0_send_data(uint8_t* data, uint32_t len);// 发送字符串 (结尾标记\0)
void USART0_send_string(char *data);

接收回调定义

// 功能开关配置
#define USART0_RECV_CALLBACK    1#if USART0_RECV_CALLBACK
// 收到串口0数据,回调函数
extern void USART0_on_recv(uint8_t* data, uint32_t len);
#endif
...
#if USART0_RECV_CALLBACKUSART0_on_recv(g_rx_buffer, g_rx_cnt);
#endif
...

● 通过宏定义做开关
系统printf打印定义

#define USART0_PRINTF				 1#if	USART0_PRINTF
#include <stdio.h>
#endif
#if USART0_PRINTF
// 配置printf打印函数
int fputc(int ch, FILE *f) {USART0_send_byte(ch);return ch;
}
#endif

完整代码

#ifndef __USART0_H__
#define __USART0_H__#include "gd32f4xx.h"// 功能开关配置
#define USART0_RECV_CALLBACK    1
#define USART0_PRINTF           1#if	USART0_PRINTF
#include <stdio.h>
#endifvoid USART0_init(void);// 发送1个byte数据
void USART0_send_byte(uint8_t byte);// 发送多个byte数据
void USART0_send_data(uint8_t* data, uint32_t len);// 发送字符串 (结尾标记\0)
void USART0_send_string(char *data);#if USART0_RECV_CALLBACK
// 收到串口0数据,回调函数
extern void USART0_on_recv(uint8_t* data, uint32_t len);
#endif#endif
#include "USART0.h"
#include <stdio.h>void USART0_init(void) {// GPIO 初始化 ----------------------------------------------------// 启用GPIO时钟rcu_periph_clock_enable(RCU_GPIOA);/* 配置TX PA9和RX PA10引脚 */gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);/* configure the USART0 TX pin and USART0 RX pin */gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);// 串口 初始化 ----------------------------------------------------// 启用USART0时钟rcu_periph_clock_enable(RCU_USART0);// 重置(可选)usart_deinit(USART0);// 配置串口参数:波特率*, 数据位,校验位,停止位, 大小端模式usart_baudrate_set(USART0, 115200UL);         // 波特率:必填usart_word_length_set(USART0, USART_WL_8BIT); // 数据位:默认8bitusart_parity_config(USART0, USART_PM_NONE);   // 校验位:默认无校验usart_stop_bit_set(USART0, USART_STB_1BIT);   // 停止位:默认1bitusart_data_first_config(USART0, USART_MSBF_LSB);// 大小端模式:默认小端// 启用发送功能usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);// 启用接收功能usart_receive_config(USART0, USART_RECEIVE_ENABLE);// 开启接收中断nvic_irq_enable(USART0_IRQn, 2, 2);// 启用RBNE中断,读数据缓冲区不为空中断usart_interrupt_enable(USART0, USART_INT_RBNE);// 启用IDLE中断,空闲中断usart_interrupt_enable(USART0, USART_INT_IDLE);// 启用USARTusart_enable(USART0);
}// 发送1个byte数据
void USART0_send_byte(uint8_t byte){// 从USART0的TX发送一个字节出去usart_data_transmit(USART0, (uint8_t)byte);// 等待发送完成 (轮询等待发送数据缓冲区为空)while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
}// 发送多个byte数据
void USART0_send_data(uint8_t* data, uint32_t len){// 满足:1.data指针不为空 2.长度不为0while(data && len--){USART0_send_byte(*data);data++;}
}// 发送字符串 (结尾标记\0)
void USART0_send_string(char *data){// 满足:1.data指针不为空 2. 数据不能是\0while(data && *data){USART0_send_byte((uint8_t)*data);data++;}
}#if USART0_PRINTF
// 配置printf打印函数
int fputc(int ch, FILE *f) {USART0_send_byte(ch);return ch;
}
#endif/************************************
中断函数:收到标记信号,马上执行
1. 触发中断函数的原因(标记)有很多
2. 需要区分是哪个标记触发的中断
RBNE: read data buffer not empty中断函数名不能随便写,要根据中断向量表复制
*************************************/#define   RX_BUFFER_LEN   1024
uint8_t   g_rx_buffer[RX_BUFFER_LEN];
uint32_t  g_rx_cnt = 0;void USART0_IRQHandler(void){if(SET == usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)){// 收到数据
//    printf(">RBNE<\n");// 清理标记(避免多次触发中断)usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE);// 获取寄存器里的数据uint8_t data = usart_data_receive(USART0);// 缓存到buffer中g_rx_buffer[g_rx_cnt++] = data;// 避免缓冲区溢出 (可选)if(g_rx_cnt >= RX_BUFFER_LEN) g_rx_cnt = 0;// 原样返回 send_byte(data);}if(SET == usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)){
//    printf(">IDLE<\n"); // 空闲// 清理标记(无效) usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE);// 只能使用以下方式清理IDLE标记usart_data_receive(USART0); // 必须读取一次USART0,读到的结果没有用// 添加字符串结束标记,避免打印出错g_rx_buffer[g_rx_cnt] = '\0';#if USART0_RECV_CALLBACK
//    printf("%s", g_rx_buffer);USART0_on_recv(g_rx_buffer, g_rx_cnt);
#endif// 把缓冲区[0, g_rx_cnt)设置为0x00 (可选)
//    memset(g_rx_buffer, 0x00, g_rx_cnt);// 重置缓冲区数据个数g_rx_cnt = 0;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847930.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3-组件通信详解

文章目录 组件通信的含义Vue3组件通信和Vue2的区别组件通信的具体实现props&#xff08;父子组件通信&#xff09;自定义事件&#xff08;子传父&#xff09;mitt&#xff08;任意组件间通信&#xff09;v-model$attrs &#xff08;非props的父子组件通信&#xff09; r e f s …

知识图谱应用---智慧金融

文章目录 智慧金融典型应用 智慧金融 智慧金融作为一个有机整体&#xff0c;知识图谱提供了金融领域知识提取、融合、分析、推断、决策等功能&#xff0c;如下图所示。在场景方面&#xff0c;智慧金融涵盖智慧支付、智慧财富管理、智慧银行、智慧证券、智慧保险、智慧风控等诸多…

智能分析设备助力废固运输车辆信息采集

进出车辆信息采集&#xff0c;这一环节可谓是整个废固生产及处理企业监管体系中的基石。前端摄像机以其敏锐的感知能力&#xff0c;精准捕捉废固运输车辆的车牌、车头、车尾以及车厢的细致画面&#xff0c;同时记录下对应的视频流信息。这些信息的采集不仅为后续的监管提供了详…

Git存储库的推送保护

Git存储库的推送保护 昨天有一个提交一直提示&#xff1a;Push rejected Push rejected Push master to origin/master was rejected by remote起初在网络上找各种解决办法&#xff0c;先列举以下找到的各类方法 提交用户的用户名和邮箱与Git不一致&#xff0c;这个只需要通…

Warning:成交前,永远相信意外即将发生

作为一名首次次创业者&#xff0c;随着创业进入深层次阶段&#xff0c;越来越感觉到&#xff1a;创业是一条不归路&#xff0c;因为路上不止有惊喜&#xff0c;还有风尘。创业之前我认为世界是“天圆地方”的&#xff0c; 创业后你猜我怎么看这个世界的&#xff1f; 创业前我一…

项目-基于LangChain的ChatPDF系统

问答系统需求文档 一、项目概述 本项目旨在开发一个能够上传 PDF 文件&#xff0c;并基于 PDF 内容进行问答互动的系统。用户可以上传 PDF 文件&#xff0c;系统将解析 PDF 内容&#xff0c;并允许用户通过对话框进行问答互动&#xff0c;获取有关 PDF 文件内容的信息。 二、…

excel 插入图片不变形的方法

在单元格内插入形状&#xff0c; 设置图片格式 设置图片的高宽

【Linux进程篇】Linux中的等待机制与替换策略

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 目录 ​编辑 进程等待 进程等待必要性 进程等待的方法 wait方法 waitpid方法 获取子进程status 阻塞与非阻塞 进程程序替换 替换原理 替换函数 进程等待 进程等待必要性 之前讲过&#xff0c;子进程退出&am…

傲医医疗集成引擎 Rhapsody 在超融合信创平台表现如何?

作者&#xff1a;SmartX 商业团队 黄玉辉 随着越来越多的医疗用户基于超融合基础设施实现 IT 基础架构信创转型&#xff0c;超融合信创架构在医疗业务场景中的实际表现也得到更多关注。尤其是集成平台业务场景——作为三甲医院互联互通评级中不可缺少的核心业务系统&#xff0…

“云环境下的等保测评新趋势:混合云安全策略与合规性考量“

在云环境尤其是混合云场景下&#xff0c;等保测评&#xff08;信息安全等级保护测评&#xff09;的新趋势聚焦于更加灵活、高效且全面的安全策略&#xff0c;以及确保合规性。以下是几个关键点&#xff1a; 混合云安全策略的新趋势&#xff1a; 1. 统一安全管理&#xff1a;由…

概率分布、回归分析、假设检验……用 DolphinDB 函数库快速实现概率统计分析

在金融和物联网等领域&#xff0c;概率统计与分析扮演着至关重要的角色。DolphinDB 作为一款强大的时序数据库&#xff0c;提供了一系列内置的概率统计与分析函数&#xff0c;能够满足用户的各种需求。 金融领域 风险管理&#xff1a;通过概率统计分析&#xff0c;金融机构可…

【主题广泛|投稿优惠】2024年交通运输与信息科学国际会议(ICTIS 2024)

2024年交通运输与信息科学国际会议&#xff08;ICTIS 2024&#xff09; 2024 International Conference on Transportation and Information Science 【重要信息】 大会地点&#xff1a;青岛 大会官网&#xff1a;http://www.icictis.com 投稿邮箱&#xff1a;icictissub-conf.…

【Vue】成绩案例

文章目录 一、功能描述二、思路分析三、完整代码 一、功能描述 1.渲染功能 2.删除功能 3.添加功能 4.统计总分&#xff0c;求平均分 二、思路分析 渲染功能 v-for :key v-bind:动态绑定class的样式&#xff08;来回切换&#xff09; 删除功能 v-on绑定事件&#xff0c; 阻止…

线性代数|机器学习-P2 A的列向量空间

文章目录 1. Ax矩阵的形式2. ACR 矩阵分解2.1 rank1 矩阵分解2.2 rank2 矩阵分解2.3 ACMR,求M 3. Ax 向量 1. Ax矩阵的形式 假设我们有如下矩阵A&#xff1a; A x [ 2 1 3 3 1 4 5 7 12 ] [ x 1 x 2 x 3 ] \begin{equation} Ax\begin{bmatrix} 2&1&3\\\\ 3&1&am…

【微信小程序开发】小程序中的上滑加载更多,下拉刷新是如何实现的?

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

期望20K,2年golang深圳某互联网小公司一面

后续约了二面&#xff08;CTO面&#xff09;&#xff0c;需要到现场&#xff0c;基本没问啥具体的技术知识&#xff0c;都是聊规划和个人职业目标 一面 1、假设访问百度网站&#xff0c;从在浏览器输入网址&#xff0c;到最终页面展示出来&#xff0c;中间会发生哪些事情&…

使用Python和wxPython将PNG文件转换为JPEG文件

简介&#xff1a; 在图像处理中&#xff0c;有时候我们需要将PNG格式的图像文件转换为JPEG格式。本篇博客将介绍如何使用Python编程语言和wxPython图形用户界面库&#xff0c;以及Pillow图像处理库来实现这一转换过程。通过本文的指导&#xff0c;您将学习如何快速将指定文件夹…

30分钟快速上手scapy

在前两篇博客中&#xff0c;笔者简单分享了如何使用scapy进行网络流量的分析&#xff0c;但比较粗略&#xff0c;没有详细说明&#xff0c;本文我们就0开始&#xff0c;一起快速学习一下scapy 框架的使用。 另附之前的两篇博客&#xff0c;有需要快速参考代码的请自取&#xf…

外贸如何找国外客户?

外贸客户开发国外客户可以使用多种软件来完成&#xff0c;以下是一些常用的软件推荐&#xff1a; 即时通讯软件&#xff1a; SKYPE&#xff1a;一款功能丰富的即时通讯软件&#xff0c;支持视频聊天、多人语音会议、文件传输等&#xff0c;方便与海外客户进行实时沟通。Line&a…

用增之Firebase

目录 简介 开发准备&#xff1a; 1、在Firebase平台创建项目 2、将项目关联到应用 3、项目配置 简介 前面讲了google ddl部分&#xff0c;本篇为Firebase的事件上报部分&#xff0c;包括在FireBase平台创建应用 &#xff0c; 如果有用到ddl…