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

【极光 Orbit·STC8x】05. GPIO库函数驱动LED流动

【极光 Orbit·STC8】05. GPIO库函数驱动LED流动


七律 · 逐光流转

八灯列阵若星河,状态为舟渡长波。
寄存器中藏玄机,Switch语句定山河。
循环往复如潮涌,步骤变量掌沉浮。
单片机前展锋芒,代码织就光之舞。


摘要

本文基于STC8H8K64U4单片机,通过整合GPIO库函数实现跑马灯功能。教程详细讲解如何使用库函数替代直接寄存器操作,涵盖端口模式配置、驱动层优化及代码重构。通过模块化设计与库函数封装,提升代码可读性与复用性,为复杂项目开发奠定基础。

与 switch 相关的编程技巧请参考:
https://blog.csdn.net/weixin_46419409/article/details/146279134?spm=1001.2014.3001.5502
https://blog.csdn.net/weixin_46419409/article/details/146288291?spm=1001.2014.3001.5502
https://blog.csdn.net/weixin_46419409/article/details/146288301?spm=1001.2014.3001.5502

https://blog.csdn.net/weixin_46419409/article/details/146288312?spm=1001.2014.3001.5502


关键字

STC8H8K64U4, GPIO库函数, 推挽输出, 模块化设计


引言

STC官方提供的GPIO库函数通过宏定义封装了寄存器操作,简化了端口配置流程。本教程通过以下改进实现功能:

  1. 库函数替代寄存器操作:使用GPIO_Init宏配置端口模式。
  2. 模块化架构:BSP层负责硬件抽象,驱动层实现状态机逻辑。
  3. Switch状态机:通过步骤变量run_step控制LED流动方向与速度。
  4. 代码复用性:驱动层可扩展为多模式控制(如正反向流动、变速模式)。
  5. 代码解耦:BSP层仅依赖库函数,无需直接操作硬件寄存器。
  6. 扩展性增强:支持快速切换GPIO模式(如开漏、上拉等)。

硬件设计

1. 硬件连接

LED通过灌电流方式连接至P1口:

STC8H8K64U4
P1.0-P1.7
220Ω电阻
LED阴极
GND
VCC
LED阳极

软件配置

1. 模块化架构设计

主函数
驱动层
状态机实现
BSP层
端口初始化
寄存器配置

2. 文件结构

STC8_Project
MDK-C51
Projects
Output
BSP
Drivers
Module
Core
STC8_Libraries
main.c
User

3. GPIO库函数集成

库文件位置
Drivers/STC8_Libraries/  
├── STC8Ax_GPIO.c  
└── STC8Ax_GPIO.h  
关键宏定义
宏定义作用描述
GPIO_Init配置GPIO端口模式
GPIO_MODE_OUT_PP推挽输出模式
GPIO_P1表示P1端口
Pin_All表示端口所有引脚

代码实现

1. BSP层:硬件抽象(bsp_led.c/bsp_led.h

bsp_led.h
#ifndef __BSP_LED_H  
#define __BSP_LED_H  #include "STC8Ax_GPIO.h"  void bsp_led_init(void);  
void bsp_set_led(uint8_t led_mask);  #endif  
bsp_led.c
#include "bsp_led.h"  void bsp_led_init(void) {  // 1. 使用库函数配置P1口为推挽输出模式  GPIO_Init(GPIO_P1, Pin_All, GPIO_MODE_OUT_PP);  // 2. 初始化所有LED为熄灭状态  P1 = 0x00;  
}  void bsp_set_led(uint8_t led_mask) {  P1 = led_mask; // 直接设置P1口电平  
}  

