普中STM32F103ZET6开发攻略(一)

各位看官老爷们,点击关注不迷路哟。你的点赞、收藏,一键三连,是我持续更新的动力哟!!!

目录

普中STM32F103ZET6开发攻略

1. GPIO端口实验——点亮LED灯

1.1 实验目的

1.2 实验原理

1.3 实验环境和器材:

1.4 实验思路

1.5 实验代码

1.5.1 LED相关代码

1.5.2 delay相关代码

1.6 实验思考和拓展

1.6.1 如何调整LED灯的闪烁频率?

1.6.2 如何实现呼吸灯效果?

1.6.2.1 非 PWM 实现呼吸灯的原理

1.6.2.2 具体实现方法(以 STM32 为例)

1. 亮度等级划分

2. 控制亮灭时间比例

1.6.2.3 代码实例:

1.6.3 除了使用简单延时外,STM32还有哪些更加精准的延时方式?

1.7 注意事项


普中STM32F103ZET6开发攻略

1. GPIO端口实验——点亮LED灯

1.1 实验目的

  1. 了解STM32F10x微控制器的GPIO口结构和基本操作

  1. 掌握STM32标准库函数对GPIO的配置和使用方法

  1. 学会使用GPIO控制LED的亮灭,实现LED基本显示效果

  1. 掌握简单延时函数的编写方法

1.2 实验原理

  1. GPIO原理

    STM32的GPIO(通用输入/输出端口)用于外设信号的输入输出控制。STM32F10x系列GPIO具有以下特性:

    (1) 每个I/O端口有16个可独立配置的I/O位

    (2) 支持8种不同的工作模式

    模式分类具体模式核心特点典型应用
    输入模式浮空输入无内部上下拉,电平由外部决定外部信号采集(需外部上下拉)
    上拉输入内部上拉,默认高电平按键输入(低电平有效)
    下拉输入内部下拉,默认低电平按键输入(高电平有效)
    模拟输入连接 ADC,禁用数字输入功能ADC 模数转换
    输出模式开漏输出需外部上拉,支持线与逻辑I2C 总线、电平转换
    推挽输出直接输出高低电平,驱动能力强LED 控制、普通数字信号
    开漏复用功能外设驱动,需外部上拉SPI/I2C 外设输出
    推挽复用功能外设驱动,直接输出高低电平USART/CAN 外设输出

    通过配置 GPIO 的模式寄存器(CRL/CRH)和输出类型寄存器,可灵活选择上述工作模式,满足不同外设的控制需求。

    (3) 每个I/O口可以产生外部中断

    (4) 位设置/复位寄存器,支持原子位操作

  2. LED控制原理

    LED (发光二极管) 是一种单向导电器件,只有在正向偏置时才会发光。根据开发板硬件设计,LED灯通常采用如下接法:

    (1) 共阳极接法:LED阳极接VCC,阴极接单片机GPIO,GPIO输出低电平时LED点亮;

    (2) 共阴极接法:LED阴极接地,阳极接单片机GPIO,GPIO输出高电平时LED点亮;

    本实验中,LED灯采用的是共阳极接法。

