PIC18F14K50 (4)
Microchip 社の USB フレームワークのコンパイルには同社の「C18」コンパイラが必要ですが、無償でダウンロードできる「評価版」には、60 日経過すると最適化機能が制限されるという制約があります。
そのため、対象のチップに関する経験が少ないままコンパイラをダウンロードして使い始めると、内蔵モジュールの扱いに慣れてきたころに最適化の制約がかかるという悲しい状態になってしまいます。
単なるアプリケーションであれば、最適化レベルが下がっても、どうということはないのですが、ブートローダなどのように、コード・サイズに絶対的な制約があるものに手を入れようとした場合には、最適化レベルが下がってしまうのは困ります。
そので、C18 コンパイラを使い始める前に、他のフリーな言語を使用して経験を積むことにしました。
それは、最近知ったのですが、「JALv2」というコンパイラです。
「JAL」というと、どこかの景気の悪い会社みたいですが、「Just Another Language」の意味で、「JALv2」 を簡単に言えば、
ということになります。
言語仕様が強固に定まっているわけでないので、現在のコンパイラで通るソース・プログラムが、将来のコンパイラでも通用するのかという、「永続性」に不安もありますし、他のアーキテクチャのマイコンで使える「可搬性」もないのですが、そこを割り切って、プログラムは「書き捨て」「使い捨て」でいいや、と考えれば価値はあります。
コンパイラ本体は
http://www.casadeyork.com/jalv2/
からダウンロードできますが、サポートされているデバイスの数が限られているので、「jallib」プロジェクト
http://code.google.com/p/jallib/
から最新版の「jallib-pack-2.4m-0.5.0.zip」をダウンロードして使います。
コンパイラ本体、デバイス・ファイル、ドキュメント、サンプル・プログラムなどが含まれており、PIC18F14K50 デバイスもサポートされています。
18F14K50 のレジスタ設定プログラムを JALv2 で書いて示しますが、単にレジスタをビット単位で設定しているだけなので、特に JALv2 の文法について理解する必要もなく、「--」以降がコメントとして扱われることだけを知っていれば十分です。 (C/C++ の「//」に相当)
下に「555」相当の機能に設定するプログラムを示します。
前回の図の設定をプログラムとして表現したものです。
-------------------------------------------------- -- 18f14k50_555_1.jal: -- -- "555" type oscillator for PIC18F14K50 -- using comparator / SR-Latch / Vref (DAC1) module -- Vdd ratiometoric operation -- -- 18F14K50 "555" -- pin pin -- --- --- -- 6 3 (OUTPUT) -- 15 2,6 (TRIGGER, THRESHOLD) -- 16 -- (External 1/3 Vdd divider) -------------------------------------------------- -- START OF TARGET CHIP DEPENDENT DECLARATIONS --- include 18f14k50 if (PIC_18F14K50 == target_chip) then -- 12 MHz crystal x4 PLL = 48 MHz clock pragma target clock 48_000_000 -- use with Microchip HID bootloader (2 K Word = 4 K byte) pragma bootloader loader18 4096 end if -- END OF TARGET CHIP DEPENDENT DECLARATIONS --- ------------------------------------------------ procedure vref_init() is REFCON0_FVR1EN = 1 -- enable Fixed Voltage Reference 1 REFCON0_FVR1S1 = 1 -- 4 x 1.024 V REFCON0_FVR1S0 = 1 -- 4 x 1.024 V REFCON1_D1EN = 1 -- DAC1 enable REFCON1_DAC1OE = 0 -- DAC1 Output disable REFCON1_D1PSS = 0x0 -- DAC1 Positive Source Select = Vdd REFCON1_D1NSS0 = 0 -- DAC1 Negative Source Select = Vss REFCON2 = 21 -- DAC1 out = (21/32) vdd = (2/3) Vdd end procedure procedure comparator_init() is CM1CON0_C1ON = 1 -- C1 ON CM1CON0_C1OE = 0 -- C1 internal only CM1CON0_C1POL = 1 -- C1 inverted CM1CON0_C1SP = 1 -- C1 high speed CM1CON0_C1R = 1 -- C1 C1VIN+ = C1Vref CM1CON0_C1CH = 1 -- C1 C1VIN- = C12IN1- (pin 15) CM2CON0_C2ON = 1 -- C2 ON CM2CON0_C2OE = 0 -- C2 internal only CM2CON0_C2POL = 0 -- C2 not inverted CM2CON0_C2SP = 1 -- C1 high speed CM2CON0_C2R = 0 -- C2 C2VIN+ = C12IN+ (pin 16) CM2CON0_C2CH = 1 -- C2 C2VIN- = C12IN1- (pin 15) CM2CON1_C1RSEL = 0 -- C1 C1Vref = Vref CM2CON1_C1HYS = 0 -- C1 hysteresis disabled -- CM2CON1_C1HYS = 1 -- C1 hysteresis enabled CM2CON1_C1SYNC = 0 -- C1 output asynchronous CM2CON1_C2RSEL = 1 -- C2 C2Vref = FVR CM2CON1_C2HYS = 0 -- C2 hysteresis disabled -- CM2CON1_C2HYS = 1 -- C2 hysteresis enabled CM2CON1_C2SYNC = 0 -- C2 output asynchronous -- set tri-state mode for comparator/vref input pins TRISC_TRISC0 = 1 -- RC0/AN4/C12IN+/VREF+ (pin 16) TRISC_TRISC1 = 1 -- RC1/AN5/C12IN1-/VREF- (pin 15) -- TRISC_TRISC2 = 1 -- RC2/AN6/C12IN2-/CVREF (pin 14) -- TRISC_TRISC3 = 1 -- RC3/AN7/C12IN3-/PGM (pin 7) -- enable analog input for comparator/vref JANSEL_ANS4 = 1 -- RC0/AN4/C12IN+/VREF+ (pin 16) JANSEL_ANS5 = 1 -- RC1/AN5/C12IN1-/VREF- (pin 15) -- JANSEL_ANS6 = 1 -- RC2/AN6/C12IN2-/CVREF (pin 14) -- JANSEL_ANS7 = 1 -- RC3/AN7/C12IN3-/PGM (pin 7) end procedure procedure SR_Latch_init() is SRCON0_SRLEN = 1 -- SR Latch enabled SRCON0_SRQEN = 0 -- SR Latch Q out disabled SRCON0_SRNQEN = 1 -- SR Latch Q* out enabled on RC4/SRQ pin TRISC_TRISC4 = 0 -- set RC4/SRQ pin to output SRCON1 = 0x00 -- at first, disable all S/R inputs SRCON1_SRSC1E = 1 -- SR Latch C1 set enabled SRCON1_SRRC2E = 1 -- SR Latch C2 reset enabled end procedure vref_init() comparator_init() SR_Latch_init()
この設定では、コンパレータ 1 の比較電圧を内蔵の Vref モジュールで Vdd の約 2/3 に設定しており、コンパレータ 2 の比較電圧は外部で Vdd を抵抗分圧して作り出し、16 番ピンから入力するようになっています。
6 番ピンと 15 番ピンとの間に 120 kΩ の抵抗をつなぎ、容量はストレー容量だけの状態で、約 480 kHz で発振しました。
15 番ピンにオシロのプローブをつないだり、手で触れたりすると 200 kHz 程度まで周波数が落ち、容量が検知できることが分かります。
この構成では、タイミング・コンデンサの充放電電流は Vdd に依存するのですが、コンパレータの比較電圧も Vdd 依存なので、両者がキャンセルし合って、いわゆる「レシオメトリック」動作となって、出力周波数には Vdd 依存性がなくなります。(理想的な場合)
アナログ・シンセの VCO では、アンチログ回路の出力電流がタイミング・コンデンサの充電電流となり、この電流を Vdd に依存しない一定値に保つなら、コンパレータの比較電圧も定電圧とする必要があります。
下のプログラムでは、コンパレータ 1 の比較電圧には内蔵 1.024 V 基準電圧の 4 倍の 4.096 V を与え、コンパレータ 2 の比較電圧には Vref (DAC1) 回路で (8/32) = (1/4) 倍に分圧した 1.024 V を与えています。
-------------------------------------------------- -- 18f14k50_555_2.jal: -- -- "555" type oscillator for PIC18F14K50 -- using comparator / SR-Latch / Vref (DAC1) module -- internal fixed voltage reference (Vdd independent) used -- -- 18F14K50 "555" -- pin pin -- --- --- -- 6 3 (OUTPUT) -- 15 2,6 (TRIGGER, THRESHOLD) -------------------------------------------------- -- START OF TARGET CHIP DEPENDENT DECLARATIONS --- include 18f14k50 if (PIC_18F14K50 == target_chip) then -- 12 MHz crystal x4 PLL = 48 MHz clock pragma target clock 48_000_000 -- use with Microchip HID bootloader (2 K Word = 4 K byte) pragma bootloader loader18 4096 end if -- END OF TARGET CHIP DEPENDENT DECLARATIONS --- ------------------------------------------------ procedure vref_init() is REFCON0_FVR1EN = 1 -- enable Fixed Voltage Reference 1 REFCON0_FVR1S1 = 1 -- 4 x 1.024 V REFCON0_FVR1S0 = 1 -- 4 x 1.024 V REFCON1_D1EN = 1 -- DAC1 enable REFCON1_DAC1OE = 0 -- DAC1 Output disable REFCON1_D1PSS = 0x2 -- DAC1 Positive Source Select = FVR REFCON1_D1NSS0 = 0 -- DAC1 Negative Source Select = Vss REFCON2 = 8 -- DAC1 out = 4.096 * (8/32) = 1.024 V end procedure procedure comparator_init() is CM1CON0_C1ON = 1 -- C1 ON CM1CON0_C1OE = 0 -- C1 internal only CM1CON0_C1POL = 1 -- C1 inverted CM1CON0_C1SP = 1 -- C1 high speed CM1CON0_C1R = 1 -- C1 C1VIN+ = C1Vref CM1CON0_C1CH = 1 -- C1 C1VIN- = C12IN1- (pin 15) CM2CON0_C2ON = 1 -- C2 ON CM2CON0_C2OE = 0 -- C2 internal only CM2CON0_C2POL = 0 -- C2 not inverted CM2CON0_C2SP = 1 -- C1 high speed CM2CON0_C2R = 1 -- C2 C2VIN+ = C2Vref CM2CON0_C2CH = 1 -- C2 C2VIN- = C12IN1- (pin 15) CM2CON1_C1RSEL = 1 -- C1 C1Vref = FVR -- CM2CON1_C1HYS = 0 -- C1 hysteresis disabled CM2CON1_C1HYS = 1 -- C1 hysteresis enabled CM2CON1_C1SYNC = 0 -- C1 output asynchronous CM2CON1_C2RSEL = 0 -- C2 C2Vref = Vref -- CM2CON1_C2HYS = 0 -- C2 hysteresis disabled CM2CON1_C2HYS = 1 -- C2 hysteresis enabled CM2CON1_C2SYNC = 0 -- C2 output asynchronous -- set tri-state mode for comparator/vref input pins -- TRISC_TRISC0 = 1 -- RC0/AN4/C12IN+/VREF+ (pin 16) TRISC_TRISC1 = 1 -- RC1/AN5/C12IN1-/VREF- (pin 15) -- TRISC_TRISC2 = 1 -- RC2/AN6/C12IN2-/CVREF (pin 14) -- TRISC_TRISC3 = 1 -- RC3/AN7/C12IN3-/PGM (pin 7) -- enable analog input for comparator/vref -- JANSEL_ANS4 = 1 -- RC0/AN4/C12IN+/VREF+ (pin 16) JANSEL_ANS5 = 1 -- RC1/AN5/C12IN1-/VREF- (pin 15) -- JANSEL_ANS6 = 1 -- RC2/AN6/C12IN2-/CVREF (pin 14) -- JANSEL_ANS7 = 1 -- RC3/AN7/C12IN3-/PGM (pin 7) end procedure procedure SR_Latch_init() is SRCON0_SRLEN = 1 -- SR Latch enabled SRCON0_SRQEN = 0 -- SR Latch Q out disabled SRCON0_SRNQEN = 1 -- SR Latch Q* out enabled on RC4/SRQ pin TRISC_TRISC4 = 0 -- set RC4/SRQ pin to output SRCON1 = 0x00 -- at first, disable all S/R inputs SRCON1_SRSC1E = 1 -- SR Latch C1 set enabled SRCON1_SRRC2E = 1 -- SR Latch C2 reset enabled end procedure vref_init() comparator_init() SR_Latch_init()
この設定では、120 kΩ + ストレー容量で、約 280 kHz で発振しました。
前の例より周波数が下がっているのは、前の例では振幅が約 1.7 V だったのに対し、この例では、振幅が約 3 V と大きくなっているためです。