IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 单片机裸机实用组件--LED -> 正文阅读

[嵌入式]单片机裸机实用组件--LED

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)
{

}

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-12-15 18:27:31  更:2021-12-15 18:28:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 15:32:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码