1.3 实验环境和器材:

  1. 电脑:Keil5+Vstudio

  2. 硬件资源:普中玄武F103开发板(主控芯片:STM32F103ZET6

1.4 实验思路

硬件接线图如下所示:

由上图可知:

  1. DS0即LED0、DS1即LED1,分别连接着:PB5和PE5

    LED0连接到GPIOB的Pin5引脚,LED1连接到GPIOE的Pin5引脚

  2. 为了完成实验目的:

    我们需要再项目工程中新建两个“库函数”:LED.c+delay.c

1.5 实验代码

1.5.1 LED相关代码

头文件:

//led.h
#ifndef _led_H
#define _led_H
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"  // 包含GPIO相关的函数和宏定义
#include "stm32f10x_rcc.h"   // 包含RCC(时钟控制)相关的函数和宏定义
void LED_init(void); 
void LED0_On(void);
void LED0_Off(void);
void LED1_On(void);
void LED1_Off(void);
void LED0_Toggle(void);
void LED1_Toggle(void);
#endif
​

源文件:

//led.c
#include "led.h"
​
void LED_init(void)
{// 使能 GPIOB 和 GPIOE 的时钟(几乎所有外设(包括 GPIO)在使用前都需要先使能对应的时钟)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE, ENABLE);
​GPIO_InitTypeDef GPIO_InitStructure;
​// 配置 PB5 为推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);
​// 配置 PE5 为推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;GPIO_Init(GPIOE, &GPIO_InitStructure);
​// 初始状态GPIO_SetBits(GPIOB, GPIO_Pin_5);GPIO_SetBits(GPIOE, GPIO_Pin_5);
}
​
​
void LED0_On(void) {GPIO_ResetBits(GPIOB, GPIO_Pin_5);
}
void LED0_Off(void){GPIO_SetBits(GPIOB, GPIO_Pin_5);
}
void LED1_On(void) {GPIO_ResetBits(GPIOE, GPIO_Pin_5);
}
void LED1_Off(void) {GPIO_SetBits(GPIOE, GPIO_Pin_5);
}
void LED0_Toggle(void) {GPIOB->ODR ^= GPIO_Pin_5;
}
void LED1_Toggle(void) {GPIOE->ODR ^= GPIO_Pin_5;
}
​

因为我们这里是直接输出高低电平:所以采用的是推挽输出的方式,由上文可知:推完输出直接输出高低电平,驱动能力强。

初始状态需要设置成为高电平,由上文中的硬件接线图可知,LED(发光二极管)是在正向偏置时才会发光,所以应该是“低电平有效

1.5.2 delay相关代码

头文件:

#ifndef __DELAY_H
#define __DELAY_H
​
#include "stm32f10x.h"
​
void Delay_Init(void);
void Delay_ms(u32 nms);
​
#endif
​

源文件:

#include "delay.h"
​
static u32 fac_ms = 0;
​
void Delay_Init(void)
{SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); // HCLK/8fac_ms = SystemCoreClock / 8000;
}
​
void Delay_ms(u32 nms)
{u32 temp;SysTick->LOAD = nms * fac_ms;SysTick->VAL = 0x00;SysTick->CTRL = 0x01;do{temp = SysTick->CTRL;} while ((temp & 0x01) && !(temp & (1 << 16)));SysTick->CTRL = 0x00;SysTick->VAL = 0X00;
}
​

1.6 实验思考和拓展

1.6.1 如何调整LED灯的闪烁频率?

LED灯闪烁的频率,归根结底还是由灯光的亮和灭时间间隔决定的,亮和灭的时间间隔越小,那么频率就越高

实现方法:

  1. 使用定时器实现精确延时

    若使用自定义简单延时函数(如void Delay_ms(uint32_t ms)),直接调整传入的延时参数。 :原闪烁周期为 0.6 秒(亮 0.3 秒 + 灭 0.3 秒),若改为亮 0.1 秒 + 灭 0.1 秒,则周期变为 0.2 秒,频率提高 3 倍。

    // 原代码(周期0.6秒)
    LED0_ON();  // 亮
    Delay_ms(300);
    LED0_OFF(); // 灭
    Delay_ms(300);
    ​
    // 调整后(周期0.2秒)
    LED0_ON();
    Delay_ms(100);
    Delay_ms(100);
  2. 使用定时器实现精确延时

    简单延时函数依赖系统时钟和循环次数,可通过计算循环次数与时钟周期的关系提高精度。 :若系统时钟为 72MHz,一个循环约耗时 1 微秒,则延时 1 毫秒需循环 1000 次。

  3. 使用定时器实现精确延时:

    利用 STM32 的定时器(如 TIM2、TIM3)产生精确中断,通过中断计数实现延时,避免 CPU 空转,提升系统效率。 步骤: ① 初始化定时器,配置为定时中断模式(如定时 1 毫秒); ② 在中断服务函数中维护一个全局计数器; ③ 主函数中通过判断计数器值实现延时。

1.6.2 如何实现呼吸灯效果?

方法:软件模拟渐变效果

1.6.2.1 非 PWM 实现呼吸灯的原理

