STM32
直播中

张旭

7年用户 995经验值
私信 关注
[问答]

如何利用STM32F407ZE去实现LED呼吸灯的效果呢

STM32F407ZE是怎样使用延时控制LED灯亮暗变换的?

如何利用STM32F407ZE去实现LED呼吸灯的效果呢?

回帖(1)

潘晓明

2021-12-15 11:39:57
STM32F407ZE 使用延时控制LED灯亮暗变换,实现LED呼吸灯效果
具体代码如下:
  main.c部分

#include
#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
#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
#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--);
        }
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分