新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > STM32F103實現(xiàn)LED燈、按鍵、定時器編程

STM32F103實現(xiàn)LED燈、按鍵、定時器編程

作者: 時間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
#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
按鍵采用狀態(tài)機實現(xiàn)按鍵掃描。在定時器中對按鍵進行處理。
時間:2016.8.9
*/
//全局變量 按鍵狀態(tài)機 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;
}
/*
函數(shù)功能:按鍵掃描函數(shù)
輸入?yún)?shù):無
輸出參數(shù):返回鍵碼。無按鍵時返回0;
外部變量:
算法:采用軟件延時實現(xiàn)按鍵掃描。
*/
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;
}
/*
函數(shù)功能:按鍵掃描函數(shù)
輸入?yún)?shù):無
輸出參數(shù):返回鍵碼。無按鍵時返回0;
外部變量:flag_20ms
算法:采用狀態(tài)機實現(xiàn)按鍵掃描。
*/
unsigned char KeyScan2(void)
{
static unsigned char keynum=0,step1=0;
if(flag_20ms==0x01)
{
flag_20ms=0;
switch(step1)
{
case 0:{//狀態(tài)1:檢測是否有按鍵按下
if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
step1=1;
else
step1=0;
return 0;
break;
}
case 1:{//狀態(tài)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:{//狀態(tài)3:檢測按鍵是否彈起
if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
{step1=2; return 0;}
else
{ step1=0;return keynum;}
break;
}
default :return 0;
}
}
return 0;
}
/*
函數(shù)功能:按鍵功能解析函數(shù)
輸入?yún)?shù):無
輸入函數(shù):KeyScan2();
輸出參數(shù):無
外部變量: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;
}
/*
函數(shù)功能:KEY0按下時,LED0 每秒閃爍一下。同時LED1熄滅。
KEY1按下時,LED1 每秒閃爍二下。同時LED0熄滅。
WAKE_UP按下,LED0、LED1都熄滅。
外部變量:flag_key0,flag_key1,flag_500ms,flag_250ms
輸入?yún)?shù):無
輸出參數(shù):無。
*/
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;
}
}
}



評論


技術(shù)專區(qū)

關(guān)閉