自分用です.この内容には自信がないので,もし参考にする人がいたら最初にデータシートを読むことをおすすめします.
1.目的
LEDドライバのTLC5940をPICで制御しようと思ったら,クロックを入れる必要があるらしい.
なのでPWMをクロックにしたい.
2.簡単な流れ
2.1.(タイマを使う場合は)タイマの周期を設定する.
2.2.PWMのピンの割当を行う
2.3.PWMの周期とデューティを決める
2.4.クロックのソースを決める
2.5.(タイマを使う場合は)タイマ スタート!
3.データシートに沿った詳細な流れと設定方法
[参考]14.3 Pulse-Width Modulation (PWM) Mode
3.1.OCx をRPxピンに割り当てる.
例えばRP14(PICの25番ピン)にOC1を割り当てる場合,ピンを出力に設定して,デジタル設定にして,OC1を割り当てる必要がある.
なお,3行目の18はRP14に割り当てる機能を表す(今回の場合はOC1).機能一覧はTABLE 10-3: SELECTABLE OUTPUT SOURCES (MAPS FUNCTION TO OUTPUT)を参照.
TRISBbits.TRISB14=0; //RP14を出力に AD1PCFG=0xffff; //全部のピンをデジタルに RPOR7bits.RP14R = 18; //RP14にOC1を割り当てる
3.2.デューティ(仕様書ではon-time)を計算し,OCxR に入れる.
最初にPWM周期とデューティ比を決める必要がある.
例えば(内蔵オシレータ8[MHz]をプリスケーラで分周した)32[MHz]をシステムクロックとし,PWM周波数が100[kHz]でデューティ比が50[%]の場合,EQUATION 14-1: CALCULATING THE PWM PERIODより,
PWM周期=[Value+1]*T_CY* (Prescaler Value)
1/100[kHz]=[Value+1]*(2*T_OSC)* (Prescaler Value)
10*10^(-6)=[Value+1]*(2*(1/32[MHz]))* (Prescaler Value)
10*10^(-6)=[Value+1]*(2*(31.25*10^(-9)))* (Prescaler Value)
10*10^(-6)=[Value+1]*(62.5*10^(-9))* (Prescaler Value)
[Value+1]=10*10^(-6) / (62.5*10^(-9))* (Prescaler Value)
[Value+1]=160*(1/Prescaler Value)
となる(はず).ここで,ValueはOCxRS やPR2に入れる値となる(?).
また,Prescaler Valueはタイマのプリスケーラで,周期を長くするために使う.システムクロックを使う場合は1固定.
Valueの値が極端な値ではないため,プリスケーラは1で良さそう.なのでValueは159となる.
Valueが求まり,デューティ比を50[%]と決めているので,OCxRに設定するべきデューティを求める事ができる.
OCxR =(Value+1)*50[%]
=80
よって,OCxRS とPR2には159,OCxRには80を入れれば良いことが分かる.
PR2 = 159; OC1RS = 159; OC1R = 80;
3.3.PWM周期を計算し,OCxRSに入れる.
3.2.を参照.
3.4.同期ソースの設定
仕様書通りに,SYNCSELに0x1F,OCTRIGに0を入れる.
OC1CON2bits.SYNCSEL=0x1f; OC1CON2bits.OCTRIG=0;
3.5.クロックソースの選択
クロックソースをシステムクロックとするか,タイマにするかなどを決める.
システムクロックにする場合はOCTSELに0b111を入れ,timer2にする場合は0b000を入れる.
システムクロックでは以下のようになる.
OC1CON1bits.OCTSEL=0b111;
3.6.必要なら割込み許可する
今回は必要ないので割愛
3.7.PWMモードを決める.
Edge-AlignedとCenter-Alignedがあるけど,これはPWM信号の生成開始地点を決めるっぽい
こちらを参照.
今回はEdge-AlignedにするのでOCMに0b110を設定
OC1CON1bits.OCM=0b110;
3.8.タイマ使うならタイマ起動
TONを1に設定する.
timer2をオンにするなら以下のようになる.
T2CONbits.TON 1;
4.まとめ
上記の設定をすべてまとめると以下のようなコードとなる.
なお,PWMのクロックソースのにはシステムクロックを使い,システムクロックは32[MHz],PWM周波数は100[kHz],デューティ比は50[%]とする.
int main(void) { CLKDIVbits.RCDIV = 0b000; //クロックの設定 TRISBbits.TRISB14=0; //RP14を出力に AD1PCFG=0xffff; //全部のピンをデジタルに RPOR7bits.RP14R = 18; //RP14にOC1を割り当てる OC1RS = 159; //計算は省略 OC1R = 80; //計算は省略 OC1CON2bits.SYNCSEL=0x1f; //仕様書から OC1CON2bits.OCTRIG=0; //仕様書から OC1CON1bits.OCTSEL=0b111; //クロックソースはシステムクロック OC1CON1bits.OCM=0b110; //Edge-Alignedを使う while(1); //動作終了 }
結果はこうなる.fに100kHzと書かれているし多分正しい.
5.タイマを使う場合の変更点
タイマの設定を行う.
PWMのクロックソースを変更する.
タイマーON!
以上の3つをコードにすると以下のようになる.
T2CON = 0x0000; T2CONbits.TCKPS=0b11; OC1CON1bits.OCTSEL=0b000; T2CONbits.TON = 1;