LED調光
ボリュームで電圧調整してADCで読み、PWMのデューティを調整するとLEDの明るさを調光できる。Fosc=1MHzで解像度10bitの場合の最大PWM周波数は978Hzくらいになっている。対象がLEDではなくモータの場合だと音が聞こえるかもね。Fosc=32MHzなら超音波になって聞こえないはずだ。
pragma_config.h
いつもと同じだから割愛しようかな。
main.c
冒頭はいつもと同じだ。
#include <xc.h>
#include "pragma_config.h"
void main(void) {
ANSELA=0;
TRISA=0xff;
PWM5の設定は以下の通り。RA5にLEDを接続する。Timer2をON、PR2を設定し、RA5のPPSでPWM5の出力を切り換え、最後にTRISAを設定する。このTRISAを忘れがちだ。
//
T2CONbits.TMR2ON=1;
PR2=0xff;
PWM5CON=0;
PWM5CONbits.PWM5EN=1;
RA5PPSbits.RA5PPS=0b00010; // PWM5
TRISAbits.TRISA5=0;
ボリュームはRA2に接続した。ANSELAでRA2(ANA2)を指定し、ADCSの範囲は意外に狭いのでデータシートの指定通りに設定する。Foscが1MHzの時にはFosc/2かFosc/4しか選べない。
あとは入力端子をRA2に設定してADCをONにするだけだ。ADC関連のレジスタは電源投入時にクリアされるはずなので「ADACT=0」「ADCON1=0」「ADCON0=0」は多分不要だが、外部電源でデバッグする時は電源が落ちないので、わざわざクリアするようにした。
//
ANSELAbits.ANSA2=1;
ADACT=0;
ADCON1=0;
ADCON1bits.ADCS=0b100; // Fosc/4
ADCON0=0;
ADCON0bits.CHS=0b000010; //RA2
ADCON0bits.ADON=1;
ループ部
ループ部は単純で、AD変換をスタートし、変換が終わるまで待ち、デューティレジスタに変換結果をセットするだけだ。間にディレイを入れてもいいが利点はない。割り込みで変換を待ってもいいが、設定が長くなってループ部が空になるだけだ。
PWMのデューティレジスタが左寄せなので、ADC結果も左寄せ(ADFM=0)にすると、単純に上位と下位を代入するだけで良い。よくできてる。
//
while(1) {
ADCON0bits.ADGO=1;
while(ADCON0bits.ADGO) {}
PWM5DCH=ADRESH;
PWM5DCL=ADRESL;
}
投稿者の人気記事
-
akira.kei
さんが
2025/03/01
に
編集
をしました。
(メッセージ: 初版)
-
akira.kei
さんが
2025/03/01
に
編集
をしました。
-
akira.kei
さんが
2025/03/01
に
編集
をしました。
-
akira.kei
さんが
2025/03/02
に
編集
をしました。
ログインしてコメントを投稿する