打印
[51单片机]

请教和讨论LED扫描电路和方法,如下图:

[复制链接]
3086|41
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
这是现在在使用的LED扫描指示灯电路,然而我用自己的想法实现下来效果不尽如人意:定时10ms扫描一次,扫描函数里放了个switch来根据案件按下次数来显示LED灯的数目,比如需要7个都亮就->亮一个后暂停1ms再亮下一个->case完了有个关灯动作,如此定时循环确保亮度一致,但是亮度一致后出现的问题是亮的越多亮度越暗,要是在增加暂停时间频率就不对了会出现闪烁的现象了,请问这样的电路该如何处理才好。
注:没有上拉,是配为强推IO来做的

LED扫描电路.png (29.34 KB )

LED扫描电路.png

相关帖子

来自 2楼
ayb_ice| | 2018-12-21 11:21 | 只看该作者
本帖最后由 ayb_ice 于 2018-12-21 11:22 编辑

这只需要扫描两次就够了,
P03为低可以控制一半,为高控制另一半,此为一个循环,周而复始
注意在一个循环开始时记录各灯开关状态,根据此状态控制各灯
应该在定时中断执行此驱动

使用特权

评论回复
评论
ayb_ice 2018-12-24 08:37 回复TA
@一叶倾城wwq :必须的 
一叶倾城wwq 2018-12-22 08:31 回复TA
昨天已经按照您说的方法试过了,效果很棒,亮的很,而且代码量少效率高,谢谢 
板凳
hwpga| | 2018-12-21 13:14 | 只看该作者
本帖最后由 hwpga 于 2018-12-21 13:37 编辑

程序尽量不要放定时器里如果非要放,保证状态机运行时间<定时时间另外



使用特权

评论回复
地板
一叶倾城wwq|  楼主 | 2018-12-21 13:33 | 只看该作者
ayb_ice 发表于 2018-12-21 11:21
这只需要扫描两次就够了,
P03为低可以控制一半,为高控制另一半,此为一个循环,周而复始
注意在一个循环 ...

"只用扫描两次",这是个好主意,我试试,谢谢提醒,只是我的程序是在主循环内执行的

使用特权

评论回复
5
一叶倾城wwq|  楼主 | 2018-12-21 13:39 | 只看该作者
hwpga 发表于 2018-12-21 13:14
用时间片轮询,而不是把程序放定时器里
时间片是等片机制,所有任务运行的时间是一致的
假设时间片8MS一次轮 ...

是的,如您所说,我使用时间标志来控制整个程序的运行,也就是您所说的时间片轮训,但是虽然使用这个方法写了好多次了,但是还是有不明白的地方,比如:10ms扫描按键、20ms处理继电器、100ms处理串口接收的数据;那会不会在20ms的时候前一个10ms也到了,这时不是两个时间片都成立了吗?是不是我没理解对,请指教

使用特权

评论回复
6
hwpga| | 2018-12-21 13:39 | 只看该作者
你的架构不行,说太明白对你也没帮助
你用最基本的主函数if(1MS) if(10MS)这种来
这种虽然不是等片轮询效率差了点,一般的任务也够用了

使用特权

评论回复
7
ayb_ice| | 2018-12-21 13:51 | 只看该作者
一叶倾城wwq 发表于 2018-12-21 13:33
"只用扫描两次",这是个好主意,我试试,谢谢提醒,只是我的程序是在主循环内执行的 ...

这种情况不可能在主循环里完成,除非你的主循环比较简单
主循环一个几十毫秒延时的就可能对显示造成致命影响,造成闪烁

定时中断只管刷新LED状态,LED状态本身通过主循环改变,

使用特权

评论回复
8
ayb_ice| | 2018-12-21 14:00 | 只看该作者
本帖最后由 ayb_ice 于 2018-12-21 14:02 编辑
一叶倾城wwq 发表于 2018-12-21 13:33
"只用扫描两次",这是个好主意,我试试,谢谢提醒,只是我的程序是在主循环内执行的 ...



示意性代码

u8 ucLedStage = 0;

bit bFlag;



