STM32控制4种灯质闪烁

上次做的STM32项目中要求实现4种灯的闪烁效果,并能控制闪烁模式的切换。实现4种灯的闪烁效果并不难,用很精确的延时函数配合高低电平控制就能实现了。控制端使用引脚输入控制,类似3-8译码器,三个输入即可控制8种闪烁效果。

4种灯质闪烁闪烁的规则如下图:

简单说就是要设定灯关闭、常亮、快闪、慢闪、亮灭时间不同闪和混合效果闪。难点在于控制。如果在一个函数中设定一个周期的灯闪烁循环,那么如果周期长的话,切换模式后也得等到周期执行完了才能进入下一种闪烁模式,于是自己写了一个以闪烁中最小周期为循环节的循环显示效果,这样发出控制命令后,能及时切换到其它模式。虽然也会延时最小变化周期,但是应该够用了,更精确的写法可以试试中断。本代码的优点就在于在于简洁易懂,无需其它配置。

代码中设定的输入控制信号为:PC1、PC2、PC3,输出的灯接PE5。定义的几种闪烁效果为:

丹顿光:亮3秒,灭1秒
等明暗光:亮、灭各2秒
连续快闪光:亮、灭各0.5秒
联甚块闪光:亮0.5秒,灭0.5秒,循环6次;亮2秒,灭2秒

PC1、PC2、PC3设定与对应模式:000灭、010常亮、100丹顿光Oc、101等明暗光Iso、110连续快闪光QFlash、111联甚快闪光VQLFI

代码如下:

#include "stm32f10x.h"

#define Delay_ms(msec) Delay_us(msec*1000)  //延时毫秒级

#define PC1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)   //读PC1

#define PC2 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)   //读PC2

#define PC3 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)   //读PC3



void LED_GPIO_Config(void) //配置LED用到的I/O口

{       

    GPIO_InitTypeDef GPIO_InitStructure; 

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOE, &GPIO_InitStructure);

    GPIO_ResetBits(GPIOE, GPIO_Pin_5);

}



   void Input_GPIO_Config(void)//输入I/O口配置

{

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; //

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //IPU;上拉、IPD下拉

    GPIO_Init(GPIOC, &GPIO_InitStructure);

}

 

void Delay_us(u32 ntimes)

{

    u32 flag;

    SysTick->LOAD=9*ntimes; 

    SysTick->VAL=0;

    SysTick->CTRL=0x00000001;

    do

    {

        flag=SysTick->CTRL;

    }

    while(flag&0x01&&!(flag&(1<<16)));

    SysTick->CTRL=0;

}



//丹顿光:亮3秒,灭1秒                                

//等明暗光:亮、灭各2秒                               

//连续快闪光:亮、灭各0.5秒                           

//联甚块闪光:亮0.5秒,灭0.5秒,循环6次;亮2秒,灭2秒 

//PC1 PC2 PC3

// 0   0   0  灭

// 0   1   0  常亮

// 1   0   0  丹顿光Oc

// 1   0   1  等明暗光Iso

// 1   1   0  连续快闪光QFlash

// 1   1   1  联甚快闪光VQLFI

//灯接的是PE5

void LED_FLASH_Simple(u8 l,u8 m,u8 s) //灯闪烁,l为亮的时间,m为灭的时间。s为亮灭模式切换

{

    u8 i;

    if(s==1) 

    {

        GPIO_SetBits(GPIOE , GPIO_Pin_5);

        for(i=0;i<l;i++) Delay_ms(500);

    }

    if(s==0)

    { 

        GPIO_ResetBits(GPIOE,GPIO_Pin_5);

        for(i=0;i<m;i++) Delay_ms(500);

    }

}



u8 s=1,j=0;

int main(void)

{

    LED_GPIO_Config();

    Input_GPIO_Config();

    while(1)

    {

      if(PC3==0 && PC1==0 )

      {

      GPIO_ResetBits(GPIOE,GPIO_Pin_5);

      j=0;

      }



      if(PC3==0 && PC1==1 )

      {

      GPIO_SetBits(GPIOE , GPIO_Pin_5);

      j=0;

      }



      if(PC3==1)

      {

      if(PC1==0 && PC2==0)  

      {

          j=0;

          LED_FLASH_Simple(6,2,s);

          if(s==1) s=0;

          else s=1;

      }

      if(PC1==0 && PC2==1)  

      {

          j=0;

          LED_FLASH_Simple(4,4,s);

          if(s==1) s=0;

          else s=1;

      }

      if(PC1==1 && PC2==0)  

      {

          j=0;

          LED_FLASH_Simple(1,1,s);

          if(s==1) s=0;

          else s=1;

      }

      if(PC1==1 && PC2==1)  

      {

          if(j<12)

          {

              LED_FLASH_Simple(1,1,s);

               if(s==1) s=0;

               else s=1;

              j++;

          }

          if(j==12) 

          {

              LED_FLASH_Simple(4,4,s);

              if(s==1) s=0;

              else s=1;

              j++;

          }

          if(j==13) 

          {

              LED_FLASH_Simple(4,4,s);

              if(s==1) s=0;

              else s=1;

              j=0;

          }

      }

      } 

      

    }

}