[STM32]

1. 指示灯模板

[复制链接]
910|9
手机看帖
扫描二维码
随时随地手机跟帖
jpy313|  楼主 | 2017-5-18 14:04 | 显示全部楼层 |阅读模式
本帖最后由 jpy313 于 2017-5-23 08:18 编辑

/*
**************************************************************************************************
*                                                                    深圳新元电子工作室
*                           
* 文    件:stm32_led.h
* 描    述:同一时刻同一颗LED只能运行一种模式
*           同一时刻运行多颗LED的不同模式
*           驱动LED的电平函数通过宏一次搞定 方便移植
*           通过滴答定时器1ms中断扫描来运行 设定后不需要while循环
* 版    本:V0.1(V0.0 版本更新到V0.1)
* 实验平台: 野火 iSO STM32 开发板
* 备    注:方便移植 通过修改“移植修改区”
* 编    辑:雨海
* 日    期:2017-03-15
***************************************************************************************************
*/

/*定义防止递归包含*/
#ifndef __STM32_LED_H
#define __STM32_LED_H

#include "stm32f10x.h"

/*移植可修改区=======================================================*/

#define LED_NUM     3u  /*LED数目*/
#define Active_Level 0  /*0:低电平打开LED  1:高电平打开LED*/

/*指示灯组合即指示灯ID*/
typedef enum
{
  LED_1   = 0,
  LED_2   = 1,
        LED_3   = 2,
} LED_ID;

/*LED硬件接口IO口定义*/
//LED1
#define LED_PinNum_1     0u
#define LED_Pin_1        GPIO_Pin_0
#define LED_Port_1       GPIOB
#define LED_Clock_1      RCC_APB2Periph_GPIOB
//LED2
#define LED_PinNum_2     7u
#define LED_Pin_2        GPIO_Pin_7
#define LED_Port_2       GPIOF
#define LED_Clock_2      RCC_APB2Periph_GPIOF
//LED3
#define LED_PinNum_3     8u
#define LED_Pin_3        GPIO_Pin_8
#define LED_Port_3       GPIOF
#define LED_Clock_3      RCC_APB2Periph_GPIOF

/*硬件输出接口引脚IO口电平定义*/
#define LED1_ON    if(Activl_Level) GPIO_SetBits(LED_Port_1,LED_Pin_1)   else GPIO_ResetBits(LED_Port_1, LED_Pin_1)
#define LED1_OFF   if(Activl_Level) GPIO_ResetBits(LED_Port_1,LED_Pin_1) else GPIO_SetBits(LED_Port_1, LED_Pin_1)
#define LED2_ON    if(Activl_Level) GPIO_SetBits(LED_Port_2,LED_Pin_2)   else GPIO_ResetBits(LED_Port_2, LED_Pin_2)
#define LED2_OFF   if(Activl_Level) GPIO_ResetBits(LED_Port_2,LED_Pin_2) else GPIO_SetBits(LED_Port_2, LED_Pin_2)
#define LED3_ON    if(Activl_Level) GPIO_SetBits(LED_Port_3, LED_Pin_3)  else GPIO_ResetBits(LED_Port_3, LED_Pin_3)
#define LED3_OFF   if(Activl_Level) GPIO_ResetBits(LED_Port_3,LED_Pin_3) else GPIO_SetBits(LED_Port_3, LED_Pin_3)


/*移植禁止修改区=======================================================*/

/*LED模式选择*/
#define LED_MODEL_ON     0  //常亮
#define LED_MODEL_OFF    1  //常灭
#define LED_MODEL_H      2  //高速闪烁
#define LED_MODEL_M      3  //中速闪烁
#define LED_MODEL_L      4  //低速闪烁

/*LED属性*/
typedef struct
{
   uint16_t ledOffDelay;      //LED灭延时
   uint16_t ledOnDelay;       //LED亮延时
         uint16_t ledWorkNum;       //LED闪烁次数 =oxff 无数次
         uint8_t  ledWorkState;     //LED工作状态 0常熄灭 1灯常亮  2灯闪烁
}  LED_typeDef;


