这是我STM32F103C8T6开发笔记专栏的一部分。可以到专栏中查阅更多内容。

STM32F103C8T6开发笔记整理​zhuanlan.zhihu.com

【写在前面】:

  1. 这篇笔记的内容,主要是指导如何进行对STM32进行GPIO的输出操作。
  2. 有关寄存器配置的说明,限于篇幅,我只能将它在参考手册中的页码标注出来,小伙伴们可以自行查阅。
  3. 我使用的是STM32F103C8T6型号的核心板。
  4. 这篇笔记,综合参考了野火、正点原子、st官方以及网络上的一些资料,然后经过我自己的思考、尝试与实践,从而整理出来的。感谢那些愿意在学习的路上分享自己知识与经验的前辈。
  5. 我在学习的过程中,经历过毫无头绪,找到一堆学习资料却不知从何开始的痛苦。我希望我整理的笔记,不光可以方便自己在以后的项目中拿来即用,也希望能够对那些喜欢玩硬件、爱折腾的小伙伴有所帮助。如果你们觉得我的文章对你们有用,欢迎大家点赞+收藏,让我知道,我的工作是有价值的。

1. GPIO相关的寄存器

首先需要知道的是,STM32中对于GPIO口的操作,无非就是操作下面的寄存器而已,所谓的标准库也好,HAL库也好,它们都只是对操作寄存器的过程进行了封装,目的是为了减轻你编程时的工作负担。因此对于寄存器的描述,你只要稍微了解一下,大概知道每个寄存器是干啥的,有哪些位,是如何配置的就行,除了一些你觉得需要留意的地方,其它的完全没有必要完全记住,用的时候知道再哪里查就行了。

两个32位的配置寄存器:GPIOx_CRL、GPIOx_CRH

两个32位数据寄存器:GPIOx_IDRGPIOx_ODR

一个32位的置位/复位寄存器:GPIOx_BSRR

一个16位复位寄存器:GPIOx_BRR

一个32位锁定寄存器:GPIOx_LCKR

注:具体的寄存器描述可以参考《STM32F10x-中文参考手册》的GPIO章节的P113页。强烈建议先花几分钟先看一下这一部分的内容。

2. GPIO输出的操作流程

Step1:使能GPIO的时钟

STM32中的每一个外设都对应了一个时钟,当我们想要使用某一个外设的时候,必须先要开启它的时钟才行。

注:STM32中有一个专门管理时钟和复位的外设RCC。有关RCC时钟控制寄存器部分的具体描述可以参考《STM32F10x-中文参考手册》的P55页,可以花个十分钟左右的时间,大概了解一下STM32有哪些时钟,又有哪些寄存器可以配置。

所有的 GPIO 都挂载到 APB2 总线上,具体的时钟由 APB2 外设时钟使能寄存器(RCC_APB2ENR)来控制(《STM32F10x-中文参考手册》P70页)。

在编程时,可以使用标准库里提供的函数RCC_APB2PeriphClockCmd(),快速的使能相应的GPIO时钟。

 /*以GPIOC为例,使能它的时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

Step2:初始化GPIO引脚至相应的模式

当我们使用GPIO口之前,我们还需要对它进行一些初始化的操作,比如要设置它的速度、模式和引脚号。

注:关于速度和模式的配置可以查看《STM32F10x-中文参考手册》P113页和P114页部分的内容。

然后关于GPIO的几种输出模式的区别有所不了解的,可以自行百度或者谷歌:推挽输出和开漏输出。

简单来说,推挽输出既可以输出高电平,也可以输出低电平;开漏输出只能输出低电平,若要输出高电平,需要外接上拉电阻才行。

像我们平时利用单片机点个灯什么的,直接将GPIO配置为推挽输出模式就可以了。

接下来,我们可以使用标准库中的GPIO_Init()函数来进行GPIO的初始化操作。

关于该函数的使用方法,看代码注释。

 /*下面的代码,将GPIOC的13号引脚配置为推挽输出,速度为50MHz*/​/*Step1:定义一个GPIO_InitTypeDef类型的结构体,该类型是标准库里定义的*/GPIO_InitTypeDef GPIO_InitStructure;​/*Step2:选择要控制的GPIO引脚为Pin13*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;  ​/*Step3:设置引脚模式为通用推挽输出*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   ​/*Step4:设置引脚速率为50MHz */   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; ​/*调用库函数GPIO_Init(),初始化GPIO*/GPIO_Init(GPIOC, &GPIO_InitStructure);  

