找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2|回复: 0
收起左侧

定时器中断实现LED多种模式任意间隔闪烁

[复制链接]
ID:1155837 发表于 2025-7-2 16:52 | 显示全部楼层 |阅读模式
下面的代码用了一个二维数组来实现led定时间隔闪烁,复用很简单,直接把ledstate函数放进定时器中断就行,可以用外部函数改变ledmode,进而调整到不同的模式。想要修改间隔,就改数组值或者改定时器中断的频率,改间隔的话,可以改数组的值,也可以增加数组的行数或者列数(同时修改计数器循环值)
具体原理很简单,就是通过ledmode和currentbit这两个数值在二维数组中选值,然后与计数器做比较,定时器每次中断都会对计数器+1,于是就有了时间基础,每个1都是定时器中断的间隔。直到计数器的值大于从数组中读取到的值,才会切换读取数组的下一位。通过&运算让位数在0到3的范围里循环。
根据你的定时器中断间隔与与想要实现的闪烁,调整数组数值就行。
const unsigned char ledform[][4] = {//二维数组
    //每次125ms定时器1中断ledcounter++,将ledcounter与数组做比较
    {0,0,0,0},    //mode0,常亮(vcc>4200mv),数组中的0表示立即切换到下一位
    {16,4,16,4},    //mode1,2000ms亮,500ms灭 (3800<vcc<=4000)
    {8,4,8,4},   //mode2,1000ms亮,500ms灭 (3400<vcc<=3800)
    {4,4,4,4},    //mode3,500ms亮,500ms灭 (2750=<vcc<=3400)
    {1,1,1,1},    //mode4,125ms亮,125ms灭(vcc<2750)
    {12,1,1,1},    //mode5,1500ms亮,125ms灭亮灭,charging
};
void LED_STATE(void){
    static unsigned char ledcounter = 0;//局部变量声明
    //用于从ledform中选值,比如ledmode=1,currentbit=2,segtimes=4
    static unsigned char currentbit = 0;//当前位
    unsigned char bitvalue = ledform[ledmode][currentbit];//读取当前位值
    if(ledmode == 0){//对常亮的特殊情况单独设置
        P30 = 0;
        ledcounter = 0;
        return;//不继续执行下面的语句
    }
    //状态切换判断
    if(ledcounter >= bitvalue){
        currentbit = (currentbit + 1) & 0X03;//0~3循环,改了列数修改这里,可以改成%N,N就是数组列数
        ledcounter = 0;
    }
    //如果位值为0,位数+1,并退出函数,实现常亮,与下面的状态切换判断不能调换先后位置
    //定义位数对应LED亮灭
    if (currentbit == 0 || currentbit == 2) {
        P30 = 0; // 亮
    } else {
        P30 = 1; // 灭
    }
    ledcounter++;//led计数器加1
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表