部分引脚可容忍5V,容忍5V的意思是:可以在这个端口输入5V的电压,也认为是高电平
但是对于输出而言,最大就只能输出3.3V,因为供电就只有3.3V
具体哪些端口能容忍5V,可以参考一下STM32的引脚定义
不带FT的,就只能接受3.3V的电压,这个我们在第一节也讲过
在STM32中,所有的GPIO都是挂载在APB2外设总线业的
st公司为了省电(低功耗),开发了一套时钟门控技术,必须启动时钟也就是RCC才能使用外设,所以无论使用stm32的任何外设,都需要先设置RCC时钟
每一个外设都接在了RCC时钟上,所以每一个外设在初始化时都要先初始化RCC时钟,比如
/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //开启DMA1的时钟
1、初始化GPIOA的RCC时钟,每个外设都需要先初始化RCC
2、初始化GPIOA,包括设置需要用到的引脚,设置其模式(输入输出)以及速度
LED灯闪烁
#include "stm32f10x.h" // Device header
#include "Delay.h"int main(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟//使用各个外设前必须开启时钟,否则对外设的操作无效/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //GPIO模式,赋值为推挽输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIO引脚,赋值为第0号引脚GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度,赋值为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //将赋值后的构体变量传递给GPIO_Init函数//函数内部会自动根据结构体的参数配置相应寄存器//实现GPIOA的初始化/*主循环,循环体内的代码会一直循环执行*/while (1){/*设置PA0引脚的高低电平,实现LED闪烁,下面展示3种方法*//*方法1:GPIO_ResetBits设置低电平,GPIO_SetBits设置高电平*/GPIO_ResetBits(GPIOA, GPIO_Pin_0); //将PA0引脚设置为低电平Delay_ms(500); //延时500msGPIO_SetBits(GPIOA, GPIO_Pin_0); //将PA0引脚设置为高电平Delay_ms(500); //延时500ms/*方法2:GPIO_WriteBit设置低/高电平,由Bit_RESET/Bit_SET指定*/GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET); //将PA0引脚设置为低电平Delay_ms(500); //延时500msGPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); //将PA0引脚设置为高电平Delay_ms(500); //延时500ms/*方法3:GPIO_WriteBit设置低/高电平,由数据0/1指定,数据需要强转为BitAction类型*/GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0); //将PA0引脚设置为低电平Delay_ms(500); //延时500msGPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1); //将PA0引脚设置为高电平Delay_ms(500); //延时500ms}
}
流水灯
#include "stm32f10x.h" // Device header
#include "Delay.h"int main(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟//使用各个外设前必须开启时钟,否则对外设的操作无效/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //GPIO模式,赋值为推挽输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //GPIO引脚,赋值为所有引脚/*另外一种方法*///GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度,赋值为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //将赋值后的构体变量传递给GPIO_Init函数//函数内部会自动根据结构体的参数配置相应寄存器//实现GPIOA的初始化/*主循环,循环体内的代码会一直循环执行*/while (1){/*使用GPIO_Write,同时设置GPIOA所有引脚的高低电平,实现LED流水灯*/GPIO_Write(GPIOA, ~0x0001); //0000 0000 0000 0001,PA0引脚为低电平,其他引脚均为高电平,注意数据有按位取反Delay_ms(100); //延时100msGPIO_Write(GPIOA, ~0x0002); //0000 0000 0000 0010,PA1引脚为低电平,其他引脚均为高电平Delay_ms(100); //延时100msGPIO_Write(GPIOA, ~0x0004); //0000 0000 0000 0100,PA2引脚为低电平,其他引脚均为高电平Delay_ms(100); //延时100msGPIO_Write(GPIOA, ~0x0008); //0000 0000 0000 1000,PA3引脚为低电平,其他引脚均为高电平Delay_ms(100); //延时100msGPIO_Write(GPIOA, ~0x0010); //0000 0000 0001 0000,PA4引脚为低电平,其他引脚均为高电平Delay_ms(100); //延时100msGPIO_Write(GPIOA, ~0x0020); //0000 0000 0010 0000,PA5引脚为低电平,其他引脚均为高电平Delay_ms(100); //延时100msGPIO_Write(GPIOA, ~0x0040); //0000 0000 0100 0000,PA6引脚为低电平,其他引脚均为高电平Delay_ms(100); //延时100msGPIO_Write(GPIOA, ~0x0080); //0000 0000 1000 0000,PA7引脚为低电平,其他引脚均为高电平Delay_ms(100); //延时100ms}
}
单片机C语言知识
GPIO输入之按键检测
分别是光敏电阻传感器、热敏电阻传感器、对射式红外传感器、反射式红外传感器
LED.c
将控制LED灯亮灭的操作写成库函数类,方便直接调用
#include "stm32f10x.h" // Device header/*** 函 数:LED初始化* 参 数:无* 返 回 值:无*/
void LED_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*GPIO初始化*/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); //将PA1和PA2引脚初始化为推挽输出/*设置GPIO初始化后的默认电平*/GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2); //设置PA1和PA2引脚为高电平
}/*** 函 数:LED1开启* 参 数:无* 返 回 值:无*/
void LED1_ON(void)
{GPIO_ResetBits(GPIOA, GPIO_Pin_1); //设置PA1引脚为低电平
}/*** 函 数:LED1关闭* 参 数:无* 返 回 值:无*/
void LED1_OFF(void)
{GPIO_SetBits(GPIOA, GPIO_Pin_1); //设置PA1引脚为高电平
}/*** 函 数:LED1状态翻转* 参 数:无* 返 回 值:无*/
void LED1_Turn(void)
{if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0) //获取输出寄存器的状态,如果当前引脚输出低电平{GPIO_SetBits(GPIOA, GPIO_Pin_1); //则设置PA1引脚为高电平}else //否则,即当前引脚输出高电平{GPIO_ResetBits(GPIOA, GPIO_Pin_1); //则设置PA1引脚为低电平}
}/*** 函 数:LED2开启* 参 数:无* 返 回 值:无*/
void LED2_ON(void)
{GPIO_ResetBits(GPIOA, GPIO_Pin_2); //设置PA2引脚为低电平
}/*** 函 数:LED2关闭* 参 数:无* 返 回 值:无*/
void LED2_OFF(void)
{GPIO_SetBits(GPIOA, GPIO_Pin_2); //设置PA2引脚为高电平
}/*** 函 数:LED2状态翻转* 参 数:无* 返 回 值:无*/
void LED2_Turn(void)
{if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0) //获取输出寄存器的状态,如果当前引脚输出低电平{ GPIO_SetBits(GPIOA, GPIO_Pin_2); //则设置PA2引脚为高电平} else //否则,即当前引脚输出高电平{ GPIO_ResetBits(GPIOA, GPIO_Pin_2); //则设置PA2引脚为低电平}
}
LED.h
#ifndef __LED_H
#define __LED_Hvoid LED_Init(void);
void LED1_ON(void);
void LED1_OFF(void);
void LED1_Turn(void);
void LED2_ON(void);
void LED2_OFF(void);
void LED2_Turn(void);#endif
按键检测函数
key.c
#include "stm32f10x.h" // Device header
#include "Delay.h"/*** 函 数:按键初始化* 参 数:无* 返 回 值:无*/
void Key_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟/*GPIO初始化*/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); //将PB1和PB11引脚初始化为上拉输入
}/*** 函 数:按键获取键码* 参 数:无* 返 回 值:按下按键的键码值,范围:0~2,返回0代表没有按键按下* 注意事项:此函数是阻塞式操作,当按键按住不放时,函数会卡住,直到按键松手*/
uint8_t Key_GetNum(void)
{uint8_t KeyNum = 0; //定义变量,默认键码值为0if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) //读PB1输入寄存器的状态,如果为0,则代表按键1按下{Delay_ms(20); //延时消抖while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); //等待按键松手Delay_ms(20); //延时消抖KeyNum = 1; //置键码为1}if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0) //读PB11输入寄存器的状态,如果为0,则代表按键2按下{Delay_ms(20); //延时消抖while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0); //等待按键松手Delay_ms(20); //延时消抖KeyNum = 2; //置键码为2}return KeyNum; //返回键码值,如果没有按键按下,所有if都不成立,则键码为默认值0
}
key.h
#ifndef __KEY_H
#define __KEY_Hvoid Key_Init(void);
uint8_t Key_GetNum(void);#endif
main.c,按键检测,然后控制LED灯的亮灭
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"uint8_t KeyNum; //定义用于接收按键键码的变量int main(void)
{/*模块初始化*/LED_Init(); //LED初始化Key_Init(); //按键初始化while (1){KeyNum = Key_GetNum(); //获取按键键码if (KeyNum == 1) //按键1按下{LED1_Turn(); //LED1翻转}if (KeyNum == 2) //按键2按下{LED2_Turn(); //LED2翻转}}
}