2. 驱动层:状态机实现(drv_run.c/drv_run.h

drv_run.c
#include "drv_run.h"  #define LED_NUM 8  
#define LED_ON_TIME 10000 // 循环计数阈值(假设主循环周期为1ms)  static uint8_t run_step = 0;  
static uint32_t led_cnt = 0;  void drv_run_init(void) {  run_step = 0;  led_cnt = 0;  
}  void drv_run_update(void) {  switch(run_step) {  case 0: // LED1亮  led_cnt++;  if(led_cnt > LED_ON_TIME) {  led_cnt = 0;  bsp_set_led(0x01); // 点亮P1.0  run_step = 1;  }  break;  case 1: // LED2亮  led_cnt++;  if(led_cnt > LED_ON_TIME) {  led_cnt = 0;  bsp_set_led(0x02); // 点亮P1.1  run_step = 2;  }  break;  // ...(省略中间case,同理至case7)  case 7: // LED8亮  led_cnt++;  if(led_cnt > LED_ON_TIME) {  led_cnt = 0;  bsp_set_led(0x80); // 点亮P1.7  run_step = 0; // 循环复位  }  break;  }  
}  

3. 主函数(main.c

#include "bsp_led.h"  
#include "drv_run.h"  void main(void) {  bsp_led_init(); // 初始化LED端口  drv_run_init(); // 初始化状态机  while(1) {  drv_run_update(); // 执行状态机逻辑  }  
}  

流程图与状态转换

1. 系统初始化流程

graph TD  A[系统启动] --> B[调用bsp_led_init()配置端口]  B --> C[调用drv_run_init()初始化状态变量]  C --> D[进入主循环]  

2. 状态迁移流程

graph LR  A[状态0(LED1亮)] --> B[状态1(LED2亮)]  B --> C[状态2(LED3亮)]  C --> D[状态3(LED4亮)]  D --> E[状态4(LED5亮)]  E --> F[状态5(LED6亮)]  F --> G[状态6(LED7亮)]  G --> H[状态7(LED8亮)]  H --> A[状态0循环]  

测试验证

1. 硬件连接

  • 电路要求
    • 8个LED的阳极通过220Ω电阻连接至VCC。
    • 阴极分别连接至P1.0~P1.7引脚。

2. 预期结果

  • LED依次从P1.0到P1.7逐个点亮,形成流动效果。
  • 每个LED亮灯时长为LED_ON_TIME * 主循环周期(默认1秒)。

文件结构与工程配置

1. 目录结构

STC8_Project/  
├── Projects/  
│   ├── MDK-C51/  
│   │   ├── STC8_LED2.uvproj  
│   │   └── Output/STC8_LED2.hex  
├── Drivers/  
│   ├── BSP/  
│   │   ├── bsp_led.c  
│   │   └── bsp_led.h  
│   ├── Module/  
│   │   ├── drv_run.c  
│   │   └── drv_run.h  
│   ├── Core/  
│   │   └── stc8h8k64u4.h  
│   └── STC8_Libraries/  
│       ├── STC8Ax_GPIO.c  
│       └── STC8Ax_GPIO.h  
└── User/  ├── main.c  └── startup_stc8h.asm  

2. Keil配置

  • 分组设置
    • Core:添加Drivers/Core/stc8h8k64u4.h
    • BSP:添加Drivers/BSP/bsp_led.c
    • Module:添加Drivers/Module/drv_run.c
    • STC8_Libraries:添加Drivers/STC8_Libraries/STC8Ax_GPIO.c
    • Include Paths
      Drivers/BSP  
      Drivers/Module  
      Drivers/Core/Inc  
      Drivers/STC8_Libraries  
      User  
      

扩展应用

  1. 模式切换:通过修改GPIO_Initmode参数,可快速切换为开漏输出(GPIO_MODE_OUT_OD)。
  2. 上拉控制:使用GPIO_PULLUP_ENABLE宏启用GPIO上拉电阻。
  3. 驱动强度:通过GPIO_DRIVE_HIGH宏设置高驱动强度。

结论

本教程通过整合GPIO库函数,实现了更简洁、可维护的跑马灯代码。库函数封装了底层寄存器操作,降低了开发复杂度,同时保持了代码的模块化与扩展性。开发者可基于此范式快速构建复杂GPIO控制场景,提升开发效率。

相关文章:

【极光 Orbit·STC8x】05. GPIO库函数驱动LED流动

【极光 OrbitSTC8】05. GPIO库函数驱动LED流动 七律 逐光流转 八灯列阵若星河,状态为舟渡长波。 寄存器中藏玄机,Switch语句定山河。 循环往复如潮涌,步骤变量掌沉浮。 单片机前展锋芒,代码织就光之舞。 摘要 本文基于STC8H8K6…...

DeepSeek进阶应用(二):结合Kimi制作PPT(双AI协作教程)

🌟引言: DeepSeek作为国产AI大模型,以强大的逻辑推理和结构化内容生成能力著称,擅长根据用户需求生成PPT大纲或Markdown文本;Kimi的PPT助手则能解析结构化内容并套用模板快速生成美观的PPT,两者结合实现“内…...

【Aioredis实战总结】Aioredis简介

一、Aioredis简介 Aioredis 是一个基于Python asyncio框架的异步Redis客户端库,专为高并发场景设计。它允许开发者在不阻塞主线程的情况下执行Redis操作,显著提升I/O密集型任务(如Web应用的缓存、实时消息队列等)的性能。自4.2.0…...

SpringBoot——Maven篇

Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的工具。它具有许多特性,其中一些重要的特性包括: 1. 自动配置:Spring Boot 提供了自动配置的机制,可以根据应用程序的依赖和环境自动配置应用程序的各种组件&#xff…...

Python中的多态与Java、C#、C++中的多态的区别有哪些?

Python中的多态与Java、C#、C等静态类型语言的主要区别体现在以下几个方面: 1. 类型系统与多态实现方式 Python(动态类型,鸭子类型) 多态基于对象的行为(方法的存在性),而非继承或接口。只要对…...

卷积神经网络(知识点)

一、为了使特征图变小: 由两种方法:1.增大步长:卷积的时候不是一次一步,而是一次多步,类似一张图片,在原来的像素基础上,每隔一个取一个像素点。 其中S就是步长 注意:扩大步长不经…...

Vision Transformer (ViT):将Transformer带入计算机视觉的革命性尝试(代码实现)

Vision Transformer (ViT):将Transformer带入计算机视觉的革命性尝试 作为一名深度学习研究者,如果你对自然语言处理(NLP)领域的Transformer架构了如指掌,那么你一定不会对它在序列建模中的强大能力感到陌生。然而&am…...

特殊 IP 地址

文章目录 特殊IP地址概述受限广播地址(Limited Broadcast Address)直接广播地址(Directed Broadcast Address)多播地址(Multicast Address)环回地址(Loopback Address)本网络本主机&…...

数学——A. K-divisible Sum + D. Exam in MAC

A. K-divisible Sum 题目: 思路: 以下 “[xxx]” 符号均代表向上取整 我们假设总和是sum,那么就有sum k * cnt 要想最大值最小,肯定是要让sum尽可能小,这样每个元素都能变小 最小情况是 sum 恰好等于 n 时&#…...

30天学习Java第五天——数组 字符串

数组 一维数组 定义 int[] anArray;int anOtherArray[];初始化int anOtherArray[] new int[] {1, 2, 3, 4, 5}; 访问 anArray[0] 10;可变数组:void varargsMethod(String... varargs) {} 该方法可以接收任意数量的字符串参数,可以是 0 个或者 N 个…...

【DeepSeek应用】本地部署deepseek模型后,如何在vscode中调用该模型进行代码撰写,检视和优化?

若已成功在本地部署了 DeepSeek 模型(例如通过 vscode-llm、ollama 或私有 API 服务),在 VS Code 中调用本地模型进行代码撰写、检视和优化的完整流程如下: 1. 准备工作:确认本地模型服务状态 模型服务类型: 若使用 HTTP API 服务(如 FastAPI/Flask 封装),假设服务地址…...

2025年【广东省安全员C证第四批(专职安全生产管理人员)】考试及广东省安全员C证第四批(专职安全生产管理人员)模拟试题

安全生产是各行各业不可忽视的重要环节,特别是在广东省这样的经济大省,安全生产的重要性更是不言而喻。为了确保安全生产管理人员具备足够的专业知识和实际操作能力,广东省定期举办安全员C证考试。本文将详细介绍2025年广东省安全员C证第四批…...

网络编程、URI和URL的区别、TCP/IP协议、IP和端口、URLConnection

DAY12.1 Java核心基础 网络编程 在互联网时代,网络在生活中处处可见,javaWeb占据了很大一部分 那如何实现javaWeb编程呢? Web编程就是运行在同一个网络下面的终端,使得它们之间可以进行数据传输 计算机网络基本知识 计算机网络…...

JAVA面试_进阶部分_Java JVM:垃圾回收(GC 在什么时候,对什么东西,做了什么事情)

在什么时候: 首先需要知道,GC又分为minor GC 和 Full GC(major GC)。Java堆内存分为新生代和老年代,新生代 中又分为1个eden区和两个Survior区域。 一般情况下,新创建的对象都会被分配到eden区&#xff…...

自探索大语言模型微调(一)

一、数据 1.1、失败案例 Hugging Face: 根据B站上搜索到的资料,datasets这个库可以直接下载丰富的数据集合和与训练模型,调用也非常的简单,唯一的缺点就是,需要外网(翻墙),用国内的…...

Unity 和 Python 的连接(通过SocketIO)附源码

在游戏或者项目开发中,Unity 通常用于创建前端,而 Python 则因其强大的数据处理能力常被用作后端。通过 Socket.IO,我们可以轻松地实现 Unity 和 Python 的实时通信。本文将介绍如何通过 Socket.IO 连接 Unity 和 Python,并附上完…...

89.HarmonyOS NEXT 应用安全与隐私保护指南:构建安全可靠的应用

温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! HarmonyOS NEXT 应用安全与隐私保护指南:构建安全可靠的应用 文章目录 HarmonyOS NEXT 应用安全与隐私保护指南:构建安全可…...

浏览器对一个资源设置了缓存,如何清除缓存,且后续请求不命中缓存

方式1、浏览器端强制刷新 方式2、修改资源url eg&#xff1a;如下图&#xff0c;添加了查询参数 <link rel"stylesheet" href"style.css?v1.2.1"> <script src"app.js?t20231010"></script> 原理&#xff1a;1、在资源的…...

spring boot 发送邮件验证码

一、前置需求 1、准备邮箱 2、登录授权码 qq邮箱在–>设置–>账号POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 开启服务 二、发送邮件 1、简单邮件 包含邮件标题、邮件正文 2、引入mail启动器 <dependency><groupId>org.springframework.boot</groupI…...

MySQL连接较慢原因分析及解决措施

文章目录 整体说明一、问题现象二、问题分析2.1、DNS反向解析问题2.2、网络问题2.3、SSL/TLS协商问题2.4、自动补全的延迟 三、问题解决 摘要&#xff1a; MySQL连接较慢原因分析及解决措施 关键词&#xff1a; MySQL、连接缓慢、客户端、参数设置 整体说明 在使用MySQL的时候…...

IMA+DeepSeekR1+本地知识库撰写NOIP2008普及组T3【传球游戏】题解

目录 一、提问词 二、DeepSeekR1回复 题目描述 解题思路 实现代码 代码说明 三、说明 【IMADeepSeekR1本地知识库】撰写NOIP2008普及组复赛题解系列 1、IMADeepSeekR1本地知识库撰写NOIP2008普及组T1【ISBN 号码】题解-CSDN博客 2、IMADeepSeekR1本地知识库撰写NOIP200…...

【大模型基础_毛玉仁】2.5 基于 Decoder-only 架构的大语言模型 -- GPT和LLaMa模型介绍

更多内容&#xff1a;XiaoJ的知识星球 目录 2.5 基于 Decoder-only 架构的大语言模型2.5.1 Decoder-only 架构2.5.2 GPT 系列语言模型1&#xff09;初出茅庐&#xff1a;GPT-1 模型2&#xff09;小有所成&#xff1a;GPT-2 模型3&#xff09;崭露头角&#xff1a;GPT-3 模型4&a…...

如何解决ChatGPTplus/pro o1/o3模型无法识别图片或者文件,限制次数?

你是否遇到ChatGPTplus无法识别图片、或者无法识别文件&#xff0c;甚至回答很简短&#xff0c;o1不思考&#xff0c;GPT-4o不能联网、分析图片和处理文件&#xff01;感觉非常敷衍。本文教你如何确定自己的账号是否被降智&#xff1b;教你如何降智的原因&#xff1b;教你解决降…...

go的gmp

参考链接&#xff1a;https://www.bilibili.com/video/BV19r4y1w7Nx Golang的GMP调度模型(协程调度器)是其并发编程的核心。GMP代表Goroutine、Machine和Processor三个关键组成部分。Goroutine是Go语言中的轻量级线程&#xff0c;Machine是操作系统的线程&#xff0c;Processor…...

Vue开发者工具(VueDevtools)下载与安装

一、这里采用极简插件 网址&#xff1a;chrome.zzzmh.cn/index#/inde… 输入 vue.js.devtools并访问 点击推荐下载 下载到本地解压缩 然后把这个文件移动到谷歌插件里面,开启开发者模式 点击详情,开启一些权限 写的一个demo&#xff0c;如果有vue代码的话&#xff0c;就会…...

【C++基础十】泛型编程(模板初阶)

【C基础十】泛型编程—模板 1.什么是模板2.函数模板的实例化&#xff1a;2.1隐式实例化2.2显示实例化 3.函数模板参数的匹配规则4.什么是类模板5.类模板的实例化6.声明和定义分离 1.什么是模板 void swap(int& a, int& b) {int tmp 0;tmp a;a b;b tmp; }void swap…...

【Linux】https 协议

目录 一、https 协议 二、加密和解密 &#xff08;一&#xff09;为什么需要加密与解密 &#xff08;二&#xff09;加密和解密的过程 &#xff08;二&#xff09;常见的加密方式 1、对称加密 2、非对称加密 3、数据摘要 4、数字签名 三、https 的加密方式 &#xff…...

新手村:数据预处理-特征缩放

新手村&#xff1a;数据预处理-特征缩放 特征缩放&#xff08;Feature Scaling&#xff09;是数据预处理中的一个重要步骤&#xff0c;特别是在应用某些机器学习算法时。特征缩放可以使不同尺度的特征具有相同的量级&#xff0c;从而提高模型训练的效率和性能。常见的特征缩放方…...

Xinference大模型配置介绍并通过git-lfs、hf-mirror安装

文章目录 一、Xinference开机服务systemd二、语言&#xff08;LLM&#xff09;模型2.1 配置介绍2.2 DeepSeek-R1-Distill-Qwen-32B&#xff08;大杯&#xff09;工具下载git-lfs&#xff08;可以绕过Hugging Face&#xff09; 2.3 DeepSeek-R1-Distill-Qwen-32B-Q4_K_M-GGUF&am…...

Python游戏开发自学指南:从入门到实践(第四天)

Python不仅适用于数据分析、Web开发和自动化脚本&#xff0c;还可以用于游戏开发&#xff01;虽然Python不是传统意义上的游戏开发语言&#xff0c;但其简洁的语法和丰富的库使其成为初学者学习游戏开发的绝佳选择。本文将为你提供一份全面的Python游戏开发自学指南&#xff0c…...