Step3:控制GPIO引脚输出高低电平

我们当然可以直接操作参考手册里描述的寄存器来输出高低电平,在这里,我们使用标准库中帮我们封装好的函数GPIO_SetBits()GPIO_ResetBits()来操作GPIO的输出电平。

 GPIO_SetBits(GPIOC,GPIO_Pin_13);    //将PC13引脚输出高电平GPIO_ResetBits(GPIOC,GPIO_Pin_13);  //将PC13引脚输出低电平

Step4:使用GPIO控制LED

基于之前新建的工程模板,将上述的三个步骤所介绍的内容组合在一起,我们就可以实现一个点亮Led灯的项目。

为了直观、整体的了解代码的结构,我将它们统一写在了main.c文件中,你们当然也可以按照自己的需要,新建一个Led.c,用于保存这些控制Led的代码。

 #include "stm32f10x.h"​void delay( uint32_t nCount);void LED_Init(void);​int main(void){/*使能GPIOC时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);/*配置相关引脚,进行LED的初始化*/LED_Init();while(1){/*将PC13引脚输出高电平,熄灭小灯*/GPIO_SetBits(GPIOC,GPIO_Pin_13);/*延时,以实现闪烁效果*/delay(0x0FFFFF);/*将PC13引脚输出低电平,点亮小灯*/GPIO_ResetBits(GPIOC,GPIO_Pin_13);  /*延时,以实现闪烁效果*/delay(0x0FFFFF);        }}​​void delay( uint32_t nCount)     //简单的延时函数{for(; nCount != 0; nCount--);}​/*配置相关引脚,进行LED的初始化*/void LED_Init(void){/*下面的代码,将GPIOC的13号引脚配置为推挽输出,速度为50MHz*/​/*Step1:定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;​/*Step2:选择要控制的GPIO引脚*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;  ​/*Step3:设置引脚模式为通用推挽输出*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   ​/*Step4:设置引脚速率为50MHz */   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; ​/*调用库函数,初始化GPIO*/GPIO_Init(GPIOC, &GPIO_InitStructure);​/*将PC13引脚输出高电平,熄灭LED*/GPIO_SetBits(GPIOC,GPIO_Pin_13; }​

将这一段程序复制到标准库工程模板的main.c文件中,编译通过后,下载进开发板,就可以看到LED闪烁的效果了。

3. 利用STM32控制一个RGB彩灯

接下来,我们利用上面的知识,来实现控制一个RGB彩灯。

首先,我们需要下面的这些元器件。

然后我们使用ST-Link来为开发板下载程序,关于ST-Link与核心板的接线,可以参考下图,然后将对应的地方用杜邦线连接即可。

关于RGB灯的连接,将最长的那个引脚接正极,剩下的三个引脚分别通过一个通过一个220​ 电阻接到开发板的PC13、PC14、PC15上去。就像下面这样。

最后实现该工程的代码如下所示:

main.c文件

#include "stm32f10x.h"
#include "led.h"int main(void)
{/*使能GPIOC时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);/*配置相关引脚,进行LED的初始化*/LED_Init();while(1){/*颜色循环效果*/Led_Cycle();}
}

