我最近一直在玩LED,由8位微控制器供电。有时有必要使用纯软件实现的脉冲宽度调制来控制LED亮度-即快速打开和关闭灯,改变开和关的时间比率。这个效果很好,直到我降到5%的亮度,闪光灯开始看起来不舒服的闪烁到眼睛。
将PWM实现为一个循环,它遍历从0到255的每个数字,在那一刻设置灯的打开或关闭。设置为20的灯将在前20个循环中亮起,然后关闭。
我正在寻找一个好的函数来处理这些数字,所以不是循环通过0,1,2,3…我的循环可以从可能性池中半随机地采样。随着时间的推移,总亮度是相同的,但亮度值为20的光可能会在256个环路中打开和关闭十几次,而不是只点亮一次,然后在大部分环路中关闭。即使循环运行速度稍慢,这也会减少闪烁效果。
一个好的抖动函数需要在调用每个8位数字时返回8位范围内的每个数字。因此,它也不需要产生重复的数字-不是随机的,只是混洗。最好不要把相似的数字按顺序放在一起--每个数字之间的差异应该很大--我估计最理想的是64-127。
限制也很有趣--它是一个时间关键型的应用程序。加法、减法和按位运算花费1个任意单位的时间,乘法花费2个单位,除法花费4个单位。浮点数是不可能的,而且中间数中每使用8位的倍数,成本大约翻一番。查找表是可能的,但将使用设备总内存容量的大约一半-因此快速算法是最好的可重用性,但当有空间进行预计算时,高质量的缓慢算法也非常有用。
谢谢你帮我的忙,有什么想法或想法。:)
发布于 2012-04-06 11:26:58
不是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) 编辑:用更大的生成器替换小生成器,使分布更“随机”。
发布于 2016-03-08 13:09:07
示例:将相位累加器用于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,一次计算一位(或者在汇编程序中,如果没有乘法和除法,则需要一次计算一位)。
可选地,可以预先计算抖动图案并将其编码为查找表中的常量。
只有2的幂的模式没有噪声;除非你正在做音频或RF合成,否则这是无关紧要的。否则其他花样就会有小鸟球。在一次输出模式后扰乱模式比特的顺序会增加噪声,但会删除小鸟。可以使用一个具有长重复周期的LFSR函数来执行此操作,该函数不会添加或删除位(1和0的数量保持不变,只是顺序发生了变化)。
请注意,要以60 Hz帧速率输出完整模式,需要60 Hz * (1 <<位)= 1.92 kHz的抖动频率。也许可以逃脱更低的抖动频率的发光二极管没有闪烁,如(1 <<位)= 32赫兹。实验!
https://stackoverflow.com/questions/10038744
复制相似问题