STM32学习笔记(二)——STM32的GPIO和AFIO

STM32学习笔记(二)——STM32的GPIO和AFIO

一、STM32芯片引脚分布

1.1 特殊功能引脚和普通功能引脚

STM32F103C8T6共有48个引脚

  • 特殊功能引脚(11个)
    • Vdd+Vss给芯片供电引脚 共三队,六个
    • VDDA+VSSA模拟电压 两个(A~Analog模拟的)
    • BOOT0启动方式选择引脚 一个
    • VBAT备用电池引脚(Battery)一个
    • NRST复位引脚 一个
  • 普通IO口引脚(37个)

其中特殊功能引脚是为了维持芯片的运行,所以被特殊化了
普通IO引脚是我们可以去应用的
来源B站铁头山羊

1.2 STM32芯片IO引脚复用

IO复用:IO引脚身兼数职的现象叫IO复用

  • 如:下图的PA9和PA10
    • 不仅可以做普通IO口,
    • 还能做串口通信的发送端口和接收端口,
    • 还能做定时器的通道引脚

来源B站UP铁头山羊

  • 作为芯片设计人员,希望STM32芯片的功能越强大越好
  • 所以设计人员向STM32芯片内加了各种外设模块,来执行各种功能,比如ADC模块,用来做模数转换;I2C模用来通信等,详见下图
  • 每一个模块都能执行特定的功能,每一个模块也会占用不同的引脚资源,芯片的引脚资源明显不够,所以必须让同一个引脚去身兼数职

在这里插入图片描述

1.3 引脚的通用功能和复用功能辨析

  • 通用功能(普通IO):我们通过编程让CPU直接通过GPIO模块对对应的IO引脚进行直接的控制

  • 复用功能:我们通过编程让CPU控制串口模块,串口模块自动的去控制GPIO模块,跟外接进行通信

总结:
通用功能:我们直接对IO引脚进行控制
复用功能:通过控制其他外设,间接对IO口进行控制,复用功能可有多个

在这里插入图片描述

1.4 IO引脚的重映射

IO重映射就说,将某个片上外设的复用功能,移动到其它的IO引脚上

  • 若我们想用PA9和PA10的串口功能,又想用PA9和PA10的定时器功能,就会产生冲突,这时我们可以将串口功能重映射到其它引脚上,避免了冲突

来源B站UP铁头山羊

1.5 最小系统板引脚图

B站UP铁头山羊老师整理的,清晰的很

  • 如,PA9和PA10,可以当作通用IO,也可以复用定时器和串口
  • 当既想用PA9、PA10的串口和定时器时,查重映射部分,看到串口可重映射到PB6和PB7

在这里插入图片描述

1.6 C8T6引脚功能总结

在这里插入图片描述

二、STM32的GPIO

2.1 GPIO简介

  • STM32的CPU通过控制片上外设来执行相应的功能在这里插入图片描述
  • 其中有一种外设叫GPIO,GPIO根据CPU的指令去控制对应的引脚,进行读写操作在这里插入图片描述

2.2 GPIO的寄存器组

寄存器组概念

  • CPU控制GPIO这个片上外设模块,执行引脚的读写操作
  • 可CPU怎么控制GPIO这个片上外设呢,他们之间怎么通信呢?
  • CPU通过寄存器组去控制GPIO外设
    在这里插入图片描述

寄存器组的组成

  • 一个寄存器组由若干个寄存器组成
  • 一个GPIO外设,可以控制16个IO口
  • GPIO寄存器组由以下组成
    • 配置寄存器
    • 输入数据寄存器
    • 输出数据寄存器

在这里插入图片描述

2.3 GPIO的8种工作模式

  • GPIO的工作模式有以下8种
    在这里插入图片描述
  • 中文之华美,我们将名称拆开理解
  • 输入输出
    • 输入:单片机IO口读取到连接的设备的电平
    • 输出:单片机IO口向连接的设备发送电平
  • 通用复用
    • 通用:CPU直接控制GPIO
    • 复用:CPU控制片上外设,片上外设控制GPIO,间接控制
    • 只有输出才有通用、复用功能区分
    • 输入只是读取外部电平,无论是CPU读取,还是片上外设读取都一样,都是那个电平信号
  • 推挽开漏
    • IO引脚内部由2个MOS管组成
    • 推挽模式:通过电压控制MOS交替导通,输出高、低电压
    • 开漏模式: 可以输出低电平,和高阻抗在这里插入图片描述
  • 上拉下拉(针对输入模式)
    • 如果IO引脚工作在输入模式,IO引脚内阻会无穷大,输入是测电压的,可以想象成万用表,万用表测量电阻两端电压时,是并联的,万用表的内存是无穷大的
    • 当输入高低电压时一切正常,但若悬空时,这时IO引脚会类似于天线,接收外界电磁波,产生干扰
    • 解决办法,就说加 上拉电阻或下拉电阻
    • 当接上拉电阻时:引脚悬空时,引脚会被拉高到高电平;引脚正常输入高低电平时,一切正常
    • 当接下拉电阻时:引脚悬空时,引脚会被拉到低电平; 引脚正常输入高低电平时,一切正常在这里插入图片描述

