单片机裸机实用组件--LED
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;} 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相关推荐
- 单片机裸机实用组件--软件定时器、时间戳
单片机裸机实用组件–软件定时器.时间戳 之前写过一篇关于单片机定时器延时计时功能的博客 ,刚工作的时候搞得现在看来还是比较糙的,是时候整一个新的了. base_timer 单片机裸机适用的定时器小组件 ...
- 工程师实战:单片机裸机程序框架是怎样炼成的?
前言 前不久,我有位做测试的朋友转去做开发的工作,面试遇到了一个问题,他没明白,打电话问了我.题目大概就是: 在单片机裸机开发时,单片机要处理多个任务,此时你的程序框架是怎样的呢? 这其实是个经典面试 ...
- 单片机按键控制数码管c语言程序,基于单片机的按键控制LED数码管共阴极动态显示电路设计报告(毕业论文).doc...
基于单片机的按键控制LED数码管共阴极动态显示电路设计报告(毕业论文) 物理与电子工程学院2014级课程设计 PAGE IV 物理与电子工程学院 <单片机原理与接口技术> 课程设计报告书 ...
- Python进阶_wxpy学习:实用组件
目录: 目录: 前言 实用组件 聊天机器人 图灵 小 i 查找共同好友 忽略 ResponseError 异常 前言 学习完了python的基本概念和相应操作后,就要进入实战阶段了,首先选的是和微信端 ...
- Raspberry PI 系列 —— 裸机点亮LED灯
Raspberry PI 系列 -- 裸机点亮LED灯 背景 近期刚买了Raspberry PI B+,配置执行了官方提供的Raspbian系统,折腾了一周Linux系统,感觉没啥意思,于是就试着想了 ...
- avr单片机led数码管六位动态显示时分秒c语言程序,AVR单片机控制8段LED数码管同时显示 - AVR单片机8位数码管显示的程序实现(两种方法介绍)...
AVR单片机控制8段LED数码管同时显示 这是一个简单的供单片机入门学习者练习用的8段LED数码管控制汇编程序,控制一个两位的数码管同时显示字符(动态刷新).用AVR- Studio-4 开发,在AV ...
- STC15单片机 线性按键控制LED流水灯位移
目录 1.现象 2.代码 3.LED模块原理图 4.线性键盘原理图 1.现象 程序下载完成后: 首先,由最右边的 LED1 点亮.当按下线性按键 S1 后,LED1 熄灭,LED2 点亮.其次,每按下 ...
- 【51单片机Task】:led十六进制控制led灯详解、按键控制流水灯、跑马灯等任务
学习目标: 学习普中51单片机的按键控制led灯. 电路图: 学习内容: LED灯的十六进制怎么算??? 在这给大家算一下:首 ...
- C51单片机之点亮LED灯
文章目录 C51单片机之点亮LED灯 1. 了解普通发光二极管的参数,掌握限流电阻的计算方法. 2. 理解单片机最小系统,单片机外围电路,Flash,RAM 和 SFR 这些概念. 3. 了解 Kei ...
最新文章
- Android 自定义动画 LoadingView
- 用力和应变片计算弹性模量_一种沿深度非均匀分布的残余应力测试计算方法与流程...
- LeetCode 1457. 二叉树中的伪回文路径(位运算+递归)
- Java基础系列13:JDBC批处理简介
- 测试老司机一起聊聊性能测试是怎么一回事?
- 如何将ffmpeg在windows编译和使用
- [swift] LeetCode 62. Unique Paths
- 第一节:Scrapy开源框架初探
- java中的位操作系统_Java中的按位运算操作
- 初识计算机编程语言教案,完整版,初识VB教学设计
- CTF—攻防练习之HTTP—命令执行漏洞
- Linux中svn提交文件后自动同步更新到网站目录
- wps linux 64 下载,WPS For Linux 10.1.0.6757社区版发布下载
- 数据结构和算法(十三)排序算法
- kuangbin新模板错误
- windows ping 端口测试
- ads design environment_ADS射频仿真软件培训材料.pdf
- CGLIB 动态代理使用
- 数据库课程设计:图书信息管理系统(Java+MySQL)(附程序)
- CF 1606E Arena