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;} elsecurr = &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 __cplusplusextern "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相关推荐

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

    单片机裸机实用组件–软件定时器.时间戳 之前写过一篇关于单片机定时器延时计时功能的博客 ,刚工作的时候搞得现在看来还是比较糙的,是时候整一个新的了. base_timer 单片机裸机适用的定时器小组件 ...

  2. 工程师实战:单片机裸机程序框架是怎样炼成的?

    前言 前不久,我有位做测试的朋友转去做开发的工作,面试遇到了一个问题,他没明白,打电话问了我.题目大概就是: 在单片机裸机开发时,单片机要处理多个任务,此时你的程序框架是怎样的呢? 这其实是个经典面试 ...

  3. 单片机按键控制数码管c语言程序,基于单片机的按键控制LED数码管共阴极动态显示电路设计报告(毕业论文).doc...

    基于单片机的按键控制LED数码管共阴极动态显示电路设计报告(毕业论文) 物理与电子工程学院2014级课程设计 PAGE IV 物理与电子工程学院 <单片机原理与接口技术> 课程设计报告书 ...

  4. Python进阶_wxpy学习:实用组件

    目录: 目录: 前言 实用组件 聊天机器人 图灵 小 i 查找共同好友 忽略 ResponseError 异常 前言 学习完了python的基本概念和相应操作后,就要进入实战阶段了,首先选的是和微信端 ...

  5. Raspberry PI 系列 —— 裸机点亮LED灯

    Raspberry PI 系列 -- 裸机点亮LED灯 背景 近期刚买了Raspberry PI B+,配置执行了官方提供的Raspbian系统,折腾了一周Linux系统,感觉没啥意思,于是就试着想了 ...

  6. avr单片机led数码管六位动态显示时分秒c语言程序,AVR单片机控制8段LED数码管同时显示 - AVR单片机8位数码管显示的程序实现(两种方法介绍)...

    AVR单片机控制8段LED数码管同时显示 这是一个简单的供单片机入门学习者练习用的8段LED数码管控制汇编程序,控制一个两位的数码管同时显示字符(动态刷新).用AVR- Studio-4 开发,在AV ...

  7. STC15单片机 线性按键控制LED流水灯位移

    目录 1.现象 2.代码 3.LED模块原理图 4.线性键盘原理图 1.现象 程序下载完成后: 首先,由最右边的 LED1 点亮.当按下线性按键 S1 后,LED1 熄灭,LED2 点亮.其次,每按下 ...

  8. 【51单片机Task】:led十六进制控制led灯详解、按键控制流水灯、跑马灯等任务

    学习目标: 学习普中51单片机的按键控制led灯. 电路图:                      学习内容:         LED灯的十六进制怎么算???         在这给大家算一下:首 ...

  9. C51单片机之点亮LED灯

    文章目录 C51单片机之点亮LED灯 1. 了解普通发光二极管的参数,掌握限流电阻的计算方法. 2. 理解单片机最小系统,单片机外围电路,Flash,RAM 和 SFR 这些概念. 3. 了解 Kei ...

最新文章

  1. Android 自定义动画 LoadingView
  2. 用力和应变片计算弹性模量_一种沿深度非均匀分布的残余应力测试计算方法与流程...
  3. LeetCode 1457. 二叉树中的伪回文路径(位运算+递归)
  4. Java基础系列13:JDBC批处理简介
  5. 测试老司机一起聊聊性能测试是怎么一回事?
  6. 如何将ffmpeg在windows编译和使用
  7. [swift] LeetCode 62. Unique Paths
  8. 第一节:Scrapy开源框架初探
  9. java中的位操作系统_Java中的按位运算操作
  10. 初识计算机编程语言教案,完整版,初识VB教学设计
  11. CTF—攻防练习之HTTP—命令执行漏洞
  12. Linux中svn提交文件后自动同步更新到网站目录
  13. wps linux 64 下载,WPS For Linux 10.1.0.6757社区版发布下载
  14. 数据结构和算法(十三)排序算法
  15. kuangbin新模板错误
  16. windows ping 端口测试
  17. ads design environment_ADS射频仿真软件培训材料.pdf
  18. CGLIB 动态代理使用
  19. 数据库课程设计:图书信息管理系统(Java+MySQL)(附程序)
  20. CF 1606E Arena

热门文章

  1. HDU ACM 1046 Gridland 找规律
  2. 这是时间的推移 不是系统的分类
  3. S3C6410驱动I80接口LCD
  4. Pat乙级 1058 选择题
  5. DOM编程中,提高程序运行速度需要注意的一些点
  6. MHA 日常维护命令集
  7. SQL 基础之用户角色日常操作(十六)
  8. 会员系统中需要验证用户的邮箱是否真实存在
  9. 使用 Node.js、Express、AngularJS 和 MongoDB 构建一个Web程序
  10. bitmap文件格式分析