赞
踩
方法一:利用简单的延时实现
由于方法一不是重点的,因此只描述一下思路和它的大概代码。由于人眼的接收误差,我们可以使灯亮灭的时间不同,从而使我们人眼看到“呼吸”的灯。
- /* for循环中的参数根据实际情况而改变 */
- while(1)
- {
- for(i=0;i<5000;i++)//灭延时逐渐变长,亮延时逐渐变短,所以这里灯由亮->灭
- {
- GPIO_ResetBits(GPIOF,GPIO_Pin_7);//LED亮
- Delay(5000-i);
- GPIO_SetBits(GPIOF,GPIO_Pin_7);//LED灭
- Delay(i);
- }
- for(i=0;i<5000;i++)//亮延时逐渐变长,灭延时逐渐变短,所以这里灯由灭->亮
- {
- GPIO_ResetBits(GPIOF,GPIO_Pin_7);//LED亮
- Delay(i);
- GPIO_SetBits(GPIOF,GPIO_Pin_7);//LED灭
- Delay(5000-i);
- }
- }
方法二:使用PWM方波输出高低电平控制LED的亮灭
我们可以通过定时器输出PWM,通过改变其在一个周期内输出高低电平的时间不同进而灯的亮灭时间不同,使灯做到“呼吸”。
那么我们该如何选择定时器并对其进行初始化使其输出的PWM作用在我们LED的引脚上呢?方法一,随便选择一个可以输出PWM信号的定时器,利用杜邦线将输出的PWM信号的引脚与LED的引脚连接。方法二,不使用杜邦线,选择一个与LED共用引脚的定时器,那么只需要初始化定时器的相关引脚即可以使得LED进行亮灭。
如下原理图
可以看到,定时器10的通道一与红色LED共用引脚,因此我们在这里使用TIM10_CH1,让其输出PWM控制LED的亮灭。代码如下:
相关的宏定义
- /* 定时器 */
- #define ADVANCE_TIM TIM10
- #define ADVANCE_TIM_CLK RCC_APB2Periph_TIM10
-
- /* TIM10通道1输出引脚 */
- #define ADVANCE_OCPWM_PIN GPIO_Pin_6
- #define ADVANCE_OCPWM_GPIO_PORT GPIOF
- #define ADVANCE_OCPWM_GPIO_CLK RCC_AHB1Periph_GPIOF
- #define ADVANCE_OCPWM_PINSOURCE GPIO_PinSource6
- #define ADVANCE_OCPWM_AF GPIO_AF_TIM10
定时器的初始化
- static void TIMx_GPIO_Config(void)
- {
- /*定义一个GPIO_InitTypeDef类型的结构体*/
- GPIO_InitTypeDef GPIO_InitStructure;
-
- /* 开启GPIO外设时钟 */
- RCC_AHB1PeriphClockCmd(ADVANCE_OCPWM_GPIO_CLK,ENABLE);
-
- /* 开启复用功能 */
- GPIO_PinAFConfig(ADVANCE_OCPWM_GPIO_PORT,ADVANCE_OCPWM_PINSOURCE,ADVANCE_OCPWM_AF);
-
- /* 引脚初始化 */
- GPIO_InitStructure.GPIO_Pin = ADVANCE_OCPWM_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
- GPIO_InitStructure.GPIO_Speed = GPIO_Medium_Speed;//中速
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不上拉不下拉
-
- GPIO_Init(ADVANCE_OCPWM_GPIO_PORT, &GPIO_InitStructure);
- }
-
-
- static void TIM_Mode_Config(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_OCInitTypeDef TIM_OCInitStructure;
-
- RCC_APB2PeriphClockCmd(ADVANCE_TIM_CLK, ENABLE);
-
- //根据自己的需求配置
- TIM_TimeBaseStructure.TIM_Prescaler = 1680-1;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseStructure.TIM_Period = 500-1;
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
-
- TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);
-
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitStructure.TIM_Pulse = 0;//设置占空比
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//低电平有效(无所谓,只是决定着占空比该如何变化)
-
- //使能通道1
- TIM_OC1Init(ADVANCE_TIM, &TIM_OCInitStructure);
-
- /* 使能通道1重载 */
- TIM_OC1PreloadConfig(ADVANCE_TIM, TIM_OCPreload_Enable);
-
- // 使能定时器
- TIM_Cmd(ADVANCE_TIM, ENABLE);
-
- /* 主动输出使能 */
- TIM_CtrlPWMOutputs(ADVANCE_TIM, ENABLE);
- }
-
- void TIMx_Configuration(void)
- {
- TIMx_GPIO_Config();
-
- TIM_Mode_Config();
- }
主函数
- #include "stm32f4xx.h"
- #include "./pwm/pwm.h"
-
- void Delay(__IO uint32_t nCount) //简单的延时函数
- {
- for(nCount; nCount != 0; nCount--);
- }
-
-
- int main(void)
- {
- int i;
-
- TIMx_Configuration();//定时器初始化
-
- /* 控制LED灯 */
- while (1)
- {
- for(i=0;i<=500;i+=50)
- {
- TIM_SetCompare1(TIM10,i);//设置占空比
- Delay(0xfffff);//延时
- }
-
- for(i=500;i>=0;i-=50)
- {
- TIM_SetCompare1(TIM10,i);
- Delay(0xfffff);
- }
- }
- }
-
-
以上仅供自己与大家学习积累,欢迎各位大佬批评与指正!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。