akira.kei が 2025年03月01日23時55分09秒 に編集
コメント無し
本文の変更
[<前の記事](https://elchika.com/article/baa04f28-52c0-44c6-8f6e-9e595bd9dc63/) : [次の記事>]() ## LED調光
ボリュームで電圧調整してADCで読み、PWMのデューティを調整するとLEDの明るさを調光できる。Fosc=1MHzで解像度10bitで最大PWM周波数は978Hzくらいになっている。対象が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; } ```