2.4 IO口的最大输出速度

最大输出速度:IO允许输出电平的最大切换频率

  • 受控于上升时间和下降时间,若频率太快,保持时间就会很小,输出不了有效的电平
    在这里插入图片描述

STM32C8T6的最大输出速度分为三挡

  • 2MHZ:每秒钟切换200万次
  • 10MHZ:每秒钟切换1000万次
  • 50MHZ:每秒钟切换5000万次

选择原则:选择满足要求的最小值,以此降低功耗
-在这里插入图片描述

2.5 GPIO内部结构

B站铁头山羊:2.2节 10:42
在这里插入图片描述

三、是的终于到了-----点灯

单纯点灯方法应用程序: 点我点我点我

3.1 学会看原理图

PC13是我们要控制的引脚,当PC13为低电平时,LED导通,点亮;当PC13为高电平时,LED不导通,不亮。
我们要去看想要控制的器件的原理图,了解是什么电平,什么方式驱动这个想要控制的器件的

在这里插入图片描述

3.2 新建工程

  • “工程是包含了我们所有编写的代码的东西”
  • 我们用到的代码,包括,从网上找到的函数库+自己编写的功能代码
  • 从标准库建立一个工程挺复杂的(想学习的可以去看正点原子的前几节课),避免重复造轮子,我们引入工程模板的概念,将常用的库函数功能,集成到一个模板里,而后只需要调用我们所需的库函数,专注于编写我们自己的功能代码即可
  • 网上已经有很多大神,帮我们建立了工程模板,如正点原子的,洋桃电子的,海创电子的,铁头山羊的,因为最近在和铁老师学习,我们接下来用铁老师的模板。

3.3 工程模板结构

  • User:用户自己编写的代码
  • Startup:单片机上电后,会先执行启动文件里的程序,而后执行主函数里的程序
  • PAL库:对标准库的补充
  • 标注库:ST提供的官方库函数

在这里插入图片描述
在这里插入图片描述

3.4 GPIO的标准库编程接口

标准库的编程接口,是和寄存器一一对应的

在这里插入图片描述

3.4 开始编程

3.4.1 IO引脚初始化

初始化:使用IO引脚前做一些参数配置的工作
IO引脚初始化步骤:

  • 使能GPIO端口时钟
  • 选择模式和其它参数(如:推挽输出?最大传输速度?)
    在这里插入图片描述

一、啥是使能GPIO端口时钟 ??????
为啥要使能时钟啊 ???

  • CPU控制的片上外设,都为时序电路,时序电路需要时钟
  • 默认状态,片上外设的时钟,都是关闭的,为了省电
  • 所以用到哪个片上外设,就要开启它对应的时钟在这里插入图片描述

不是,那咋使能时钟啊 ???

  • 我们需要向RCC外设的寄存器里写值(忽略)
  • 我们只需要调用对应的函数即可
    在这里插入图片描述

二、GPIO_Init咋用啊??????
GPIO_Init简介:

  • 用于初始化单个IO引脚
  • 使用时填入两个参数
  • 参数1:选择想要初始化引脚的端口号,如出书画PC13,参数填GPIOC
  • 参数2:初始化各种参数,为结构体类型的指针。库函数帮我们声明好了结构体类型,这个结构体类型名称叫GPIO_InitTypeDef,也就是它给了一张表格,表格叫GPIO_InitTypeDef,你需要将你用的参数,填写到表格中。在这里插入图片描述

结构体知识补充:

  • 声明结构体类型,再定义结构体变量
  • 类比:结构体类型=int类型
  • 类比:定义结构体类变量=定义整形变量。
  • 类比:GPIO_InitTypeDef a = int a