/*对外函数应用接口*/
void LED_Init(void);
void LED_ON(LED_ID);
void LED_OFF(LED_ID);
void LED_Toggle(LED_ID);
void LED_Config(LED_ID Led,uint16_t offTime,uint16_t onTime,uint8_t num);
void LED_Model( LED_ID Led,uint8_t mode);
void LED_Scan(void);


#endif


/*
**************************************************************************************************
*                                                                    深圳新元电子工作室
*                        
* 文    件:stm32_led 模板
* 描    述:同一时刻同一颗LED只能运行一种模式
*           同一时刻运行多颗LED的不同模式
*           通过滴答定时器1ms中断扫描来运行 设定后不需要while循环 适合开发用
* 版    本:V0.1(V0.0 版本更新到V0.1)
* 实验平台: 野火 iSO STM32 开发板
* 备    注:方便移植 通过修改“移植修改区” 适合开发用
* 编    辑:雨海
* 日    期:2017-03-15
***************************************************************************************************
*/

#include "stm32_led.h"

/*移植可修改区=======================================================*/
GPIO_TypeDef*  GPIO_PORT[LED_NUM] = {LED_Port_1, LED_Port_2, LED_Port_3 };
const uint16_t GPIO_PIN[LED_NUM]  = {LED_Pin_1,  LED_Pin_2,  LED_Pin_3  };
const uint32_t GPIO_CLK[LED_NUM]  = {LED_Clock_1,LED_Clock_2,LED_Clock_3};


/*移植禁止修改区=======================================================*/

LED_typeDef    LED[LED_NUM]; /*定义LED_NUM个LED属性变量*/

/**
  * @brief  LED RCC GPIO初始化
  * @param  无
  * @retval 无
  */
void LED_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        
  uint8_t i;
        
        for(i=0;i<LED_NUM;i++)
        {
                RCC_APB2PeriphClockCmd(GPIO_CLK, ENABLE);
                GPIO_InitStructure.GPIO_Pin = GPIO_PIN;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                GPIO_Init(GPIO_PORT, &GPIO_InitStructure);                        
                LED_OFF((LED_ID)i);
        }
}

/**
  * @brief  关闭LED
  * @param  Led: 选择LED
  * @retval None
  */
void LED_OFF(LED_ID Led)
{
        if(Active_Level)
   GPIO_PORT[Led]->BRR = GPIO_PIN[Led];
  else
          GPIO_PORT[Led]->BSRR = GPIO_PIN[Led];        
}

/**
  * @brief  打开LED
  * @param  Led: 选择LED
  * @retval None
  */
void LED_ON(LED_ID Led)
{
        if(Active_Level)        
   GPIO_PORT[Led]->BSRR = GPIO_PIN[Led];
  else
    GPIO_PORT[Led]->BRR = GPIO_PIN[Led];         
}

/**
  * @brief  取反LED
  * @param  Led: 选择LED
  * @retval None
  */
void LED_Toggle(LED_ID Led)
{
  GPIO_PORT[Led]->ODR ^= GPIO_PIN[Led];
}

/**
  * @brief LED闪烁驱动参数初始化配置
  * @param Led: 选择LED
        * @param offTime LED熄灭延时时间 单位毫秒   
        * @param onTime  LED亮灯延时时间 单位毫秒   
        * @param num     LED开启次数  num = 0xff 无数次               
  * @retval 无
  * @NOTE  OffTime  onTime   状态
  *         0xff       --    常灭
  *         0x00     0xff    常亮         
  */
void LED_Config(LED_ID Led,uint16_t offTime,uint16_t onTime,uint8_t num)
{
        LED[Led].ledOffDelay = offTime;
        LED[Led].ledOnDelay  = onTime;
        LED[Led].ledWorkNum = num;    //0无数次数 非0 开启次数
}