void T0Isr(void)
{
        
        static u8 ucBkp;
        //比如5MS中断一次
        
        //
        //P03切换到高阻状态
        P03_Input();
        
        bFlag = !bFlag;
        if (bFlag)
        {
                P03 = 1;
                ucBkp = ucLedStage;
                P20 = ucBkp & 0x01;
                P21 = ucBkp & 0x02;
                P22 = ucBkp & 0x04;
                P23 = ucBkp & 0x08;
        }
        else
        {
                P03 = 0;
                P20 = ucBkp & 0x10;
                P21 = ucBkp & 0x20;
                P22 = ucBkp & 0x40;
                P23 = ucBkp & 0x80;
        }
        //P03切换到推挽状态
        P03_Output();
}


void main(void)
{
        while (1)
        {
                ucLedStage = 0x55;
                DelaySecond(10);
               
                ucLedStage = 0xAA;
                DelaySecond(10);
        }
}

使用特权

评论回复
9
一叶倾城wwq|  楼主 | 2018-12-21 14:16 | 只看该作者
hwpga 发表于 2018-12-21 13:39
你的架构不行,说太明白对你也没帮助
你用最基本的主函数if(1MS) if(10MS)这种来
这种虽然不是等片轮询效率 ...

就是这样做的,只是感觉知其一不知其二,看来该看看书了,惭愧

使用特权

评论回复
10
mcu51hi2c| | 2018-12-21 15:56 | 只看该作者
让我来指导你,楼上2,3,4,5,6,7,8,9楼太LOW了,扫描灯一定要放在定时器里来做,而且定时为1MS中断一次,而且1ms只亮一个灯,所以亮7个灯就要花7MS的时间,分段处理软件,你在软件中“亮的越多亮度越暗”,是因为在中断的时间你同时打开几个灯同时亮的原因。另外10ms扫描按键、20ms处理继电器、100ms,处理不冲突,看软件:
中断函数:
if(T8IE && T8IF)//  中断1ms
{
        T8IF = 0;  //清中断标志位
        SysTime10Ms=SysTime10Ms+1;
        if(SysTime10Ms > 9)//10ms
        {
                SysTime10Ms = 0;
                SysTime10ms_Flag = 1;
                SysTime20Ms =SysTime20Ms+1;
                if(SysTime20Ms >1)//20ms
                {

                        SysTime20Ms = 0;
                        SysTime20Ms_Flag = 1;
                        SysTime100Ms=SysTime100Ms+1;
                        if(SysTime100Ms > 4)//100Ms
                        {
                                SysTime100Ms = 0;
                                SysTime100Ms_Flag = 1;
                        }
                }       
        }
}
//大循环
while(1)
{
if(SysTime10ms_Flag)
{
SysTime10ms_Flag = 0;
//10ms扫描按键
}
if(SysTime20ms_Flag)
{
SysTime20ms_Flag = 0;
//20ms处理继电器
}

}
就是这么简单,了解了吧

使用特权

评论回复
评论
hwpga 2018-12-21 20:48 回复TA
看清楚上面if这种我1点39秒就说过了,太细的我不讲了,吵赢了就爽个嘴没实际意义 
11
一叶倾城wwq|  楼主 | 2018-12-21 16:31 | 只看该作者
本帖最后由 一叶倾城wwq 于 2018-12-21 16:39 编辑
mcu51hi2c 发表于 2018-12-21 15:56
让我来指导你,楼上2,3,4,5,6,7,8,9楼太LOW了,扫描灯一定要放在定时器里来做,而且定时为1MS中断一 ...

一言不合就放代码,不过感谢你的回复,现在就是用的这种套路我想问的是:第一步10ms处理一个事件,第二步你20ms标志为真时,需要10ms再加一次,也就是再加一次这里,共处理了两次10ms事件一次20ms事件,20ms时存在两个标志都为真,两个处理在主函数里从上往下执行,此时,还是我们想要的时间片吗?!

使用特权

评论回复
12
mcu51hi2c| | 2018-12-21 17:39 | 只看该作者
一叶倾城wwq 发表于 2018-12-21 16:31
一言不合就放代码,不过感谢你的回复,现在就是用的这种套路我想问的是:第一步10ms处理一个事件 ...

这个没有关系的,软件要的时间片只是在10,20MS,时间到了的时候去执行一个工作而已

使用特权

评论回复
13
一叶倾城wwq|  楼主 | 2018-12-21 19:03 | 只看该作者
mcu51hi2c 发表于 2018-12-21 17:39
这个没有关系的,软件要的时间片只是在10,20MS,时间到了的时候去执行一个工作而已 ...