具体操作步骤

  • 将库函数给你表格,写上你自己的名字,也就是定义结构体类型变量GPIO_InitTypeDef GPIOInitStruct(名称自定义);

  • 填写结构体变量的参数:

    • 端口C一共有16个引脚,用的哪一个引脚?
    • GPIO的模式是啥?推挽输出,输入上拉?
    • 若是输出,输出的最大速度是啥?
  • 调用GPIO_Init()函数,填入两个参数
    在这里插入图片描述

3.4.2 ODR的写入和读取

ODR(Output Data Register)输出数据寄存器

  • 此寄存器可以写入也可以读取
  • 写入:控制MOS管通断
  • 读取:读出上次写入ODR的值

在这里插入图片描述

3.4.3 IDR的读取

IDR(Intput Data Register)输入数据寄存器

在这里插入图片描述

3.4.4 IO的翻转

IO翻转:先让灯亮,延时一会,再让灯灭,在延时一会,以此循环
编程实现:

  • 实现延时功能:库函数中没有这个功能,引入PAL库
    • 引入头文件#include “stm32f10x_pal.h”
    • 对PAL 库初始化 PAL_Init()
    • 使用PAL库中的延时函数 PAL_Delay() 单位ms

在这里插入图片描述

方案1的实现:

#include "stm32f10x.h"
#include "stm32f10x_pal.h"

int main(void)
{
	GPIO_InitTypeDef GPIOInitStruct;
	PAL_Init();
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIO外设时钟
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_13;
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//输出开漏
	GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC,&GPIOInitStruct);//初始化GPIO外设C组
	
	while(1)
	{
		GPIO_WriteBit(GPIOC,GPIO_Pin_13,0);//给PC13引脚写0,点亮灯
		PAL_Delay(100);//延时100ms
		GPIO_WriteBit(GPIOC,GPIO_Pin_13,1);//给PC13引脚写0,熄灭灯
		PAL_Delay(100);//延时100ms
	}
}

方案2的实现:

方案2中的翻转是如何做到的呢?

  • ODR寄存器的可以读取上次写入的值
  • 我们只需要读取上次写的是0还是1,若是1 这次写0;若是0,这次写1,就可以实现翻转的功能在这里插入图片描述
#include "stm32f10x.h"
#include "stm32f10x_pal.h"

int main(void)
{
	GPIO_InitTypeDef GPIOInitStruct;
	PAL_Init();
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIO外设时钟
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_13;
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//输出开漏
	GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC,&GPIOInitStruct);//初始化GPIO外设C组
	
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,0);//给PC13引脚写0,点亮灯
	
	while(1)
	{
		  PAL_Delay(100);//延时100ms
			
			//翻转代码
			if(GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_13) == 0)
			{
				GPIO_WriteBit(GPIOC,GPIO_Pin_13,1);
			}
			else 
			{
				GPIO_WriteBit(GPIOC,GPIO_Pin_13,0);
			}
	}
}

四、按键编程

单纯按键应用程序: 点我点我点我

4.1 按键的电路设计

外接上拉电阻:

  • 按键打开,IO口读取到的是高电平
  • 按键闭合,IO口读取到的是低电平

内部上拉电阻

  • 由于单片机内部本来就有两个电阻
  • 可设置输入模式,来启用内部的上拉电阻,这样按键电路,节省了一个电阻

在这里插入图片描述

按键电路:连接时,连接1-3端 或者2-4端
在这里插入图片描述

4.2 按键编程的原理

当按键按下时,IO口读取到的是低电平 当按键松开时,IO口读取到的值是高电平,我们可以不断的读取IO引脚的值,来检测按键的状态

在这里插入图片描述

但我们习惯于捕捉,按键按下或者松开那一瞬间的值,因为只有在按键状态变化的瞬间才去切换LED的亮灭

  • 如:电脑的鼠标左键,当我们按下按键时,鼠标不会有反映,只有当我们松开按键的瞬间,鼠标才完成了点击这个动作,所以我们捕捉的是按键发生变化的瞬间。
  • 方法:我们声明两个变量
    • previous 上次
    • current 当前
    • 若上次读到IDR寄存器里值是1,当前IDR寄存器是0,表示按键按下的瞬间
      *若读到从0到1,是松开按键的瞬间

在这里插入图片描述

1.先定义两个变量,存储上一次读取到的值,和这一次读取到的值
2.然后将当前值,赋给上一次值
3.在读取当前值
4.若当前值和上一次值不想等,则代表,按键状态发生了变化
5.那是按下的变化,还是松开的变化呢
6.只需要判断当前值,当前值是0,则是按下的瞬间
7.当前值是1,则是松开的瞬间

在这里插入图片描述

