本帖最后由 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();
}
|