单片机裸机实用组件--LED
Posted 不咸不要钱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机裸机实用组件--LED相关的知识,希望对你有一定的参考价值。
[easy_led](https://gitee.com/main_i/easy_led)
介绍
单片机常用led驱动,可以十分方便的控制led闪烁频率和闪烁持续时间
移植教程
- 将 easy_led.c easy_led.h easy_led_port.c 添加到工程中
- 打开 easy_led_port.c 文件,自行实现里面的函数, 里面的函数主要是为了实现临界区保护
- 周期性的调用 void eled_ticks(void); 函数
使用说明
- led IO硬件初始化
- 初始化LED驱动并设置led默认的闪烁状态,注意闪烁状态的单位为ticks 也就是 void eled_ticks(void); 函数的执行周期
void eled_init(eLED_T * uLed, ledControl_t ledControl, uint16_t ledOnDefaultTicks, uint16_t ledOffDefaultTicks);
- 根据需要设置LED闪烁周期和持续时间,当持续时间结束后,LED会自动恢复到初始化时设置的默认闪烁状态
void eled_set(eLED_T * uLed, uint16_t ledOnTicks, uint16_t ledOffTicks, uint16_t keepTicks);
使用例子
eLED_T g_eled1, g_eled2, g_eled3, g_eled4;
/* LED IO控制函数 */
void eled1_control(uint8_t level)
//HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, (GPIO_PinState)level);
void eled2_control(uint8_t level)
//HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, (GPIO_PinState)level);
void eled3_control(uint8_t level)
//HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, (GPIO_PinState)level);
void eled4_control(uint8_t level)
//HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, (GPIO_PinState)level);
int main(void)
/* 设置led1 默认状态 90 个周期亮 10个周期灭 */
eled_init(&g_eled1, eled1_control, 90, 10);
eled_init(&g_eled2, eled2_control, 100, 100);
eled_init(&g_eled3, eled3_control, 10, 10);
eled_init(&g_eled4, eled4_control, 50, 50);
/* 设置led4 状态 10 个周期亮 10个周期灭 持续500个周期 */
eled_set(&g_eled4, 10, 10, 500);
eled_set(&g_eled3, 10, 90, 500);
while (1)
delay_ms(10);
/* 10ms 调用一次 也可以放在中断中 */
eled_ticks();
easy_led.c
/**
* @file easy_led.c
* @author 不咸不要钱 (main_2018@163.com)
* @brief led驱动文件
* @version 0.1
* @date 2021-11-24
*
* @copyright Copyright (c) 2019
*
*/
#include "easy_led.h"
/** 指向led驱动链表头节点 */
static eLED_T * s_ledHead = 0;
extern void eled_port_init(void);
extern void eled_port_lock(void);
extern void eled_port_unlock(void);
/*!
* @brief led翻转处理
*
* @param eLed :led对象
* @param onTicks :一个闪烁周期中亮的节拍数
* @param offTicks:一个闪烁周期中暗的节拍数
*
* @return 无
*
* @note 内部调用
*
* @see
*/
static void eled_handler(eLED_T * eLed, uint16_t onTicks, uint16_t offTicks)
if(1 == eLed->ulTicks)
if(1 >= onTicks)
/* 默认led不亮 */
eLed->ledControl(0);
else
eLed->ledControl(1);
else if(eLed->ulTicks >= onTicks)
eLed->ledControl(0);
if(eLed->ulTicks >= offTicks)
eLed->ulTicks = 0;
/*!
* @brief led初始化
*
* @param eLed :led对象
* @param ledControl :指向led控制函数(该函数有一个参数 参数为0时 LED 亮)
* @param ledOnDefaultTicks :默认状态闪烁时 led点亮的节拍数
* @param ledOffDefaultTicks:默认状态闪烁时 led关闭的节拍数
*
* @return 无
*
* @note
*
* @see
*/
void eled_init(eLED_T * eLed, ledControl_t ledControl, uint16_t ledOnDefaultTicks, uint16_t ledOffDefaultTicks)
if(0 == s_ledHead)
eled_port_init();
eled_port_lock();
eLed->ulTicks = 0;
eLed->ulLedOnDefaultTicks = ledOnDefaultTicks + 1;
eLed->ulLedOffDefaultTicks= ledOnDefaultTicks + ledOffDefaultTicks;
eLed->ulLedOnTicks = 0;
eLed->ulLedOffTicks = 0;
eLed->ulKeepTicks = 0;
eLed->ledControl = ledControl;
/* 防止重复初始化 */
eLED_T * node = s_ledHead;
while(node)
if(node == eLed)
eled_port_unlock();
return;
else
node = node->ptNextLed;
eLed->ptNextLed = s_ledHead;
s_ledHead = eLed;
eled_port_unlock();
/*!
* @brief led状态设置
*
* @param eLed : led对象
* @param ledOnTicks : 一个闪烁周期 led点亮的节拍数
* @param ledOffTicks: 一个闪烁周期 led关闭的节拍数
* @param keepTicks : led闪烁持续时间 为0xFFFF时 永久持续
*
* @return 无
*
* @note 当闪烁持续时间结束后 会按初始化时设置的默认状态进行闪烁
*
* @see
*/
void eled_set(eLED_T * eLed, uint16_t ledOnTicks, uint16_t ledOffTicks, uint16_t keepTicks)
eled_port_lock();
eLed->ulTicks = 0;
eLed->ulLedOnTicks = ledOnTicks + 1;
eLed->ulLedOffTicks = ledOnTicks + ledOffTicks;
eLed->ulKeepTicks = keepTicks;
eled_port_unlock();
/*!
* @brief led默认状态设置
*
* @param eLed : led对象
* @param ledOnDefaultTicks :默认状态闪烁时 led点亮的节拍数
* @param ledOffDefaultTicks:默认状态闪烁时 led关闭的节拍数
*
* @return 无
*
* @note 当闪烁持续时间结束后 会按初始化时设置的默认状态进行闪烁
*
* @see
*/
void eled_set_default(eLED_T * eLed, uint16_t ledOnDefaultTicks, uint16_t ledOffDefaultTicks)
eled_port_lock();
eLed->ulLedOnDefaultTicks = ledOnDefaultTicks + 1;
eLed->ulLedOffDefaultTicks= ledOnDefaultTicks + ledOffDefaultTicks;
eled_port_unlock();
/*!
* @brief led停止闪烁
*
* @param eLed : led对象
*
* @return 无
*
* @note 将该led从链表移除
*
* @see
*/
void eled_stop(eLED_T * eLed)
eLED_T** curr;
for(curr = &s_ledHead; *curr; )
eLED_T* entry = *curr;
if (entry == eLed)
eled_port_lock();
*curr = entry->ptNextLed;
eled_port_unlock();
return;
else
curr = &entry->ptNextLed;
/*!
* @brief led 节拍处理
*
* @param 无
*
* @return 无
*
* @note 需要周期性执行 闪烁时间设置均以该周期为单位
*
* @see
*/
void eled_ticks(void)
eLED_T * target = s_ledHead;
eled_port_lock();
while(target)
if(target->ulTicks == TICKS_MAX)
target->ulTicks = 0;
target->ulTicks ++;
if(0 == target->ulKeepTicks)
eled_handler(target, target->ulLedOnDefaultTicks, target->ulLedOffDefaultTicks);
else
eled_handler(target, target->ulLedOnTicks, target->ulLedOffTicks);
target->ulKeepTicks --;
target = target->ptNextLed;
eled_port_unlock();
easy_led.h
/**
* @file easy_led.h
* @author 不咸不要钱 (main_2018@163.com)
* @brief led驱动头文件
* @version 0.1
* @date 2021-11-24
*
* @copyright Copyright (c) 2019
*
*/
#ifndef __EASY_LED_H
#define __EASY_LED_H
#include <stdint.h>
#ifdef __cplusplus
extern "C"
#endif
/*! 时钟节拍最大值 uint16_t 0xFFFF */
#define TICKS_MAX (0xFFFF)
/*! 函数指针 指向led控制函数(该函数有一个参数 参数为0时 LED 亮) */
typedef void (*ledControl_t)(uint8_t);
/**
* @brief uLED结构体
* @note 无
*/
typedef struct eLED
uint16_t ulTicks; /*!< 时钟节拍 */
uint16_t ulLedOnDefaultTicks; /*!< 默认状态闪烁时 led点亮的节拍数 */
uint16_t ulLedOffDefaultTicks; /*!< 默认状态闪烁时 led关闭的节拍数 */
uint16_t ulLedOnTicks; /*!< 使用uLedSet函数后 led闪烁时点亮的节拍数 */
uint16_t ulLedOffTicks; /*!< 使用uLedSet函数后 led闪烁时关闭的节拍数 */
uint16_t ulKeepTicks; /*!< 使用uLedSet函数后 led闪烁持续时间 */
ledControl_t ledControl; /*!< 指向led控制函数 */
struct eLED * ptNextLed; /*!< 指向下一个led对象 */
eLED_T;
void eled_init(eLED_T * uLed, ledControl_t ledControl, uint16_t ledOnDefaultTicks, uint16_t ledOffDefaultTicks);
void eled_set(eLED_T * uLed, uint16_t ledOnTicks, uint16_t ledOffTicks, uint16_t keepTicks);
void eled_set_default(eLED_T * eLed, uint16_t ledOnDefaultTicks, uint16_t ledOffDefaultTicks);
void eled_stop(eLED_T * eLed);
void eled_ticks(void);
#ifdef __cplusplus
#endif
#endif
easy_led_port.c
/**
* @file easy_led_port.c
* @author 不咸不要钱 (main_2018@163.com)
* @brief led驱动移植接口文件
* @version 0.1
* @date 2021-11-24
*
* @copyright Copyright (c) 2019
*
*/
#include "easy_led.h"
/*!
* @brief led 接口文件初始化
*
* @param
*
* @return 无
*
* @note
*
* @see
*/
void eled_port_init(void)
/*!
* @brief led 加锁
*
* @param
*
* @return 无
*
* @note
*
* @see
*/
void eled_port_lock(void)
/*!
* @brief led 开锁
*
* @param 无
*
* @return 无
*
* @note
*
* @see
*/
void eled_port_unlock(void)
以上是关于单片机裸机实用组件--LED的主要内容,如果未能解决你的问题,请参考以下文章