led.c文件

 #include "led.h"​/*配置相关引脚,进行LED的初始化*/void LED_Init(void){/*下面的代码,将GPIOC的13号引脚配置为推挽输出,速度为50MHz*/​/*Step1:定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;​/*Step2:选择要控制的GPIO引脚*/GPIO_InitStructure.GPIO_Pin = Led_Red_Pin | Led_Green_Pin | Led_Blue_Pin;   ​/*Step3:设置引脚模式为通用推挽输出*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   ​/*Step4:设置引脚速率为50MHz */   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; ​/*调用库函数,初始化GPIO*/GPIO_Init(Led_Port, &GPIO_InitStructure);​/*将PC13引脚输出低电平,点亮小灯*/GPIO_SetBits(Led_Port, Led_Red_Pin | Led_Green_Pin | Led_Blue_Pin); }​/*亮红色*/void LED_Red(void){GPIO_ResetBits(Led_Port, Led_Red_Pin);GPIO_SetBits(Led_Port, Led_Green_Pin | Led_Blue_Pin);}​/*亮绿色*/void LED_Green(void){GPIO_ResetBits(Led_Port, Led_Green_Pin);GPIO_SetBits(Led_Port, Led_Red_Pin | Led_Blue_Pin);}​/*亮蓝色*/void LED_Blue(void){GPIO_ResetBits(Led_Port, Led_Blue_Pin);GPIO_SetBits(Led_Port, Led_Red_Pin | Led_Green_Pin);}​/*亮青色*/void LED_Cyan(void){GPIO_ResetBits(Led_Port, Led_Blue_Pin | Led_Green_Pin);GPIO_SetBits(Led_Port, Led_Red_Pin);}​/*亮黄色*/void LED_Yellow(void){GPIO_ResetBits(Led_Port, Led_Red_Pin | Led_Green_Pin);GPIO_SetBits(Led_Port, Led_Blue_Pin);}​/*亮品红色*/void Led_Solferino(void){GPIO_ResetBits(Led_Port, Led_Red_Pin  | Led_Blue_Pin);GPIO_SetBits(Led_Port, Led_Green_Pin);}​/*亮白色*/void Led_White(void){GPIO_ResetBits(Led_Port, Led_Red_Pin | Led_Green_Pin | Led_Blue_Pin);}​/*关闭彩灯*/void Led_Black(void){GPIO_SetBits(Led_Port, Led_Red_Pin | Led_Green_Pin | Led_Blue_Pin);}​/*颜色循环效果*/void Led_Cycle(void){LED_Red();delay(Delay_Time);LED_Green();delay(Delay_Time);  LED_Blue();delay(Delay_Time);LED_Cyan();delay(Delay_Time);LED_Yellow();delay(Delay_Time);Led_Solferino();delay(Delay_Time);Led_White();delay(Delay_Time);Led_Black();delay(Delay_Time);}​/*简易延时函数*/void delay( uint32_t nCount)    {for(; nCount != 0; nCount--);}

led.h文件

#ifndef __LED_H
#define __LED_H#include "stm32f10x.h"/*为RGB相关的引脚添加一些宏定义*/
#define Led_Port            GPIOC
#define Led_Red_Pin         GPIO_Pin_13
#define Led_Green_Pin       GPIO_Pin_14
#define Led_Blue_Pin        GPIO_Pin_15/*延时时间*/
#define Delay_Time 0x7FFFF8void LED_Init(void);
void LED_Red(void);
void LED_Green(void);
void LED_Blue(void);
void LED_Cyan(void);
void LED_Yellow(void);
void Led_Solferino(void);
void Led_White(void);
void Led_Black(void);
void Led_Cycle(void);
void delay(uint32_t nCount);#endif

【注】:使用ST-Link为STM32下载程序时,需要为其进行供电,我们用一根micro-usb线连接开发板与电脑或者充电宝就可以了。

为了方便文件的分享与管理,我将该项目完整的工程文件,放在了我的个人公众号里面,想要学习的小伙伴可以在微信里搜索:蟹老板的折腾日常。回复:001,即可免费获取。