呼吸灯的本质是让人眼感知到 LED 亮度的线性渐变(从暗到亮或从亮到暗)。人眼对亮度的感知具有惰性,当 LED 在极短时间内(如几毫秒)频繁亮灭时,会将亮灭时间的平均值视为 “亮度”。因此,即使不使用硬件 PWM,也可以通过软件控制 LED 的亮灭占空比(即导通时间与周期的比例),逐步改变占空比来模拟亮度变化。

1.6.2.2 具体实现方法(以 STM32 为例)

LED 为共阳极接法(低电平点亮),通过以下步骤实现亮度渐变:

1. 亮度等级划分

将亮度从 0%(全灭)到 100%(最亮)划分为若干等级(如 256 级),用一个变量(如brightness)表示当前等级(范围:0~255)。

  • brightness=0:LED 全灭(高电平)。

  • brightness=255:LED 全亮(低电平)。

2. 控制亮灭时间比例

每个亮度等级对应一个周期总时间(如 10ms),其中:

  • 点亮时间 = (brightness / 255) × 周期总时间

  • 熄灭时间 = 周期总时间 - 点亮时间

通过循环改变brightness的值(如从 0 逐渐增加到 255,再逐渐减小到 0),并在每个等级中控制 LED 的亮灭时间,即可实现渐变效果。

1.6.2.3 代码实例:
// 定义LED引脚(共阳极,低电平点亮)
#define LED_GPIO_PORT GPIOB
#define LED_PIN GPIO_Pin_5
​
// 亮度等级(0~255)
uint8_t brightness = 0;
uint8_t direction = 1; // 1表示亮度增加,-1表示亮度减少
​
void breathe_led(void) {// 亮度渐变方向控制(到达边界时反转方向)if (brightness == 255) direction = -1;if (brightness == 0) direction = 1;brightness += direction;
​// 计算亮灭时间(周期总时间设为10ms,可调整)uint16_t on_time = (brightness * 10) / 255; // 点亮时间(ms)uint16_t off_time = 10 - on_time; // 熄灭时间(ms)
​// 控制LED点亮GPIO_ResetBits(LED_GPIO_PORT, LED_PIN); // 低电平点亮delay_ms(on_time); // 点亮持续时间
​// 控制LED熄灭GPIO_SetBits(LED_GPIO_PORT, LED_PIN); // 高电平熄灭delay_ms(off_time); // 熄灭持续时间
}
​
// 主循环中调用
while (1) {breathe_led();
}

与 PWM 方案的对比

特性非 PWM 软件模拟硬件 PWM
实现复杂度需编写循环逻辑和延时函数,代码较繁琐直接配置定时器 PWM 模式,代码简洁
CPU 占用率高(需实时控制亮灭时间,阻塞延时)低(定时器硬件自动更新占空比)
亮度平滑度受延时精度限制,可能有闪烁感平滑(硬件驱动,频率稳定)
适用场景简单实验、对实时性要求低的场合高要求场景(如电机调速、精密调光)

1.6.3 除了使用简单延时外,STM32还有哪些更加精准的延时方式?
  1. 定时器延时(精确且不阻塞 CPU)

    原理:利用定时器的计数功能,通过配置自动重装载值(TIMx_ARR)和预分频器(TIMx_PSC)设定定时时间,结合中断或查询方式实现延时。

    优点:精度高(可达微秒级),延时期间 CPU 可执行其他任务。

  2. SysTick 定时器延时(系统级延时)

    原理:利用 STM32 内部的 SysTick 定时器(系统滴答定时器),基于系统时钟(如 72MHz)产生精确中断。

    优点:无需额外外设,由 Cortex-M 内核直接支持,适合系统级延时。

  3. 实时操作系统(RTOS)任务调度

    原理:在 RTOS(如 FreeRTOS、uCOS)中,通过任务调度函数(如vTaskDelay())实现延时,本质是释放 CPU 资源给其他任务。

    优点:多任务并行处理,延时期间可执行其他任务,适合复杂系统。

  4. 总结与拓展

    1. 简单场景:优先使用 SysTick 或定时器查询方式,兼顾精度与代码复杂度。

    2. 复杂场景:引入 RTOS 或定时器中断,实现多任务协同和精确时序控制。

    3. 进阶实践:结合 DMA(直接内存访问)与定时器,实现无 CPU 参与的自动 PWM 输出,进一步提升效率。

1.7 注意事项