4.3 按键控制灯的亮灭代码实现

1.PC13连接的是灯 要把PC13初始化为输出开漏模式
2.PA0连接的按键 初始化为输入上拉模式
3.读取PA0的电平,看其是否是按键按下后又松开那个瞬间,若是
4.编写灯翻转程序

#include "stm32f10x.h"
#include "stm32f10x_pal.h"

int main(void)
{
	uint8_t current = 1;
	uint8_t previous = 1;
	GPIO_InitTypeDef GPIOInitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//开启GPIOC时钟
	PAL_Init();
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_13;
	GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC,&GPIOInitStruct);//初始化GPIOC
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIOA时钟
	
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;//代码一行一行执行,所以直接给结构体变量直接赋值就行
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOA,&GPIOInitStruct);//初始化GPIOA 
	
	while(1)
	{
		previous = current ;
		current = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);
		if(current != previous)
		{
			if(current == 0)//按键按下
			{		
			}
			else
			{
				//切换灯的亮灭状态
				if( GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_13) == 0 )
				{
					GPIO_WriteBit(GPIOC,GPIO_Pin_13,1);
				}
				else
				{
					GPIO_WriteBit(GPIOC,GPIO_Pin_13,0);
				}
			}
		}
		
	}
}

4.4 按键消抖

4.4.1 按键抖动产生原因
  • 按键按下时,弹簧片与另一个引脚连通,不按下时不连通,
  • 因为其物理结构,会产生抖动
  • IO引脚会捕获这种抖动,从而对实验产生干扰

在这里插入图片描述

4.4.2 按键消抖方法

硬件电路时固定的,我们考虑用软件消抖方法。

在这里插入图片描述

由于抖动的时间不会超过10ms,所以我们可以等待10ms,直到按键电平稳定的时候,再去判断其电平状态

在这里插入图片描述

代码实现如下

  • 采集当前值和上一次值,如果当前值不等于上次的值
  • 那么,等待10ms
  • 再次采集当前值,如果当前值,还是不等于上次值
  • 那么执行对应的程序

在这里插入图片描述

#include "stm32f10x.h"
#include "stm32f10x_pal.h"

int main(void)
{
	uint8_t current = 1;
	uint8_t previous = 1;
	GPIO_InitTypeDef GPIOInitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//开启GPIOC时钟
	PAL_Init();
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_13;
	GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC,&GPIOInitStruct);//初始化GPIOC
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIOA时钟
	
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;//代码一行一行执行,所以直接给结构体变量直接赋值就行
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOA,&GPIOInitStruct);//初始化GPIOA 
	
	while(1)
	{
		previous = current ;
		current = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);//第一次读取
		if(current != previous)//第一次检测 不相等
		{
			PAL_Delay(10);//延时10ms
			current = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);//再次读取
			if(current != previous)//再次检测
			{
				if(current == 0)//按键按下
				{		
				}
				else
				{
					//切换灯的亮灭状态
					if( GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_13) == 0 )
					{
						GPIO_WriteBit(GPIOC,GPIO_Pin_13,1);
					}
					else
					{
						GPIO_WriteBit(GPIOC,GPIO_Pin_13,0);
					}
				}
			}
		
		}
	}
}

4.4.3 大佬的肩膀-PAL库按键消抖

大佬的库中,关于按键的函数有两条

在这里插入图片描述

使用方法:

在这里插入图片描述

使用方法详细介绍:

  • 引用头文件:#include “stm32f10x_pal_button.h”
  • 声明句柄:PalButton_HandleTypeDef hbutton1;//button1的句柄变量,(最好写主函数外面)
  • 填写按键初始化参数
    • 哪个引脚组
    • 哪个引脚
    • 外部上拉电阻 还是内部上拉电阻
    • 编写按键按下执行的功能函数,并将函数名,填写到句柄回调函数参数中
  • 调用初始化函数PAL_Button_Init( )
  • 在While中写执行函数PAL_Button_Proc( )

在这里插入图片描述

标准库和PAL库对比

在这里插入图片描述

代码:

#include "stm32f10x.h"
#include "stm32f10x_pal.h"
#include "stm32f10x_pal_button.h"

PalButton_HandleTypeDef hbutton1;//button1的句柄变量

static void OnButtonlRealeased(void)
{
	//对PC13亮灭切换
	if(GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_13) == 0)
	{
		GPIO_WriteBit(GPIOC,GPIO_Pin_13,1);
	}
	else
	{
		GPIO_WriteBit(GPIOC,GPIO_Pin_13,0);
	}

}

