目录
一、时钟使能的含义
1.为什么要时钟使能?
2.什么是时钟使能?
3.GPIO的使能信号?
二、代码封装
1.封装前完整代码
2.封装结构
封装后代码
led.c
led.h
key.c
key.h
main.c
每一个stm32单片机里都有着各种硬件设备,每一个设备对于频率的要求是不同的,有些设备要求频率低,有些设备要求频率高。如果为所有硬件设备设置同一频率,这就会出现性能不足或者资源浪费的情况,所以引入“时钟”这一概念,实现频率分配,即“分频”,“倍频”。需要低频和高频的设备使用相应的时钟使能函数(已经固定,需要查表或者查图获得),可以使用自己所需要的频率,实现资源的合理分配。
时钟是分频,使能是信号,是动作。所有时钟默认是disable,需要用哪个频率,调用相应的信号,设为enable。
时钟使能是用分频得到的信号作为模块的使能信号,模块原有的时钟不变。即用分频信号去控制模块的使能端口。
GPIO模块的使能信号是AHB1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
通过一系列的分频和倍频使得每一个模块有比较适配的频率,利用率高。分倍频原理如下:
在前面的开关控制灯的亮灭代码实现时, 有开关的五大参数设置和灯的五大参数设置等数十行代码在函数实现的前面,影响程序的可读性,所以要进行代码的封装,增强简洁性。
#include "stm32f4xx.h" // Device header
int main()
{
//时钟使能--LED
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
//GPIO时钟控制 //参数配置
//让程序决定第几组第几根引脚,如何工作
GPIO_InitTypeDef led_gpio;
led_gpio.GPIO_Mode = GPIO_Mode_OUT; //引脚以输出方式工作
led_gpio.GPIO_OType = GPIO_OType_PP; //推挽
led_gpio.GPIO_Pin = GPIO_Pin_9| GPIO_Pin_10 |GPIO_Pin_8;
led_gpio.GPIO_Speed=GPIO_High_Speed; //gpio的反应速率,不太影响
led_gpio.GPIO_PuPd=GPIO_PuPd_DOWN; //上拉 GPIO_PuPd_DOWN 下拉//GPIO_PuPd_NOPULL
GPIO_Init(GPIOF,&led_gpio);
GPIO_SetBits(GPIOF, GPIO_Pin_9);
GPIO_SetBits(GPIOF, GPIO_Pin_10);
uint16_t key0=0;
//时钟使能--KEY开关
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
//GPIO时钟控制 //参数配置
//让程序决定第几组第几根引脚,如何工作
GPIO_InitTypeDef key_gpio;
key_gpio.GPIO_Mode = GPIO_Mode_IN; //引脚以输入方式工作
key_gpio.GPIO_OType = GPIO_OType_PP; //推挽
key_gpio.GPIO_Pin = GPIO_Pin_4| GPIO_Pin_3 |GPIO_Pin_2;//第几根引脚
key_gpio.GPIO_Speed=GPIO_High_Speed; //gpio的反应速率,不太影响
key_gpio.GPIO_PuPd=GPIO_PuPd_UP; //上拉 GPIO_PuPd_DOWN 下拉//GPIO_PuPd_NOPULL
GPIO_Init(GPIOE,&key_gpio); //初始化
while(1)
{
//uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);
key0= GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4);//默认高电平,按下,接地
if(key0==1)
{
GPIO_WriteBit(GPIOF, GPIO_Pin_10,1);//led高电平,灯灭
}
else
{
GPIO_WriteBit(GPIOF, GPIO_Pin_10,0); //led高电平,灯亮
}
}
}
#include "stm32f4xx.h" // Device header
void Led_Init()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
GPIO_InitTypeDef gpio_init;
gpio_init.GPIO_Mode=GPIO_Mode_OUT;
gpio_init.GPIO_OType=GPIO_OType_OD;
gpio_init.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;
gpio_init.GPIO_PuPd=GPIO_PuPd_NOPULL;
gpio_init.GPIO_Speed=GPIO_High_Speed;
GPIO_Init(GPIOF,&gpio_init);
}
void Led_Init(void);//声明
#include "stm32f4xx.h" // Device header
void Key_Init()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
GPIO_InitTypeDef gpio_key;
gpio_key.GPIO_Mode=GPIO_Mode_IN;
gpio_key.GPIO_OType=GPIO_OType_OD;
gpio_key.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
gpio_key.GPIO_PuPd=GPIO_PuPd_UP;
gpio_key.GPIO_Speed=GPIO_High_Speed;
GPIO_Init(GPIOE,&gpio_key);
}
void Key_Init(void);
#include "stm32f4xx.h" // Device header
#include "led.h"
#include "key.h"
int main()
{
Led_Init();
Key_Init();
uint8_t key=0;
while(1)
{
key= GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4);//默认高电平,按下,接地
if(key0==1)
{
GPIO_WriteBit(GPIOF, GPIO_Pin_10,1); //led高电平,灯灭
}
else
{
GPIO_WriteBit(GPIOF, GPIO_Pin_10,0); //led低电平,灯亮
}
}
}
至此,main.c代码变简洁了不少,而且代码更加易读,代码层次也更清晰。