stm32核心板可以点亮灯吗_二、STM32的GPIO输出操作相关推荐

  1. stm32核心板可以点亮灯吗_利用STM32F103C8T6最小系统板点亮流水灯

    后台网友建议制作一个流水灯,正好发现自己有之前购买的STM32F103C8T6核心板,今天搭建一个流水灯,正好学习一下STM32 GPIO输出如何实现,将来驱动蜂鸣器.继电器等都会使用的. 流水灯相当 ...

  2. stm32核心板可以点亮灯吗_2020年的Flag立了吗?学好EDA要算一个

    欢迎来到崭新的2020. 新的篇章徐徐展开,80后都奔四了,90后也要奔三,我们和光同尘.与时舒卷,但还是要向前摸索. 那么,作为一个未来的电子从业工程师,什么是你能力的基本盘?学会EDA! EDA ...

  3. stm32核心板可以点亮灯吗_STM32库函数点亮LED

    很多码农写出的第一个程序是"Hello World!",因为这个程序简单容易上手,能给你自信心,让你更加坚定学习编程的信念:单片机也是如此,相信很多单片机老师教给你的第一个程序就是 ...

  4. stm32核心板可以点亮灯吗_STM32G0板卡试用 | NUCLEO-G071RB板之PWM调光实验

    新近参与电堂平台活动,获得最新款NUCLEO-G071RB板卡,帮助我了解STM32G071RB这款芯片的特性,下文为我的试用体验. 项目概述 ST公司从2012年推出入门级低成本Cortex-M0内 ...

  5. STM32核心板电路分析

    文章目录 STM32核心板电路分析 蜂鸣器电路分析 按键电路和led电路分析 继电器电路和usb转串口电路分析 杨桃32学习笔记,本文图片文字皆为转述 STM32核心板电路分析 上图可以看到: (1) ...

  6. EC600N(二)--核心板初次点亮

    系列文章目录 EC600N(一)–基本信息介绍 EC600N(二)–核心板初次点亮 目录 系列文章目录 前言 一.使用前说明 1.供电方式 2. 模块开机状态 二.AT指令测试 1.测试准备 2.AT ...

  7. (置顶)飞控板不用看得高大上,本质就是STM32加那几个传感器,和平衡车板子差不多,是完全可以自己画的,甚至不用画,买个STM32核心板+十轴模块

    你自己画一块板子,然后真正飞成了,我觉得你会非常开心的,这种感觉不一样的我觉得,你说是不是. 飞控我们不用看得高大上,本质还是STM32加传感器,可能和平衡车的差不多,所以不用觉得高大上什么的. 真的 ...

  8. nucleo stlink 固件_【指南】如何用STM32核心板DIY STLink V2

    写在前面 这篇指南目前并不完善,只是我对最近几天DIY过程的一点总结,不过,我相信它足够帮助你从零开始做一个STLink出来,而且是以非常简单的方式. 所需材料.工具/软件 基本焊接工具. STM32 ...

  9. stm32呼吸灯程序_学习STM32从点灯开始!

    前言 学STM32我们从点灯开始,学Linux驱动我们自然也要点个灯来玩玩,尽量在从这些基础例程中榨取知识,细抠.细抠,为之后更复杂的知识打好基础. 与硬件无关的LED驱动 回顾hello驱动程序,我 ...

最新文章

  1. 一种定位内存泄露的方法(Linux)
  2. springframework报错_应对报错信息的必杀技!
  3. 虚拟服务器选那个存储好,如何选择虚拟环境中的存储?
  4. Python学习笔记:求一组数据的众数
  5. 6步教你zencart模板制作
  6. 图解CNN:通过100张图一步步理解CNN
  7. 【超详细附参考】阿里云部署spring项目基本流程详解及踩坑经验
  8. 自定义UTI注册自己的APP
  9. 【一起DIY】吞币机器人
  10. 虹科QA | SWCF2022 12月6日演讲笔记:C波段卫星与5G之间的干扰排查及解决方案
  11. 开源J2EE项目Zheng环境Docker部署
  12. 前端——获取手机验证码案例
  13. --fiddler--实战--抓包到底干嘛用?
  14. 弘辽科技:新手卖家如何制作高点击率主图
  15. nginx配置-根据UA进行域名跳转且仅限域名访问
  16. 最全的CSS浏览器兼容问题
  17. 电脑没有Hyper-V的解决方法,该咋办?
  18. echarts.js制作中国地图
  19. 跟百度网盘说再见?阿里云盘永不限速!永久容量赶快领!
  20. 忻州计算机cad培训,忻州CAD三维建模培训cad三维制图教程

热门文章

  1. PostgreSQL报错 ERROR: function sum(character varying) does not exist
  2. html 正方形符号,Html 特殊符号
  3. php的原子操作,原子操作 · 国外PHP框架Nette官网教程 · 看云
  4. Java 编程问题:二、对象、不变性和`switch`表达式
  5. 数据分析----数据清洗
  6. 问题十四:怎么可视化球的法向量
  7. Linux 下 QT 安卓开发环境搭建
  8. 谈谈我所了解的数据分析行业(上)
  9. vue之push() pop() shift() unshift() splice() sort() reverse()等等
  10. ThinkPHP6 验证码(点击刷新)