最近我一直在玩LED,由8位微控制器供电。有时需要使用脉冲宽度调制的纯软件实现来控制LED亮度 - 即快速打开和关闭灯光以改变打开和关闭时间的比例。这种效果很好,直到我达到约5%的亮度,闪光开始看起来令人不舒服的闪烁。
将PWM实现为循环,它逐步执行0-255中的每个数字,以便在此时间打开或关闭指示灯。设置为20值的灯将在前20个循环中打开,然后关闭。
我正在寻找一个能够在这些数字周围移动的好功能,所以不是循环通过0,1,2,3 ...我的循环可以从可能性池中半随机地进行采样。总亮度随时间变化是相同的,但是20亮度值的光可以在256个循环中打开和关闭十几次,而不是仅仅点亮一次然后关闭大部分循环。即使循环运行稍慢,这也可以减少闪烁效应。
当使用每个8位数调用时,良好的抖动功能需要返回8位范围内的每个数字。因此,它也不需要产生重复的数字 - 不是随机的,只是改组。最好是它不会按顺序将相似的数字放在一起 - 每个数字之间的差异应该很高 - 理想情况下我的数字大约为64-127。
这些限制也很有趣 - 这是一个时间关键的应用程序。加法,减法和按位运算花费1个任意单位时间,乘法成本2个单位,分割成本4个单位。浮点数不在问题中,并且中间数字中使用的每8位数的成本大约翻倍。查找表是可能的,但是大约会占用设备总内存容量的一半 - 因此快速算法最适合重用,但是当有预先计算的空间时,优质慢速算法也非常有用。
感谢您帮助我解决任何想法或想法。 :)
答案 0 :(得分:5)
不是100%确定我理解正确,但基本上我认为任何不分256的数字都会生成数字组0..255,如果你只是将它加到自己的模256. 一些闪回来自抽象代数课......
像这样:s = {}
n = 157
for i in range(0, 256):
s[n] = True
print n
n += 157
n %= 256
print "check: has to be 256: ", len(s)
编辑:用较大的发电机替换小型发电机,使配电更“随机”。
答案 1 :(得分:5)
示例:在8位寄存器中使用相位累加器进行5位抖动,其中占空比= 1到31 [%=占空比/(1 位)]。
// Easier to do in assembly, where there is access to the carry flag
unsigned bits = 5; // states = 1 << bits
unsigned carry = 7; // keep carry bit within an 8 bit register, limits bits
unsigned frq = ((1 << carry) * duty) / (1 << bits); // More than 8 bit intermediate value
unsigned phs = 0;
for (i = 0; i < (1 << bits); i++) {
phs += frq; // Carry is high bit
output((phs >> carry) & 1); // Output carry
phs &= (1 << carry) - 1; // Discard carry
}
抖动模式如下:
00: 00000000000000000000000000000000
01: 00000000000000000000000000000001
02: 00000000000000010000000000000001
03: 00000000001000000000010000000001
04: 00000001000000010000000100000001
05: 00000010000010000001000001000001
06: 00000100001000010000010000100001
07: 00001000010001000010001000010001
08: 00010001000100010001000100010001
09: 00010001001000100100010010001001
10: 00010010010010010001001001001001
11: 00100100100100100100100100100101
12: 00100101001001010010010100100101
13: 00101001010010100101001010010101
14: 00101010010101010010101001010101
15: 00101010101010100101010101010101
16: 01010101010101010101010101010101
17: 01010101010101011010101010101011
18: 01010101101010110101010110101011
19: 01010110101101011010110101101011
20: 01011011010110110101101101011011
21: 01011011011011011011011011011011
22: 01101101101101110110110110110111
23: 01101110110111011011101101110111
24: 01110111011101110111011101110111
25: 01110111101110111101110111101111
26: 01111011110111110111101111011111
27: 01111101111101111110111110111111
28: 01111111011111110111111101111111
29: 01111111110111111111101111111111
30: 01111111111111110111111111111111
31: 01111111111111111111111111111111
如果没有足够宽的整数(或者在没有乘法或除法的情况下在汇编程序中),则可能需要一次一个循环地计算frq。
可选择地,可以预先计算抖动模式,并将其编码为查找表中的常量。
只有两种力量的模式没有噪音;除非您正在进行音频或RF合成,否则这无关紧要。否则其他模式都有小鸟。在输出一次模式之后对模式位的顺序进行加扰会增加噪声,但会删除小鸟。 LFSR函数具有较长的重复周期,不会添加或删除位(1和0的数量保持不变,只是它们的顺序更改)可用于执行此操作。
注意,要以60Hz帧速率输出完整模式,需要60Hz *(1 <比特)= 1.92kHz的抖动频率。对于没有闪烁的LED,可能会有更低的抖动频率,例如(1 <比特)= 32Hz。实验!