新闻中心

EEPW首页>嵌入式系统>设计应用> STM32F103实现LED灯、按键、定时器编程

STM32F103实现LED灯、按键、定时器编程

作者: 时间:2016-11-18 来源:网络 收藏
#include "delay.h"
#include "sys.h"
#include " LED.h"
#include "key.h"
#include "timer2.h"
/*
程序功能:KEY0按下时,LED0 每秒闪烁一下;同时LED1熄灭(LED0慢闪)。
KEY1按下时,LED1 每秒闪烁二下;同时LED0熄灭(LED0快闪)。
WAKE_UP按下,LED0、LED1都熄灭。
硬件:LED0----GPIOA.8
LED1----GPIOD.2
KEY0----GPIOC.5
KEY1----GPIOA.15
KEY_WAKEUP----GPIOA.0
TIMER2定时器功能。
软件:KEIL5
按键采用状态机实现按键扫描。在定时器中对按键进行处理。
时间:2016.8.9
*/
// 全局变量按键状态机 LED0灯闪烁频率 LED1灯闪烁频率
unsigned char flag_20ms=0x0,flag_500ms=0,flag_250ms=0;
// 按键KEY0按下标志 按键KEY1按下标志
unsigned char flag_key0=0,flag_key1=0;
int main(void)
{
Led_Init();// LED灯初始化
key_init();//KEY按键初始化
Timer2_config(71,2000); //定时两毫秒
while(1)
{
Led_Control(); //LED控制
}
}
#include "sys.h"
#include "delay.h"
#include "key.h"
extern unsigned char flag_20ms;
extern unsigned char flag_key0,flag_key1;
void key_init(void)
{
GPIO_InitTypeDef KEY_InitTypeDef;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC,ENABLE);
KEY_InitTypeDef.GPIO_Pin=GPIO_Pin_0;
KEY_InitTypeDef.GPIO_Mode=GPIO_Mode_IPD;
KEY_InitTypeDef.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&KEY_InitTypeDef);
KEY_InitTypeDef.GPIO_Pin=GPIO_Pin_5;
KEY_InitTypeDef.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOC,&KEY_InitTypeDef);
KEY_InitTypeDef.GPIO_Pin=GPIO_Pin_15;
KEY_InitTypeDef.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOA,&KEY_InitTypeDef);
KEY0=1;
KEY1=1;
WK_UP=0;
}
/*
函数功能:按键扫描函数
输入参数:无
输出参数:返回键码。无按键时返回0;
外部变量:
算法:采用软件延时实现按键扫描。
*/
unsigned char KeyScan(void)
{
unsigned char keynum=0;
if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
{
delay_ms(10);
if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
{
if(KEY0!=1)
{
while(KEY0!=1);
keynum=1;return keynum;}
else if(KEY1!=1)
{while(KEY1!=1);
keynum=2;return keynum;}
else if(WK_UP!=0)
{while(WK_UP!=0);
keynum=3;return keynum;}
else
return 0;
}
else
return keynum;
}
else
return keynum;
}
/*
函数功能:按键扫描函数
输入参数:无
输出参数:返回键码。无按键时返回0;
外部变量:flag_20ms
算法:采用状态机实现按键扫描。
*/
unsigned char KeyScan2(void)
{
static unsigned char keynum=0,step1=0;
if(flag_20ms==0x01)
{
flag_20ms=0;
switch(step1)
{
case 0:{//状态1:检测是否有按键按下
if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
step1=1;
else
step1=0;
return 0;
break;
}
case 1:{//状态2:检测是否真的有按键按下
if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
{
if(KEY0!=1)
{step1=2; keynum=1;}
else if(KEY1!=1)
{step1=2; keynum=2;}
else if(WK_UP!=0)
{step1=2; keynum=3;}
else
{step1=0; }
}
return 0;
break;
}
case 2:{//状态3:检测按键是否弹起
if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
{step1=2; return 0;}
else
{ step1=0;return keynum;}
break;
}
default :return 0;
}
}
return 0;
}
/*
函数功能:按键功能解析函数
输入参数:无
输入函数:KeyScan2();
输出参数:无
外部变量:flag_key0,flag_key1
*/
void keyfunction(void)
{
unsigned char temp;
temp=KeyScan2();
if(temp>0)
{
switch(temp)
{
case 1:{
flag_key0=1;
break;
}
case 2:{
flag_key1=1;
break;
}
case 3:{
flag_key0=0; flag_key1=0;
break;
}
}
}
}
#include "LED.h"
//位带操作 要用到SYS.H
//#define LED0 PAout(8)
//#define LED1 PDout(2)
//不知道为什么,把 Led_InitTypeDef定义成指针变量后,程序运行不成功。灯不亮。
extern unsigned char flag_20ms,flag_500ms,flag_250ms;
extern unsigned char flag_key0,flag_key1;
void Led_Init(void)
{
GPIO_InitTypeDef Led_InitTypeDef;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA,ENABLE);
Led_InitTypeDef.GPIO_Mode=GPIO_Mode_Out_PP;
Led_InitTypeDef.GPIO_Speed=GPIO_Speed_50MHz;
Led_InitTypeDef.GPIO_Pin=GPIO_Pin_8;
GPIO_Init(GPIOA,&Led_InitTypeDef);
Led_InitTypeDef.GPIO_Pin=GPIO_Pin_2;
GPIO_Init(GPIOD,&Led_InitTypeDef);
LED0=1;
LED1=1;
}
/*
函数功能:KEY0按下时,LED0 每秒闪烁一下。同时LED1熄灭。
KEY1按下时,LED1 每秒闪烁二下。同时LED0熄灭。
WAKE_UP按下,LED0、LED1都熄灭。
外部变量:flag_key0,flag_key1,flag_500ms,flag_250ms
输入参数:无
输出参数:无。
*/
void Led_Control(void)
{
if(flag_key0==1)
{
if(flag_500ms==1)
LED0=0;
else LED0=1;
}
else
LED0=1;
if(flag_key1==1)
{
if(flag_250ms==1)
LED1=0;
else LED1=1;
}
else
LED1=1;
}
#include "sys.h"
#include "stm32f10x_tim.h"
#include " led.h"
#include "timer2.h"
#include "key.h"
extern unsigned char flag_20ms,flag_500ms,flag_250ms;
void Timer2_config(unsigned int presc,unsigned int period)
{
TIM_TimeBaseInitTypeDef My_TIM2_Init;
NVIC_InitTypeDef My_NVIC_Init;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
My_TIM2_Init.TIM_Prescaler=presc;
My_TIM2_Init.TIM_Period=period;
My_TIM2_Init.TIM_ClockDivision=TIM_CKD_DIV1;
My_TIM2_Init.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&My_TIM2_Init);
My_NVIC_Init.NVIC_IRQChannel=TIM2_IRQn;
My_NVIC_Init.NVIC_IRQChannelCmd=ENABLE;
My_NVIC_Init.NVIC_IRQChannelPreemptionPriority=1;
My_NVIC_Init.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&My_NVIC_Init);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM2,ENABLE);
}
void TIM2_IRQHandler(void)
{
static unsigned char temp1,temp2,temp3;
if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
if(temp1++>=10)
{temp1=0;flag_20ms=0x01;
keyfunction();
}
if(temp2++>=250)
{ temp2=0;flag_500ms++;
if(flag_500ms>1) flag_500ms=0;}
if(temp3++>=125)
{ temp3=0;flag_250ms++;
if(flag_250ms>1)
flag_250ms=0;
}
}
}



评论


技术专区

关闭