江科大STM32(1):第一个外设GPIO
参考:STM32入门笔记分享(跟江科大老师学的,无偿分享,不用三连,已经更新完成!)_哔哩哔哩_bilibili
引脚电平0~3.3v,部分容忍5V,对输出而言,最大只能输出3.3V.
只要可以采用高低电平来控制的地方,都可以用GPIO来完成,如果控制的是功率比较大的设备,只需加入驱动电路即可。
1.GPIO通用输入输出口,可配置八种输入输出模式
输出模式下可控制端口输出高低电平,用以驱动LED,蜂鸣器,模拟通信协议通信时许(IIC,SPI)
输入模式下可读取端口的高低电平,读取按键输入,外界模块电平信号输入,ADC电压采集,模拟通信协议接收数据。
2.GPIO基本结构
所有GPIO都挂载在APB2总线上
寄存器是一段特殊的存储器,内核可以通过APB2总线对寄存器进行读写,以完成输出电平和读取电平的功能,但是只有低16位才有对应端口。
驱动器负责增大驱动能力
3.GPIO位结构
在推挽输出下,P-MOS和N-MOS均有效,数据寄存器为1时,上管导通,下管断开,输出接到VDD,输出高电平。反之同理,这种模式下高低电平均有较强的驱动能力,所以又称为强推输出模式。
在开漏输出模式下,P-MOS无效,数据寄存器为1时,下管断开,输出断开,高阻模式。
4.GPIO八种工作模式
浮空、上拉、下拉输入配置
模拟输入配置
使用ADC专业配置
输出配置
一个端口只能有一个输出,但可以有多个输入
复用功能配置
5.外设GPIO配置
6.LED闪烁实验
1 | /*利用库函数点灯1.首先是使能时钟2.配置端口模式3.设置端口的高低电平进行电灯void RCC-AHBPeriphClockCmd(Rcc_AHBPeriph,NewState);void RCC-APB2PeriphClockCmd(Rcc_APB2Periph,NewState);开启APB2外设时钟控制void RCC-APB1PeriphClockCmd(Rcc_APB1Periph,NewState);void GPIO_DeInit(GPIOX);被指定的GPIO外设会被复位void GPIO_AFIODeInit();复位AFIO外设void GPIO_Init(GPIOX,GPIO_InitStruct);用结构体参数来初始化GPIO口void GPIO_StructInit(GPIO_InitStruct);把结构体变量赋一个默认值*/ |

实验代码
1 #include "stm32f10x.h" // Device header 2 #include "Delay.h" 3 4 int main(void) 5 { 6 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 7 8 GPIO_InitTypeDef GPIO_InitStructure; 9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 11 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 12 GPIO_Init(GPIOA, &GPIO_InitStructure); 13 14 while (1) 15 { 16 GPIO_ResetBits(GPIOA, GPIO_Pin_0); 17 Delay_ms(500); 18 GPIO_SetBits(GPIOA, GPIO_Pin_0); 19 Delay_ms(500); 20 21 //GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET); 22 //Delay_ms(500); 23 //GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); 24 //Delay_ms(500); 25 26 //GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0); 27 //Delay_ms(500); 28 //GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1); 29 //Delay_ms(500); 30 } 31 }
7.LED流水灯
1 #include "stm32f10x.h" // Device header 2 #include "Delay.h" 3 4 int main(void) 5 { 6 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 7 8 GPIO_InitTypeDef GPIO_InitStructure; 9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; 11 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 12 GPIO_Init(GPIOA, &GPIO_InitStructure); 13 14 while (1) 15 { 16 GPIO_Write(GPIOA, ~0x0001); //0000 0000 0000 0001 17 Delay_ms(100); 18 GPIO_Write(GPIOA, ~0x0002); //0000 0000 0000 0010 19 Delay_ms(100); 20 GPIO_Write(GPIOA, ~0x0004); //0000 0000 0000 0100 21 Delay_ms(100); 22 GPIO_Write(GPIOA, ~0x0008); //0000 0000 0000 1000 23 Delay_ms(100); 24 GPIO_Write(GPIOA, ~0x0010); //0000 0000 0001 0000 25 Delay_ms(100); 26 GPIO_Write(GPIOA, ~0x0020); //0000 0000 0010 0000 27 Delay_ms(100); 28 GPIO_Write(GPIOA, ~0x0040); //0000 0000 0100 0000 29 Delay_ms(100); 30 GPIO_Write(GPIOA, ~0x0080); //0000 0000 1000 0000 31 Delay_ms(100); 32 } 33 }
8.蜂鸣器
1 #include "stm32f10x.h" // Device header 2 #include "Delay.h" 3 4 int main(void) 5 { 6 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 7 8 GPIO_InitTypeDef GPIO_InitStructure; 9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; 11 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 12 GPIO_Init(GPIOB, &GPIO_InitStructure); 13 14 while (1) 15 { 16 GPIO_ResetBits(GPIOB, GPIO_Pin_12); 17 Delay_ms(100); 18 GPIO_SetBits(GPIOB, GPIO_Pin_12); 19 Delay_ms(100); 20 GPIO_ResetBits(GPIOB, GPIO_Pin_12); 21 Delay_ms(100); 22 GPIO_SetBits(GPIOB, GPIO_Pin_12); 23 Delay_ms(700); 24 } 25 }
9、GPIO输入
按键控制LED
LED.c模块代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #include "stm32f10x.h" // Device header void LED_Init( void ) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2); } void LED1_ON( void ) { GPIO_ResetBits(GPIOA, GPIO_Pin_1); } void LED1_OFF( void ) { GPIO_SetBits(GPIOA, GPIO_Pin_1); } void LED1_Turn( void ) { if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0) { GPIO_SetBits(GPIOA, GPIO_Pin_1); } else { GPIO_ResetBits(GPIOA, GPIO_Pin_1); } } void LED2_ON( void ) { GPIO_ResetBits(GPIOA, GPIO_Pin_2); } void LED2_OFF( void ) { GPIO_SetBits(GPIOA, GPIO_Pin_2); } void LED2_Turn( void ) { if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0) { GPIO_SetBits(GPIOA, GPIO_Pin_2); } else { GPIO_ResetBits(GPIOA, GPIO_Pin_2); } } |
Key.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include "stm32f10x.h" // Device header #include "Delay.h" void Key_Init( void ) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } uint8_t Key_GetNum( void ) { uint8_t KeyNum = 0; if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { Delay_ms(20); while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); Delay_ms(20); KeyNum = 1; } if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0) { Delay_ms(20); while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0); Delay_ms(20); KeyNum = 2; } return KeyNum; } |
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include "stm32f10x.h" // Device header #include "Delay.h" #include "LED.h" #include "Key.h" uint8_t KeyNum; int main( void ) { LED_Init(); Key_Init(); while (1) { KeyNum = Key_GetNum(); if (KeyNum == 1) { LED1_Turn(); } if (KeyNum == 2) { LED2_Turn(); } } } |
光敏传感器控制有源蜂鸣器
当遮住光线时,输出指示灯灭,代表输出高电平
有光线时,输出指示灯亮,代表输出低电平
Buzzer.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include "stm32f10x.h" // Device header void Buzzer_Init( void ) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB, GPIO_Pin_12); } void Buzzer_ON( void ) { GPIO_ResetBits(GPIOB, GPIO_Pin_12); } void Buzzer_OFF( void ) { GPIO_SetBits(GPIOB, GPIO_Pin_12); } void Buzzer_Turn( void ) { if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_12) == 0) { GPIO_SetBits(GPIOB, GPIO_Pin_12); } else { GPIO_ResetBits(GPIOB, GPIO_Pin_12); } } |
LightSensor.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include "stm32f10x.h" // Device header void LightSensor_Init( void ) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } uint8_t LightSensor_Get( void ) { return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13); } |
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include "stm32f10x.h" // Device header #include "Delay.h" #include "Buzzer.h" #include "LightSensor.h" int main( void ) { Buzzer_Init(); LightSensor_Init(); while (1) { if (LightSensor_Get() == 1) { Buzzer_ON(); } else { Buzzer_OFF(); } } } |
GPIO使用方法
初始化需要的时钟,定义结构体引出参数并赋值
使用GPIO_Init()将指定的GPIO外设初始化好。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了