是啊,反过来想想,我们只是控制了频率并不是要去控制时间段,如果像之前的想法假设一个周期100ms,只在第一个10ms去处理第一个事件,那在后90个毫秒都是没有去处理它的,这更不是初衷。但单纯这样的依靠时间标志处理不好的话还是会有堵塞的情况发生,我觉得,比如每10个毫秒都有事件发生,那在100ms时不是要执行10个事件处理了?然后就是有的代码没有执行的机会...

使用特权

评论回复
14
一叶倾城wwq|  楼主 | 2018-12-21 19:07 | 只看该作者
得抽时间看书了

使用特权

评论回复
15
mcu51hi2c| | 2018-12-21 19:46 | 只看该作者
一叶倾城wwq 发表于 2018-12-21 19:03
是啊,反过来想想,我们只是控制了频率并不是要去控制时间段,如果像之前的想法假设一个周期100ms,只在第 ...

,你想得太多了,从没有堵过,这是一种软件思路。另外的问题,扫描灯的问题,2到9楼说的是不对的,要在定时器里分段扫描,每1MS里只能点一个灯

使用特权

评论回复
评论
hwpga 2018-12-21 20:38 回复TA
真不想回你,等片分时机制你都不懂 
16
hwpga| | 2018-12-21 20:51 | 只看该作者
mcu51hi2c 发表于 2018-12-21 19:46
,你想得太多了,从没有堵过,这是一种软件思路。另外的问题,扫描灯的问题,2到9楼说的是不对 ...

真正的分片,所有的任务刷新时间是一致的
像上面的按键,蜂鸣器,串口,以10MS刷一次的话
第一个10MS ,刷按键
第二个10MS, 刷蜂鸣器
第三个10MS,  刷串口


使用特权

评论回复
评论
SNmory 2018-12-22 08:52 回复TA
我也是您的理解,按10楼的逻辑来的话,30ms的时间,10ms的事件执行了3次,20ms事件执行一次,30ms事件执行一次。从执行次数上就不满足楼主想要的。从结构上分析,在20ms的时候,程序需要处理10ms事件和20ms事件,在两个事件处理的时间一旦溢出,另外的事件时间节点将不对。 
17
chongdongchen| | 2018-12-21 21:43 | 只看该作者
mcu51hi2c 发表于 2018-12-21 15:56
让我来指导你,楼上2,3,4,5,6,7,8,9楼太LOW了,扫描灯一定要放在定时器里来做,而且定时为1MS中断一 ...

一次1ms只亮一个灯,你哪来的自信,还“让我来指导你,楼上2,3,4,5,6,7,8,9楼太LOW了”。
你回头仔细看看,2楼方法比你的强多少?

使用特权

评论回复
18
一叶倾城wwq|  楼主 | 2018-12-22 08:38 | 只看该作者
chongdongchen 发表于 2018-12-21 21:43
一次1ms只亮一个灯,你哪来的自信,还“让我来指导你,楼上2,3,4,5,6,7,8,9楼太LOW了”。
你回头 ...

这个没得说的,我1楼阐述问题时就已经说明:就是用的1ms亮一个,然后七个都亮时亮度明显不够。
用2楼的方法,我已经实现,2次扫描即可,亮度与单独上拉并无区别(感官上)。

使用特权

评论回复
19
一叶倾城wwq|  楼主 | 2018-12-22 08:44 | 只看该作者
hwpga 发表于 2018-12-21 20:51
真正的分片,所有的任务刷新时间是一致的
像上面的按键,蜂鸣器,串口,以10MS刷一次的话
第一个10MS ,刷 ...

那是不是“真正的分片”,比如事件少---->三个事件开三个定时器,然后在定时器里执行,互不干扰,你10ms干你的我10ms干我的,理论上这样说不说得通?但实际情况上我们所谓的分片,只是一个概念,并没有真正分片?

使用特权

评论回复
20
mcu51hi2c| | 2018-12-22 11:37 | 只看该作者
chongdongchen 发表于 2018-12-21 21:43
一次1ms只亮一个灯,你哪来的自信,还“让我来指导你,楼上2,3,4,5,6,7,8,9楼太LOW了”。
你回头 ...

LED扫描电路,只有这一种1MS只亮一个灯这种软件思路实现,2楼的方法,会出现亮度不均的现象

使用特权

评论回复
评论
chongdongchen 2018-12-24 15:52 回复TA
推挽输出了解一下,带不动这几个LED? 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

79

主题

1296

帖子

11

粉丝