(1) 使用标准库函数时,需要注意头文件的包含和依赖关系。

(2) 共阳极LED的控制逻辑:低电平点亮,高电平熄灭。

(3) 简单延时函数的精确度受系统时钟和编译优化的影响。

(4) GPIO操作前必须先使能对应的外设时钟。

文章有写的不当的地方,欢迎在评论区中指正修改。如果感觉文章实用对你有帮助,欢迎点赞收藏和关注,你的点赞关注就是我动力,大家一起学习进步。

有不懂的可以在评论区里提出来哟,博主看见后会及时回答的。

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

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

相关文章

AWS API Gateway 配置WAF(中国区)

问题 需要给AWS API Gateway配置WAF。 AWS WAF设置 打开AWS WAF首页&#xff0c;开始创建和配置WAF&#xff0c;如下图&#xff1a; 设置web acl名称&#xff0c;然后开始添加aws相关资源&#xff0c;如下图&#xff1a; 选择资源类型&#xff0c;但是&#xff0c;我这里出…

测试分类详解

测试分类 一、按测试对象分类 1. 界面测试 1.1 测试内容介绍 界面测试验证用户界面(UI)的视觉呈现和交互逻辑&#xff0c;确保符合设计规范并提供良好的用户体验。测试内容包括&#xff1a; 页面布局和元素对齐字体、颜色和图标一致性交互反馈&#xff08;悬停、点击状态&a…

打开NRODIC SDK编译不过怎么处理,keil与segger studio

打开NRODIC SDK编译不过怎么处理,以下是keil处理. 1,如图,不要安装安装也不会过 2. 不要安装点击否 3.点击确定后进来这个样子 4.这里选择这个勾,OK后就不会再有后面的pack_license 5.去掉勾后这里要选择自己SDK对应的pack版本,我的是8.27.0 6.OK后弹出个界面也要反复选择…

HarmonyOS ArkUI-X开发中的常见问题及解决方案

一、跨平台编译与适配问题 1. 平台特定API不兼容 ‌问题现象‌&#xff1a;使用Router模块的replaceUrl或startAbility等鸿蒙专属API时&#xff0c;编译跨平台工程报错cant support crossplatform application。 ‌解决方案‌&#xff1a; 改用ohos.router的跨平台封装API&a…

CSS篇-2

4. position 的值分别是相对于哪个位置定位的&#xff1f; position 属性是 CSS 布局中一个非常核心的概念&#xff0c;它允许我们精确控制元素在文档中的定位方式&#xff0c;从而脱离或部分脱离正常的文档流。理解 position 的不同值以及它们各自的定位基准&#xff0c;是实…

设计模式:观察者模式 - 实战

一、观察者模式场景 1.1 什么是观察者模式&#xff1f; 观察者模式&#xff08;Observer Pattern&#xff09;观察者模式是一种行为型设计模式&#xff0c;用于定义一种一对多的依赖关系&#xff0c;当对象的状态发生变化时&#xff0c;所有依赖于它的对象都会自动收到通知并更…

Axure中继器交互完全指南:核心函数解析×场景实战×避坑策略(懂得才能应用)

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!如有帮助请订阅专栏! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 主要内容:中继器核心函数解析、场景方法详解、注意事项、特殊函数区别 课程目标:提高中继器的掌握…

【设计模式-4.5】行为型——迭代器模式

说明&#xff1a;本文介绍设计模式中&#xff0c;行为型设计模式之一的迭代器模式。 定义 迭代器模式&#xff08;Iterator Pattern&#xff09;&#xff0c;也叫作游标模式&#xff08;Cursor Pattern&#xff09;&#xff0c;它提供一种按顺序访问集合/容器对象元素的方法&…

鸿蒙OSUniApp自定义手势识别与操作控制实践#三方框架 #Uniapp

UniApp自定义手势识别与操作控制实践 引言 在移动应用开发中&#xff0c;手势交互已经成为提升用户体验的重要组成部分。本文将深入探讨如何在UniApp框架中实现自定义手势识别与操作控制&#xff0c;通过实际案例帮助开发者掌握这一关键技术。我们将以一个图片查看器为例&…

【数据结构】树形结构--二叉树

