单片机裸机实用组件--LED

Posted 不咸不要钱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机裸机实用组件--LED相关的知识,希望对你有一定的参考价值。

[easy_led](https://gitee.com/main_i/easy_led)

介绍

单片机常用led驱动,可以十分方便的控制led闪烁频率和闪烁持续时间

移植教程

  1. 将 easy_led.c easy_led.h easy_led_port.c 添加到工程中
  2. 打开 easy_led_port.c 文件,自行实现里面的函数, 里面的函数主要是为了实现临界区保护
  3. 周期性的调用 void eled_ticks(void); 函数

使用说明

  1. led IO硬件初始化
  2. 初始化LED驱动并设置led默认的闪烁状态,注意闪烁状态的单位为ticks 也就是 void eled_ticks(void); 函数的执行周期
void eled_init(eLED_T * uLed, ledControl_t ledControl, uint16_t ledOnDefaultTicks, uint16_t ledOffDefaultTicks);
  1. 根据需要设置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的主要内容,如果未能解决你的问题,请参考以下文章

单片机裸机实用组件--LED

单片机裸机实用组件--软件定时器时间戳

单片机裸机实用组件--软件定时器时间戳

单片机裸机实用组件--软件定时器时间戳

嵌入式裸机烧写LED

ARM裸机开发:C语言点亮LED