IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> pwm,输入捕获,定时器中断混合操作led(基于stm32f4探索者) -> 正文阅读

[嵌入式]pwm,输入捕获,定时器中断混合操作led(基于stm32f4探索者)

所需要实现的功能

在这里插t入图片描述通过按键捕获,长按来切换三种模式(为了写程序的方便,直接朴取正点原子给出的输入捕获例程)在这里插入图片描述模式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


  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 10:57:40  更:2021-08-02 10:59:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 10:03:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计