所需要实现的功能
通过按键捕获,长按来切换三种模式(为了写程序的方便,直接朴取正点原子给出的输入捕获例程)
模式2:通过短按来切换led1的相位,实现视觉上的延迟
模式3:led0闪烁作为计时器,通过短按切换led1的状态
模式1 默认状态为pwm占空比每次增大0.2,长按key0 pwm占空比每次减小0.2
//pwm模式中将会用到的变量
u16 terminal=300;//计数器的最大值
u16 led0pwmval=0;//递增模式下计数器的初始值
u16 key0pwmval=300;//递减模式下计数器的初始值
u8 dir=1;//计数方向
static int M=4;//记录还剩几个0.2
static int N=1;//记录增加了几个0.2
u16 key;//记录led0、led1、led2中是否有按键按下
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
LED_Init();
KEY_Init();
//逐渐递增模式下的呼吸灯 pwm:低电平有效 模式1
//逐渐变亮模式
if(key==0)//没有按键按下
{
if(led0pwmval<300)
{
delay_ms(10);
if(dir) //向上计数
led0pwmval++;//比较值增加
else
led0pwmval--;//比较值减少
if(led0pwmval>terminal*N*0.2)//比较值最大每次增加0.2
{
dir=0;//向下计数
N++;//增大0.2
}
if(led0pwmval==0)//比较值为0,周期结束,重新计数
dir=1;
TIM_SetCompare1(TIM14,led0pwmval);//计数器小于最大值, 低电平有效, led亮
}
else
TIM_SetCompare1(TIM14,0);//计数器超过最大值, 高电平无效 ,led0熄灭
}
```c
//逐渐递减模式下的呼吸灯 pwm:低电平有效 模式1
else //有按键按下
{
if(key0pwmval>0)//计数器的值大于0
{
delay_ms(10);
if(dir) //向下计数
key0pwmval--;//比较值减少
else //向上计数
key0pwmval++;//比较值增大
if(key0pwmval<terminal*M*0.2)//比较值最大每次减小0.2
{
dir=0;
M--;//减小0.2
}
if(key0pwmval>=300)
dir=1;//比较值达到300 重新计数、
TIM_SetCompare1(TIM14,key0pwmval);//计数器小于最大值,低电平有效,led亮
}
else
{
TIM_SetCompare1(TIM14,terminal);//计数器已经减小到0, 一直低电平led0亮
}
}
模式2 :通过短按来切换led1的相位,实现视觉上的延迟
//所需要的变量以及对相关定时器的初始化,这里并没有初始化所有需要用到的定时器和io,后面再做解答
long long temp=0; //按键捕获的时间
extern u8 K2;//切换相位
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
LED_Init();
KEY_Init();
TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1); //以1Mhz的频率计数 arr设置为最大,定时器溢出时间很长
//有短按键
if(temp>=100&&temp<=500)//捕获到短按键
{
temp=0;//按键捕获清零
if(++K2==4) //相位变换
K2=0;
}
//中断服务函数中
static u8 i=0;//记录led0到第几个相位
static u8 n=0;//记录led1到第几个相位
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
if(MODE==2)
{
if(i==1)//第一个相位
LED0=0; //亮 1s
if(i==2)
LED0=1; //灭 3s
if(n==K2)//相位与按键次数相同
LED1=0; //亮
if(n==K2+1)
LED1=1; //灭
//达到4秒重新开始计时
if(++i>4) i=0;
if(++n>4) n=0;
}
}
模式3:led0闪烁作为计时器,通过短按切换led1的状态
u8 K3;//记录按键次数,切换状态
if(temp>=100&&temp<=500)
{
temp=0;//按键捕获清零
K3++;//模式变换
if(K3>3)//按键超过3次,回到模式1
K3=1;
}
else//没有按键时清掉捕获的时间
{
temp=0;
}
//中断服务函数中
static u8 j=0;//记录有几个500ms
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
if(MODE==3)
{
++j;
LED0=!LED0;//led0每1s闪烁
//状态1 周期为2s
if(K3==1)
{
if(j==2) //每1s翻转
{
LED1=!LED1;
j=0;
}
}
//状态2
else if(K3==2)
{
if(j==3) //每1.5s翻转
{
LED1=!LED1;
j=0;
}
}
//状态 3
else if(K3==3)
{
if(j==1) //每0.5秒翻转
{
LED1=!LED1;
j=0;
}
}
//超过1500ms,重新计算
if(j>3)
j=0;
}
值得注意的是:
正点原子给出的代码中,按键扫描函数中对wk_up进行了初始化,而我们在输入捕获的函数中需要用到wk_up判断长按短按,所以在main函数中同时初始化key_init和tim5的话,按键将会冲突;另一方面led0在pwm模式和后面两个模式中都有用到,不能同时进行初始化,所以我们在进入该模式时对io口和定时器进行初始化
//while循环中
u8 IO_Switch=0; //管理灯的IO口切换
//为了避免每次循环都初始化,我们设置一个变量在重新进入该模式时才初始化
//mode1
if(IO_Switch==0)
{//只初始化一次,防止每次进来都初始化一次
IO_Switch=1;
// TIM14_GPIO_Init(); //改变IO口映射
TIM14_PWM_Init1(500-1,84-1); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
TIM_Cmd(TIM3,DISABLE);//关定时器3
}
//mode2
if(IO_Switch==1)
{
IO_Switch=2;
TIM_Cmd(TIM3,ENABLE);
TIM_Cmd(TIM14,DISABLE);
LED_Init(); //OI口重新映射
TIM3_Int_Init(10000-1,8400-1);//定时1s //84M/8400=1000hz的计数频率计数到1000,PWM频率为1000/1000=1hz
}
//mode3
if(IO_Switch==2)
{
IO_Switch=0;
TIM_SetCounter(TIM3,0); //设置计数值
TIM3_Int_Init(5000-1,8400-1); //定时1s //定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数5000次为500ms
}
相关代码有待完善 还请大佬指正
下面贴上源码
main
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "timer.h"
#include "key.h"
#include "pwm.h"
#include "stm32f4xx.h"
#include "usart.h"
extern u8 TIM5CH1_CAPTURE_STA; //输入捕获状态
extern u32 TIM5CH1_CAPTURE_VAL; //输入捕获值
u8 K2; //记录按键次数
u8 K3;
u8 MODE; //模式
int main(void)
{
//***********************模式1中的变量**************************
u16 terminal=300;
u16 key0pwmval=300;
u16 led0pwmval=0;
u8 dir=1;
u16 init=0;
static int M=4;
static int N=1;
u16 key;
//***********************模式1中的变量**************************
long long temp=0;
u8 IO_Switch=0; //管理灯的IO口切换
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200);//初始化串口波特率为115200
LED_Init();
KEY_Init();
K2=1;
K3=1;
MODE=1;
TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1); //以1Mhz的频率计数 arr设置为最大,定时器溢出时间很长
//TIM14_PWM_Init1(500-1,84-1); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
//TIM3_Int_Init(10000-1,8400-1);//定时1s //84M/8400=1000hz的计数频率计数到1000,PWM频率为1000/1000=1hz
while(1)
{
if(TIM5CH1_CAPTURE_STA&0X80) //成功捕获到了一次高电平
{
temp=TIM5CH1_CAPTURE_STA&0X3F;
temp*=0XFFFFFFFF; //溢出时间总和
temp+=TIM5CH1_CAPTURE_VAL; //得到总的高电平时间
temp=temp/1000; //us转换成ms
TIM5CH1_CAPTURE_STA=0; //开启下一次捕获
}
//长按更换模式
if(temp>500)
{
temp=0;
MODE++;
TIM_Cmd(TIM3,ENABLE);//模式2和3
TIM_Cmd(TIM14,DISABLE);
}
//长按键超过3次
if(MODE>3)
{
MODE=1;
TIM_Cmd(TIM14,ENABLE); //恢复模式1
TIM_Cmd(TIM3,DISABLE);
}
switch(MODE)
{
case 1://************************************模式1***************************
if(IO_Switch==0)
{//只初始化一次,防止每次进来都初始化一次
IO_Switch=1;
TIM14_PWM_Init1(500-1,84-1); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
TIM_Cmd(TIM3,DISABLE);//关定时器3
}
key=KEY_Scan(1);//支持连续扫描按键
//逐渐变亮模式
if(key==0)
{
if(led0pwmval<300)
{
delay_ms(10);
if(dir) //比较值增加
led0pwmval++;
else //比较值减少
led0pwmval--;
if(led0pwmval>terminal*N*0.2)//比较值最大每次增加0.2
{
dir=0;
N++;
}
if(led0pwmval==0)//比较值为0,周期结束,重新计数
dir=1;
TIM_SetCompare1(TIM14,led0pwmval);
}
else
TIM_SetCompare1(TIM14,0);
}
//逐渐变暗模式
else
{
if(key0pwmval>0)
{
delay_ms(10);
if(dir) key0pwmval--;//比较值减少
else key0pwmval++;//比较值增大
if(key0pwmval<terminal*M*0.2)//比较值最大每次减小0.2
{
dir=0;
M--;
}
if(key0pwmval>=300)
dir=1;//比较值达到300 重新计数、
TIM_SetCompare1(TIM14,key0pwmval);
}
else
{
TIM_SetCompare1(TIM14,terminal);
}
}
break;
case 2:/********************模式2********************************/
if(IO_Switch==1)
{
IO_Switch=2;
TIM_Cmd(TIM3,ENABLE);
TIM_Cmd(TIM14,DISABLE);
LED_Init(); //OI口重新映射
TIM3_Int_Init(10000-1,8400-1);//定时1s //84M/8400=1000hz的计数频率计数到1000,PWM频率为1000/1000=1hz
}
//有短按键
if(temp>=100&&temp<=500)
{
temp=0;//按键捕获清零
if(++K2==4) //相位变换
K2=0;
}
break;
case 3:/********************模式3********************************/
if(IO_Switch==2)
{
IO_Switch=0;
TIM_SetCounter(TIM3,0); //设置计数值
TIM3_Int_Init(5000-1,8400-1); //定时1s //定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数5000次为500ms
}
if(temp>=100&&temp<=500)
{
temp=0;//按键捕获清零
K3++;//模式变换
if(K3>3)
K3=1;
}
else//没有按键时清掉捕获的时间
{
temp=0;
}
break;
}
}
}
timer。c
#include "timer.h"
#include "led.h"
#include "delay.h"
//********************************定时器中断****************************************
//通用定时器3中断初始化
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3时钟
TIM_TimeBaseInitStructure.TIM_Period = arr; //自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
TIM_Cmd(TIM3,ENABLE); //使能定时器3
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
static u8 i=0;
static u8 n=0;
static u8 j=0;//记录有几个500ms
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
if(MODE==2)
{
if(i==1)
LED0=0; //亮 1s
if(i==2)
LED0=1; //灭 3s
if(n==K2)
LED1=0; //亮
if(n==K2+1)
LED1=1; //灭
//达到4秒重新开始计时
if(++i>4) i=0;
if(++n>4) n=0;
}
else if(MODE==3)
{
++j;
LED0=!LED0;//led0每1s闪烁
//状态1 周期为2s
if(K3==1)
{
if(j==2) //每1s翻转
{
LED1=!LED1;
j=0;
}
}
//状态2
else if(K3==2)
{
if(j==3) //每1.5s翻转
{
LED1=!LED1;
j=0;
}
}
//状态 3
else if(K3==3)
{
if(j==1) //每0.5秒翻转
{
LED1=!LED1;
j=0;
}
}
//按键超过3次清零
if(j>3)
j=0;
}
// else MODE==1??
// {
// n=0;
// }
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}
//**************************输入捕获*************************************
//**************************输入捕获*************************************
//**************************输入捕获*************************************
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{
TIM_ICInitTypeDef TIM5_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //TIM5时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0复用位定时器5
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
//初始化TIM5输入捕获参数
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
TIM_ICInit(TIM5, &TIM5_ICInitStructure);
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断
TIM_Cmd(TIM5,ENABLE ); //使能定时器5
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
}
//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.
//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)
u8 TIM5CH1_CAPTURE_STA=0; //输入捕获状态
u32 TIM5CH1_CAPTURE_VAL; //输入捕获值(TIM2/TIM5是32位)
//定时器5中断服务程序
void TIM5_IRQHandler(void)
{
if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)//溢出
{
if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获了一次
TIM5CH1_CAPTURE_VAL=0XFFFFFFFF;
}
else TIM5CH1_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
{
if(TIM5CH1_CAPTURE_STA&0X40) //捕获到一个下降沿
{
TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);//获取当前的捕获值.
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
}
else //还未开始,第一次捕获上升沿
{
TIM5CH1_CAPTURE_STA=0; //清空
TIM5CH1_CAPTURE_VAL=0;
TIM5CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
TIM_Cmd(TIM5,DISABLE ); //关闭定时器5
TIM_SetCounter(TIM5,0);
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
TIM_Cmd(TIM5,ENABLE ); //使能定时器5
}
}
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
}
pwm.c
#include "pwm.h"
#include "led.h"
#include "usart.h"
void TIM14_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9复用为定时器14
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能PORTF时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOF9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化PF9
}
//TIM14 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM14_PWM_Init1(u32 arr,u32 psc)
{
//此部分需手动修改IO口设置
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); //TIM14时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能PORTF时钟
TIM14_GPIO_Init();
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14
//初始化TIM14 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
TIM_OC1Init(TIM14, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM14OC1
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //使能TIM14在CCR1上的预装载寄存器
TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能
TIM_Cmd(TIM14, ENABLE); //使能TIM14
}
key.c
#include "key.h"
#include "delay.h"
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //KEY0 KEY1 KEY2对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_UP;//浮空
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
}
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按键按松开标志
if(mode)key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0||KEY2==0))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)return 1;
else if(KEY1==0)return 2;
else if(KEY2==0)return 3;
//else if(WK_UP==1)return 4;
}
else if(KEY0==1&&KEY1==1&&KEY2==1)
key_up=1;
return 0;// 无按键按下
}
led.c
#include "led.h"
//初始化PF9和PF10为输出口.并使能这两个口的时钟
//LED IO初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
//GPIOF9,F10初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化
GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);//GPIOF9,F10设置高,灯灭
}
timer.h
#ifndef _TIMER_H
#define _TIMER_H
#include "sys.h"
void TIM3_Int_Init(u16 arr,u16 psc);
void TIM5_CH1_Cap_Init(u32 arr,u16 psc);
extern u8 K2;
extern u8 K3;
//extern u8 n;//记录有几个500ms
extern u8 MODE;
#endif
key.h
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
/*下面的方式是通过直接操作库函数方式读取IO*/
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) //PE4
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) //PE3
#define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) //PE2
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //PA0
#define KEY0_PRES 1
#define KEY1_PRES 2
#define KEY2_PRES 3
#define WKUP_PRES 4
void KEY_Init(void); //IO初始化
u8 KEY_Scan(u8); //按键扫描函数
#endif
led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
//LED端口定义
#define LED0 PFout(9) // DS0
#define LED1 PFout(10) // DS1
void LED_Init(void);//初始化
#endif
pwm.h
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
//arr:自动装载值
//psc:时钟预分频系数
void TIM14_GPIO_Init(void);
void TIM14_PWM_Init1(u32 arr,u32 psc);
void TIM14_PWM_Init2(u32 arr,u32 psc);
#endif
timer.h
#ifndef _TIMER_H
#define _TIMER_H
#include "sys.h"
void TIM3_Int_Init(u16 arr,u16 psc);
void TIM5_CH1_Cap_Init(u32 arr,u16 psc);
extern u8 K2;
extern u8 K3;
//extern u8 n;//记录有几个500ms
extern u8 MODE;
#endif