編集履歴一覧に戻る
akira.keiのアイコン画像

akira.kei が 2025年03月01日23時52分45秒 に編集

コメント無し

本文の変更

[<前の記事](https://elchika.com/article/baa04f28-52c0-44c6-8f6e-9e595bd9dc63/) : [次の記事>]() ## LED調光 ボリュームで電圧調整してADCで読み、PWMのデューティを調整するとLEDの明るさを調光できる。Fosc=1MHzで解像度10bitで最大PWM周波数は978Hzくらいになっている。対象がLEDではなくモータの場合だと音が聞こえるかもね。 ![PWM](https://camo.elchika.com/5e681016f480fd38f73c4ab531eeb522fd863139/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33363031626666382d633530632d343762382d613765362d3531663731393163323336642f32393737366433652d616335372d343465302d383335332d373561663433333332613466/) ## 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しか選べない。 ![ADCS](https://camo.elchika.com/a0e266bef9abb246cf08cd83148c79e9a89dd77d/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33363031626666382d633530632d343762382d613765362d3531663731393163323336642f34616265396439352d643336312d343436352d623665322d626161383835663862303239/) あとは入力端子を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; } ```