int main(void)
{
	GPIO_InitTypeDef GPIOinitStruct;
	
	PAL_Init();
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	
	GPIOinitStruct.GPIO_Pin  = GPIO_Pin_13;
	GPIOinitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIOinitStruct.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC,&GPIOinitStruct);
	
	//设置按键PA0 内部上拉
	hbutton1.Init.GPIOx = GPIOA;
	hbutton1.Init.GPIO_Pin = GPIO_Pin_0;
	hbutton1.Init.Button_Mode = Button_Mode_IPU;
	hbutton1.Init.ButtonReleasedCallback = OnButtonlRealeased;
	
	PAL_Button_Init(&hbutton1);
	
	while(1)
	{
		PAL_Button_Proc(&hbutton1);
	}
}

4.4.3 补充 句柄

句柄:

  • 编程=数据结构+算法
  • 如:描述人要有年龄,身高,性别(数据结构)+行为,走,跑,跳(算法)
  • 句柄就说一种数据结构,用来存储,表示这个实体的所有数据
  • 而函数,算法,是对句柄里的数据执行的某种操作

例子: 现在创建一个句柄,也就是描述一个茶壶的信息,
有总容积,当前水量

在这里插入图片描述

然后对这个茶壶进行三种操作

  • 创建一个10L的空茶壶:其实就是对茶壶这个数据结构进行操作

在这里插入图片描述

  • 向茶壶中注入水:其实就是对茶壶这个数据结构进行操作

在这里插入图片描述

  • 将茶壶中水倒出:其实就是对茶壶这个数据结构进行操作

在这里插入图片描述

4.4.3 补充 回调函数(HAL库编程也会用到)

什么是回调函数:
将我们定义的函数名称告诉给PAL库,这样PAL库将在适当的时机调用这个函数(自动调用,我搞不懂怎么调用的)

  • 但是用法是,将想要在按键松开时执行的程序,自己封装成一个自定义函数,然后把函数名传递给句柄中的一个参数

  • 例:我们将切换PC13亮灭状态的代码,封装成一个函数 void OnButtonlPressed()

  • 我们希望按键松开时执行这个函数,这样我们把我们定义的函数名,给到PAL库,也就是给到这个句柄中的一个参数

在这里插入图片描述

五、AFIO

5.1 AFIO简介

  • IO引脚可以进行复用,
  • IO复用,就说同一个IO引脚身兼数职,有多个功能
  • IO引脚直接被CPU控制–通用
  • IO引脚被片上外设进行控制–复用,同一个IO引脚复用功能有多个
  • 如下图,若我们想同时使用,片上外设1和片上外设2,那么引脚就冲突了,这是我们需要复用功能重映射来解决这个问题,也就是左图黄色的小框框,
  • 这个小框框,将某一个开关的引脚,重映射到别的位置,这个方式就说复用功能的重映射
  • AFIO也是一个片上外设
    在这里插入图片描述

在这里插入图片描述

5.2 IO复用功能重映射表

官方编程手册8.3小节
B站UP铁头山羊:2.5节 14:00
B站UP铁头山羊: 2.5AFIO

在这里插入图片描述

5.3 AFIO编程

标准库接口位置:和GPIO外设在一起在这里插入图片描述
有四个编程接口:
在这里插入图片描述
使用方法:
在这里插入图片描述
调用上图函数,第一参数填写要重映射外设功能的名称,开启重映射

如:

重映射外设USART1

在这里插入图片描述

重映射外设TIM1

在这里插入图片描述

  • 25
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好!对于STM32GPIO输出实验,点亮三色LED,您可以按照以下步骤进行操作: 1. 首先,您需要在STM32的开发环境中创建一个新的工程。 2. 在工程中,您需要包含相应的头文件,如"stm32f10x.h"。 3. 接下来,配置相应的引脚为输出模式。假设红色LED连接到GPIOA的Pin0引脚,绿色LED连接到GPIOA的Pin1引脚,蓝色LED连接到GPIOA的Pin2引脚,您可以使用以下代码进行配置: ``` GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置红色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置绿色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置蓝色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ``` 4. 现在,您可以使用相应的寄存器来控制LED的点亮和熄灭。例如,要点亮红色LED,可以使用以下代码: ``` GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置高,点亮红色LED ``` 要熄灭红色LED,可以使用以下代码: ``` GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置低,熄灭红色LED ``` 同样的方法,您可以控制绿色和蓝色LED的点亮和熄灭。 这就是点亮三色LED的基本步骤。希望对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值