人様の丸写しでなく、なるべくデータ・シートだけでいろいろやってみようとするコーナーの4回目はDSM ( Data Signal Modulator )、使うPICはPIC16F1827だ。
どんなものなのかはデータ・シートの図を見ると良く分かる。
3種類の矩形波を用意して合成したものを出力する。
詳しく書くと、Modulatorの信号がHighの間はCarrier Highのパルスを出し、Modulatorの信号がLowの間はCarrier Lowの信号を出す。
データ・シートを眺めながら、あれこれやった結果、上の図に似たそれらしい出力が得られたので、PICkit 3のLogic Toolの絵を貼っておく。
Modulatorが2kHz、Carrierは40kHzのものと16kHzのものを用いた。
Carrierの部分をそれぞれ拡大したものが下の図になる。
上のデータ・シートを参考にしてDSMそのものは以下のようにCCP1~3までを割り当てるように設定した。
使う信号をCCPだけにする方がたぶん設定が楽だろうと思ったからで、他にCCPを選んだ理由はない。
CCP自体が、先日PWMを試したときに初めて使ってみたものなので、完全な理解からは程遠い状態なのに、どんどん新しいものを試している状況だ。
//DSM
MDCONbits.MDEN = 1;//Modulator Module Enable bit
MDCONbits.MDOE = 1;//Modulator Module Pin Output Enable bit = 9th Pin(RB3)
MDSRCbits.MDMS = 0b0010;//Modulation Source is CCP1 output (PWM Output mode only)
MDCARHbits.MDCH = 0b0101;//Modulator Data High Carrier Selection bits CCP2
MDCARLbits.MDCL = 0b0110;//Modulator Data Low Carrier Selection bits CCP3
CCPの設定は3つ同様なので、Modulatorに用いたCCP1の例を書くと以下の通り。
//PWM Period 2kHz 2000 = 1/( (249 + 1) x 4 / 8000000 x 4 )
//Set CCP1 (Timer2)
PR2 = 249;//Timer2 Period register
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M3 = 1;//PWM mode
//Duty Cycle
CCPR1L = 0b01111101;
CCP1CONbits.DC1B = 0b00;//PWM Duty Cycle Least Significant bits
CCPTMRSbits.C1TSEL = 0x00;//CCP1 is based off Timer 2 in PWM Mode
PIR1bits.TMR2IF = 0;//TMR2 to PR2 Match Interrupt Flag bit
T2CONbits.T2CKPS = 0b01;//Timer2 Clock Prescale Select bits (4)
T2CONbits.TMR2ON = 0b1;//Timer2 On bit
Duty Cycleの設定でちょっと面倒だったのは、10bit分を分割して設定しなければならないからで、この例では
( 249 + 1 ) x 4 = 1000
を分子として、Duty Cycleが50%なるように分母を決めるので、設定値は半分の500になる。
これを2進数に直して、
500 = 0b0111110100
上位8bitを
CCPR1L = 0b01111101;
と設定し、下位2bitを
CCP1CONbits.DC1B = 0b00;
と設定する。(※1)
初めてなので、これだけでもなかなか面倒だが、まだまだここで触れていないオプションがわんさかある。
以下は、これもあれこれあれこれやった挙句にCCP1, CCP2, CCP3をPICkit 3で同時に表示させてみたところ。
実はこのCCP1の出力を捕らえるのにはなかなか面倒な手順がある。
何と、例えばCCP1とMDOUTは初期設定では同じピンに配置されているのだ。
そのため、ピンの機能には優先順位があって、こういう場合はプライオリティーの上のもの、ここではMDOUTが優先される。
じゃ、CCP1はどうなるのかというと、驚いたことに別のピンへ機能を移すことが出来る。
以上のような経緯から、以下のような設定をしないとそれぞれの矩形波(特にCCP1は面倒)を同時に眺めることはできない。
APFCON0bits.CCP1SEL = 1;//CCP1 -> RB0
MDCARHbits.MDCHODIS = 0;//Modulator High Carrier Output Disable bit
MDCARLbits.MDCLODIS = 0;//Modulator Low Carrier Output Disable bit
下の2行はDSM使用時にピン出力しない状態にしてくれるのを解除するための設定だ。
多機能PIC恐るべし。
(追記※1)
どうせ4で割るんだから下位2ビットは無視してもいい?
んじゃ、わざわざ10ビット用意した意味は?
(追記)
ちゃんと4種類のパルスを並べて見れる画像。