LED头文件
#ifndef _LED_H
#define _LED_H
#include "sys.h"
//LED端口定义
#define LED0 PEout(3)
#define LED1 PEout(4)
void LED_Init(void); //初始化
#endif
LED初始化程序
#include "led.h"
//LED IO初始化
void LED_Init(void)
{
RCC->AHB1ENR|=1<<4;//使能PORTE时钟
GPIO_Set(GPIOE,PIN3|PIN4,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PE3,PE4设置
LED0=1;//蓝色,LED0关闭
LED1=1;//白色,LED1关闭
}
GPIO_Set()设置函数的实现
//GPIO通用设置
//GPIOx:GPIOA~GPIOI.
//BITx:0X0000~0XFFFF,位设置,每个位代表一个IO,第0位代表Px0,第1位代表Px1,依次类推.比如0X0101,代表同时设置Px0和Px8.
//MODE:0~3;模式选择,0,输入(系统复位默认状态);1,普通输出;2,复用功能;3,模拟输入.
//OTYPE:0/1;输出类型选择,0,推挽输出;1,开漏输出.
//OSPEED:0~3;输出速度设置,0,2Mhz;1,25Mhz;2,50Mhz;3,100Mhz.
//PUPD:0~3:上下拉设置,0,不带上下拉;1,上拉;2,下拉;3,保留.
//注意:在输入模式(普通输入/模拟输入)下,OTYPE和OSPEED参数无效!!
void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD)
{
u32 pinpos=0,pos=0,curpin=0;
for(pinpos=0;pinpos<16;pinpos++)
{
pos=1<<pinpos; //一个个位检查
curpin=BITx&pos;//检查引脚是否要设置
if(curpin==pos) //需要设置
{
GPIOx->MODER&=~(3<<(pinpos*2)); //先清除原来的设置
GPIOx->MODER|=MODE<<(pinpos*2); //设置新的模式
if((MODE==0X01)||(MODE==0X02)) //如果是输出模式/复用功能模式
{
GPIOx->OSPEEDR&=~(3<<(pinpos*2)); //清除原来的设置
GPIOx->OSPEEDR|=(OSPEED<<(pinpos*2));//设置新的速度值
GPIOx->OTYPER&=~(1<<pinpos) ; //清除原来的设置
GPIOx->OTYPER|=OTYPE<<pinpos; //设置新的输出模式
}
GPIOx->PUPDR&=~(3<<(pinpos*2)); //先清除原来的设置
GPIOx->PUPDR|=PUPD<<(pinpos*2); //设置新的上下拉
}
}
}
GPIO_Set()对应头文件部分代码
//GPIO设置专用宏定义
#define GPIO_MODE_IN 0 //普通输入模式
#define GPIO_MODE_OUT 1 //普通输出模式
#define GPIO_MODE_AF 2 //AF功能模式
#define GPIO_MODE_AIN 3 //模拟输入模式
#define GPIO_SPEED_2M 0 //GPIO速度2Mhz
#define GPIO_SPEED_25M 1 //GPIO速度25Mhz
#define GPIO_SPEED_50M 2 //GPIO速度50Mhz
#define GPIO_SPEED_100M 3 //GPIO速度100Mhz
#define GPIO_PUPD_NONE 0 //不带上下拉
#define GPIO_PUPD_PU 1 //上拉
#define GPIO_PUPD_PD 2 //下拉
#define GPIO_PUPD_RES 3 //保留
#define GPIO_OTYPE_PP 0 //推挽输出
#define GPIO_OTYPE_OD 1 //开漏输出
void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD);//GPIO设置函数
按键初始化代码
void KEY_Init(void)
{
RCC->AHB1ENR|=1<<1; //使能PORTB时钟
RCC->AHB1ENR|=1<<6; //使能PORTG时钟abcdefg
GPIO_Set(GPIOG,PIN13|PIN10|PIN15,GPIO_MODE_IN,0,0,GPIO_PUPD_PU);
GPIO_Set(GPIOB,PIN3,GPIO_MODE_IN,0,0,GPIO_PUPD_PU);
}
按键头文件代码
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY1 PGin(13) //PE4
#define KEY2 PGin(10) //PE3
#define KEY3 PGin(15) //P32
#define KEY4 PBin(3) //PA0
void KEY_Init(void); //IO初始化
u8 KEY_Scan(u8); //按键扫描函数
#endif
按键扫描函数实现
//实验测试使用,返回值确定是哪个按键按下
u8 KEY_Scan()
{
static u8 key_up=1;//按键按松开标志
if(key_up&&(KEY1==0||KEY2==0))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY1 == 0)
{
return '1'; //KEY_CONFIRE按下
}
else if(KEY2 == 0)
{
return '2'; //KEY_CANCLE按下
}
}else if(KEY1==1&&KEY2==1) key_up=1;
return '0';// 无按键按下
}
测试用main()函数
int main(void)
{
LED_Init(); //LED初始化
KEY_Init(); //按键初始化
while(1)
{
u8 key_flag = KEY_Scan('0');
if(key_flag == '1')
{
LED0 = 0;
}
else
{
LED0 = 1;
}
if(key_flag == '2')
{
LED1 = !LED1;
delay_ms(300); //预防松开按键太快,重新检测到,但是一直按着会闪烁
}
}
}