型号:STM32F103ZE
按键部分原理图:主函数:
#include "bsp-led2.h"
#include "stm32f10x.h"
#include "key1.h"
#include "delay.h"
#include "sys.h"
int main(void)
{
vu8 key=0;
LED_GPIO_Config(); //LED端口初始化
KEY_GPIO_Config(); //初始化与按键连接的硬件接口
delay_init(); //初始化延迟函数
PBout(5)=0; //点亮LED0亮
PEout(5)=0; //点亮LED1亮
while(1)
{
key=KEY_Scan(0);
if(key==1)
{
PBout(5)=!PBout(5); //LED0翻转
PEout(5)=PEout(5); //LED1保持不变
}
else if(key==2)
{
PEout(5)=!PEout(5); //LED1翻转
PBout(5)=PBout(5); //LED0保持不变
}
else if(key==4)
{
PBout(5)=!PBout(5); //LED0翻转
PEout(5)=!PEout(5); //LED1翻转
}
else delay_ms(10);
}
}
key1.c
#include "stm32f10x.h"
#include "key1.h"
void KEY_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE端口
GPIO_InitStruct.GPIO_Pin = KEY0_GPIO_PIN|KEY1_GPIO_PIN; //KEY0 KEY1
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOE, &GPIO_InitStruct); //初始化GPIOE
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //KEY3
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化GPIOA
}
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按键按松开标志
if(mode)
key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0||KEY3==1))
{
key_up=0;
if(KEY0==0)
return 1;
else if(KEY1==0)
return 2;
else if(KEY3==1)
return 4;
}else if(KEY0==1&&KEY1==1&&KEY3==0)
key_up=1;
return 0;// 无按键按下
}
key1.h
#ifndef __KEY_H
#define __KEY_H
#include "stm32f10x.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//读取按键0
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//读取按键1
#define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)//读取按键2
#define KEY3 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP)
#define KEY0_GPIO_PIN GPIO_Pin_4 //连接到SCL时钟线的GPIO
#define KEY0_GPIO_PORT GPIOE //设置GIPO端口
#define KEY0_GPIO_CLK RCC_APB2Periph_GPIOE //设置GIPO端口
#define KEY1_GPIO_PIN GPIO_Pin_3 //连接到SCL时钟线的GPIO
#define KEY1_GPIO_PORT GPIOE //设置GIPO端口
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOE //设置GIPO端口
void KEY_GPIO_Config(void); //IO初始化
u8 KEY_Scan(u8); //按键扫描函数
#endif
其他
//延时函数
void delay_ms(u16 nms)
{
if(delay_osrunning&&delay_osintnesting==0) //如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度)
{
if(nms>=fac_ms) //延时的时间大于OS的最少时间周期
{
delay_ostimedly(nms/fac_ms); //OS延时
}
nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时
}
delay_us((u32)(nms*1000)); //普通方式延时
}
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
运行结果: