CPU+コンパイラ自作キャンプ/PWMで滑らかにLED明滅
明るさを段階的に変えることを調光(ちょうこう)と呼ぶ SystemVerilogでの実装例
code:PWMで明るさを制御する回路の中核部分.sv
// PWM 輝度制御タイマと輝度設定値
assign onboard_led = ~{5'b0, pwm_timer <= brightness};
オンボードLEDのうち1つの明るさをPWMで階調制御
brightnessに明るさ(輝度)を0~255で設定
pwm_timerが高速にインクリメントされていく
https://gyazo.com/cb67db51b13e7e359eab028788488948
点灯と消灯を高速に繰り返すことで、人間の目には明るさが段階的に変わっているように見える
brightnessが大きいほど pwm_timer <= brightness が1になる期間が長くなる→明るくなる
ビット反転~{...}してるのは、オンボードLEDが0で点灯、1で消灯という仕様だから
pwm_timerのインクリメント時間の設計
pwm_timerのインクリメントが遅すぎると点灯・消灯の点滅が目に見えてしまう
速すぎるのもあまり良くない
スイッチング損失が増大して消費電力が増えたり、配線などによるインピーダンスで思ったような電流が流れないかも
LEDのPWM制御なら1ms~10msくらいがちょうど良いと思う。
シミュレーション
code:シミュレーション結果
./sim.exe
0 led=11111x on_period= 0
5 led=111110 on_period= 0
165 led=111111 on_period= 165
38415 led=111110 on_period= 165
38715 led=111111 on_period= 300
76815 led=111110 on_period= 300
77265 led=111111 on_period= 450
115215 led=111110 on_period= 450
115815 led=111111 on_period= 600
《中略》
9792015 led=111110 on_period=38250
9830565 led=111111 on_period=38550
9868815 led=111110 on_period=38550
9869115 led=111111 on_period= 300
9907215 led=111110 on_period= 300
9907665 led=111111 on_period= 450
LEDのビット0が0/1を繰り返している→高速に点滅
その周期は38400
10単位時間で1クロック変化するので、3840クロック分
シミュレーションにおけるクロック周波数は1MHzとしているため、3840クロックは3.84msに相当
on_periodは直前にLEDが点灯していた時間を表す
on_periodが徐々に増えている=だんだんLEDが明るくなっている
on_period=38550は3.855msに相当