STM32使用延时控制LED灯亮暗变换,LED呼吸灯效果

STM32F407ZE 使用延时控制LED灯亮暗变换,实现LED呼吸灯效果
具体代码如下:

main.c部分

#include <stm32f4xx.h> 
#include "sys.h"
#include "led.h"
#include "delay.h"
#include "tim.h"

int main()
{
    
    
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组  2分组
	
	LED_Init();										//LED灯初始化
	
	while(1)										//呼吸灯
	{
    
    
		int i=0;
        for(;i<100;i++)
        {
    
    
            delay(60);
            TIM_Init(i);
        }
        
        for(;i>0;i--)
        {
    
    
            delay(60);
            TIM_Init(i);
        }
	}
}

tim.h部分:

#ifndef __TIM_H_
#define __TIM_H_

#include <stm32f4xx.h>
#include "sys.h"
void TIM_Init(int light);
#endif

tim.c部分
#include "tim.h"

void TIM_Init(int light)
{
    
    
	TIM_TimeBaseInitTypeDef TIMInit_struct;
	NVIC_InitTypeDef  TIMNVIC_Struct;
	
	//0、使能TIM2时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
	
	//1、初始化定时器2模块
	TIMInit_struct.TIM_Prescaler = 840-1;					//84Mhz/840 = 100000Hz 0.01ms/脉冲
	TIMInit_struct.TIM_Period    = light;					//定时1s
	TIMInit_struct.TIM_CounterMode = TIM_CounterMode_Up;	//递增模式
	TIMInit_struct.TIM_ClockDivision = TIM_CKD_DIV1;		//不分频
	TIM_TimeBaseInit(TIM4,&TIMInit_struct);

    TIMInit_struct.TIM_Period    = 100-light;				//定时1s
    TIM_TimeBaseInit(TIM5,&TIMInit_struct);
    
   
    
	//2、开启定时器2的更新中断---确保定时一到能够通过中断机制报告给CPU
	//让CPU快速执行对应的功能
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
	TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);
    
    
	//3、NVIC中断管理
	TIMNVIC_Struct.NVIC_IRQChannel = TIM4_IRQn;//stm32f4xx.h
	TIMNVIC_Struct.NVIC_IRQChannelPreemptionPriority = 1;
	TIMNVIC_Struct.NVIC_IRQChannelSubPriority        = 0;
	TIMNVIC_Struct.NVIC_IRQChannelCmd   = ENABLE;
	NVIC_Init(&TIMNVIC_Struct);
	
    TIMNVIC_Struct.NVIC_IRQChannel = TIM5_IRQn;//stm32f4xx.h
    NVIC_Init(&TIMNVIC_Struct);
        
	//4、开启对应定时器的计数器----启动定时器
	TIM_Cmd(TIM4,ENABLE);
    TIM_Cmd(TIM5,ENABLE);
}

void TIM4_IRQHandler(void)
{
    
    
	//再次对相应的标志位进行判断
	if(TIM_GetITStatus(TIM4,TIM_IT_Update) == 1)
	{
    
    
		PFout(9) 	= 	1;
		PFout(10) 	= 	1;
        PEout(13) 	= 	1;
		PEout(14) 	= 	1;
		
		//清除指定的中断标志位  Update
		TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
	}
}
void TIM5_IRQHandler(void)
{
    
    
	//再次对相应的标志位进行判断
	if(TIM_GetITStatus(TIM5,TIM_IT_Update) == 1)
	{
    
    
		PFout(9) 	= 	0;
		PFout(10) 	= 	0;
        PEout(13) 	= 	0;
		PEout(14) 	= 	0;
		
		//清除指定的中断标志位  Update
		TIM_ClearITPendingBit(TIM5,TIM_IT_Update);
	}
}

sys.h

#ifndef __SYS_H
#define __SYS_H	 
#include "stm32f4xx.h" 

//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414 
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814 
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14 
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014 
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414    
#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14    
#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     

#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010 
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410 
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810 
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10 
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010 
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410 
#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810 
#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10 
#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010 
 
//STM32中  对寄存器的访问  是不能单独访问寄存器的单个bit  只能以32bit地址访问寄存器
//这些位为只写形式,只能在字(word)--4byte、半字2byte 或字节模式下访问 
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出 
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入

#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //输出 
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //输入


#endif

led.h部分

#ifndef _LED_H_
#define _LED_H_

#include <stm32f4xx.h>
#include "sys.h"

void LED_Init(void);

#endif

led.c部分

#include "led.h"


void LED_Init(void)
{
    
    
	GPIO_InitTypeDef LED;
	
	//1、先开启对应用到的模块时钟节拍
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);	//PE组时钟

	//2、可以初始化配置GPIO  F组的9号引脚
	LED.GPIO_Pin   = GPIO_Pin_9 | GPIO_Pin_10;
	LED.GPIO_Mode  = GPIO_Mode_OUT;							//输出模式
	LED.GPIO_Speed = GPIO_Fast_Speed;						//快速  点灯和引脚速度无关
	LED.GPIO_OType = GPIO_OType_PP;							//推挽输出
	LED.GPIO_PuPd  = GPIO_PuPd_UP;							//内部上拉
	GPIO_Init(GPIOF,&LED);
	
	
	LED.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14;
	GPIO_Init(GPIOE,&LED);
	
	//初始化完成  灭掉4盏灯
	PFout(9)  = 1;
	PFout(10) = 1;
	PEout(13) = 1;
	PEout(14) = 1;

}

delay.h部分

#ifndef _DELAY_H_
#define _DELAY_H_


void delay(int tim);

#endif

delay.c部分

#include "delay.h"

void delay(int tim)
{
    
    
	int i;
	while(tim--)
	{
    
    
		for(i =3840;i>0;i--);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43793181/article/details/109148477