【数据结构】树形结构--二叉树 一.知识补充1.什么是树2.树的常见概念 二.二叉树&#xff08;Binary Tree&#xff09;1.二叉树的定义2.二叉树的分类3.二叉树的性质 三.二叉树的实现1.二叉树的存储2.二叉树的遍历①.先序遍历②.中序遍历③.后序遍历④.层序遍历 一.知识补充 1.什…

从认识AI开始-----解密LSTM:RNN的进化之路

前言 我在上一篇文章中介绍了 RNN&#xff0c;它是一个隐变量模型&#xff0c;主要通过隐藏状态连接时间序列&#xff0c;实现了序列信息的记忆与建模。然而&#xff0c;RNN在实践中面临严重的“梯度消失”与“长期依赖建模困难”问题&#xff1a; 难以捕捉相隔很远的时间步之…

接地气的方式认识JVM(一)

最近在学jvm&#xff0c;浮于表面的学了之后&#xff0c;发现jvm并没有我想象中的那么神秘&#xff0c;这篇文章将会用接地气的方式来说一说这些jvm的相关概念以及名词解释。 带着下面两个问题来阅读 认识了解JVM大致有什么在代码运行时的都在背后做了什么 JVM是个啥&#xf…

Next.js 15 与 Apollo Client 的现代集成及性能优化

Next.js 15 与 Apollo Client 的现代集成及性能优化 目录 技术演进集成实践性能优化应用案例未来趋势 技术演进 Next.js 15 核心特性对开发模式的革新 Next.js 15 通过引入 App Router、服务器组件&#xff08;Server Components&#xff09;和客户端组件&#xff08;Clie…

无人机桥梁3D建模、巡检、检测的航线规划

无人机桥梁3D建模、巡检、检测的航线规划 无人机在3D建模、巡检和检测任务中的航线规划存在显著差异&#xff0c;主要体现在飞行高度、航线模式、精度要求和传感器配置等方面。以下是三者的详细对比分析&#xff1a; 1. 核心目标差异 任务类型主要目标典型应用场景3D建模 生成…

Hive数据倾斜问题深度解析与实战优化指南

一、数据倾斜现象的本质与危害 数据倾斜是Hive在MapReduce计算过程中,​部分Key对应的数据量远超其他Key,导致少数Reducer任务处理时间远高于其他任务的性能瓶颈问题。典型表现为: ​作业进度卡在99%​​:99%的Reducer已完成,剩余1%持续数小时​资源利用率失衡​:部分节…

VRRP 原理与配置:让你的网络永不掉线!

VRRP 原理与配置&#xff1a;让你的网络永不掉线&#xff01; 一. VRRP 是什么&#xff0c;为什么需要它&#xff1f;二. VRRP 的核心概念三. VRRP 的工作原理四. 华为设备 VRRP 配置步骤 &#xff08;主备模式&#xff09;4.1 拓扑示例4.2 &#x1f6e0; 配置步骤 五. VRRP 配…

解决开发者技能差距:AI 在提升效率与技能培养中的作用

企业在开发者人才方面正面临双重挑战。一方面&#xff0c;IDC 预测&#xff0c;到2025年&#xff0c;全球全职开发者将短缺400万人&#xff1b;另一方面&#xff0c;一些行业巨头已暂停开发者招聘&#xff0c;转而倚重人工智能&#xff08;AI&#xff09;来满足开发需求。这不禁…

痛点即爆点?如何挖掘客户的痛点和需求?

销售的核心在于精准洞察客户需求与痛点&#xff0c;并运用专业能力为其提供定制化解决方案&#xff0c;从而消除客户顾虑、解决问题&#xff0c;最终实现双赢。而快速识别客户痛点&#xff0c;不仅是成交的关键&#xff0c;更是建立专业形象、赢得客户信任的核心能力。那么&…

云服务器如何自动更新系统并保持安全?

云服务器自动更新系统是保障安全、修补漏洞的重要措施。下面是常见 Linux 系统&#xff08;如 Ubuntu、Debian、CentOS&#xff09;和 Windows 服务器自动更新的做法和建议&#xff1a; 1. Linux 云服务器自动更新及安全维护 Ubuntu / Debian 系统 手动更新命令 sudo apt up…