/*led运行模式*/
void LED_Model(
              LED_ID Led,      //选择LED
              uint8_t mode     //运行模式选项
)
{
  if(mode==LED_MODEL_ON)
        {
                LED[Led].ledOnDelay  = 0xff;        
                LED[Led].ledOffDelay = 0x00;
                LED[Led].ledWorkNum  = 0xff;   
              LED[Led].ledWorkState =1;        
        }
        else if(mode==LED_MODEL_OFF)
  {
                LED[Led].ledOnDelay  = 0x00;        
                LED[Led].ledOffDelay = 0xFF;
                LED[Led].ledWorkNum  = 0xff;   
              LED[Led].ledWorkState =0;        
  }
        else if(mode==LED_MODEL_H)
        {
                LED[Led].ledOnDelay  = 100;        
                LED[Led].ledOffDelay = 100;
                LED[Led].ledWorkNum  = 0xff;   

               LED[Led].ledWorkState =2;        
        }
        else if(mode==LED_MODEL_M)
        {
                LED[Led].ledOnDelay  = 200;        
                LED[Led].ledOffDelay = 200;
                LED[Led].ledWorkNum  = 0xff;   

             LED[Led].ledWorkState =2;        
        }
        else if(mode==LED_MODEL_L)
        {
                LED[Led].ledOnDelay  = 300;        
                LED[Led].ledOffDelay = 300;
                LED[Led].ledWorkNum  = 0xff;   

               LED[Led].ledWorkState =2;        
       }

}


/*LED闪烁 用于扫描调用*/
static void LED_Flash(LED_ID ledName)
{        
        static uint16_t ledCount[LED_NUM]={0,0,0};
        static uint8_t  countFlag[LED_NUM]={0,0,0};
        static uint16_t ledTwinkleNum[LED_NUM]={0,0,0};

        ledCount[ledName]++;               
        if((countFlag[ledName]==0)&&(ledCount[ledName]>=LED[ledName].ledOffDelay)) //灯熄灭延时
        {
                countFlag[ledName]=1;
                ledCount[ledName]=0;
                LED_ON(ledName);
                if(LED[ledName].ledWorkNum!=0XFF)        //判断有无闪烁次数 0XFF无 其他表示次数
                {
                        ledTwinkleNum[ledName]++;
                        if(ledTwinkleNum[ledName]>=LED[ledName].ledWorkNum)
                        {
                          LED_OFF(ledName);
                        }
                }                        
        }
        if((countFlag[ledName]==1)&&(ledCount[ledName]>=LED[ledName].ledOnDelay)) //灯亮光延时
        {
                countFlag[ledName]=0;
                ledCount[ledName]=0;
                LED_OFF(ledName);
        }
}






/**
  * @brief  LED扫描 用于节拍扫描 中断调用
  * @param  无
  * @retval 无
  */
void LED_Scan(void)
{        
        uint8_t ledName;

        for(ledName=0; ledName<LED_NUM; ledName++)
        {

                 switch(LED[ledName].ledWorkState)
                 {
                         case 0: LED_OFF(ledName);   break;  //LED常灭
                         case 1: LED_ON(ledName);    break;  //LED常亮
                         case 2: LED_Flash(ledName); break;  //LED闪烁
                         default:break;
                 }
  }
}


/*************************END stm32_led.c********************************************/


/**
  * @brief 滴答定时器中断服务函数 中断间隔1ms
  *
  */
#include "stm32_led.h"
void SysTick_Handler(void)
{
  LED_Scan();        
}



  

相关帖子

dirtwillfly| | 2017-5-18 14:14 | 显示全部楼层
感谢分享

使用特权

评论回复
jpy313|  楼主 | 2017-5-18 15:03 | 显示全部楼层

使用特权

评论回复
青蓝pisces| | 2017-5-19 18:24 | 显示全部楼层
楼主想表达什么?

使用特权

评论回复
jpy313|  楼主 | 2017-5-19 18:53 | 显示全部楼层
分享

使用特权

评论回复
Prry| | 2017-5-20 23:58 | 显示全部楼层
再深入理解,写个简单的操作系统内核,多线程!

使用特权

评论回复
jpy313|  楼主 | 2017-5-22 08:30 | 显示全部楼层

使用特权

评论回复
阿航| | 2017-5-22 21:16 | 显示全部楼层
有创意~~~~~~

使用特权

评论回复
ihafd| | 2017-5-22 22:03 | 显示全部楼层
路过

使用特权

评论回复
jpy313|  楼主 | 2017-5-23 08:06 | 显示全部楼层
O(∩_∩)O谢谢你们关注

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

23

帖子

1

粉丝