標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第488回]
●CONFIGの表記
前回に引き続いてPICアセンブラプログラムの説明です。
CONFIGはPICの基本的な設定をするためのレジスタで、プログラムの先頭部分で、決められた表記に従ってパラメータを設定します。
PICではハードウェアのほとんどの機能が、特殊なレジスタに割り当てられたビットのON、OFFによって選択されます。
たとえばPORTAのビットの向きを出力に設定するか、入力に設定するかは、TRISAレジスタのビットを0にするか1にするかで決定されます。
アセンブラのプログラムでは、
movlw 0ff ;wレジスタにFFを入れる
movwf TRISA ;wレジスタの値をTRISAに入れる
のように書きます。
これでPORTAの全ビットが入力になります。
CONFIGもレジスタなのですが、movwfなどの命令を使って設定することはできません。
CONFIGにはプログラムが実行されるよりも以前に設定が必要な最も基本的な機能を設定します。
たとえば、CPUクロックを外付けのクリスタル発振から入力するか、それとも内蔵発振によって得るか、とかプログラムのコピープロテクトをかけるかどうか、などの設定です。
CONFIGの設定はこの項の最初のところに書きましたように、あらかじめ決められた書き方で行います。
このCONFIGの表記方法がPIC16FとPIC18Fでは大きく異なっています。
たとえばPIC16F628などでは、
__CONFIG _WDT_ON & _PWRTE_ON & _INTRC_OSC_CLKOUT & _LVP_OFF & _MCLRE_ONのように表記してきました。
; The following is an assignment of address values for all of the ; configuration registers for the purpose of table reads _CONFIG1L EQU H'300000' _CONFIG1H EQU H'300001' _CONFIG2L EQU H'300002' _CONFIG2H EQU H'300003' _CONFIG3H EQU H'300005' _CONFIG4L EQU H'300006' _CONFIG5L EQU H'300008' _CONFIG5H EQU H'300009' _CONFIG6L EQU H'30000A' _CONFIG6H EQU H'30000B' _CONFIG7L EQU H'30000C' _CONFIG7H EQU H'30000D' ;----- CONFIG1L Options -------------------------------------------------- _PLLDIV_1_1L EQU H'F8' ; No prescale (4 MHz oscillator input drives PLL directly) _PLLDIV_2_1L EQU H'F9' ; Divide by 2 (8 MHz oscillator input) _PLLDIV_3_1L EQU H'FA' ; Divide by 3 (12 MHz oscillator input) _PLLDIV_4_1L EQU H'FB' ; Divide by 4 (16 MHz oscillator input) _PLLDIV_5_1L EQU H'FC' ; Divide by 5 (20 MHz oscillator input) _PLLDIV_6_1L EQU H'FD' ; Divide by 6 (24 MHz oscillator input) _PLLDIV_10_1L EQU H'FE' ; Divide by 10 (40 MHz oscillator input) _PLLDIV_12_1L EQU H'FF' ; Divide by 12 (48 MHz oscillator input)
それではということで、_CONFIG1Hや_PLLDIV_1_1Lなどを使って書くとみごとにエラーになってしまいます。
ううう。わからん。なぜだ?
ということで、当初はしっかりと悩んでしまったものなのですが。
実はP18F2550.incの、その部分よりも少し上のところに、このように書いてあります。
;========================================================================== ; ; IMPORTANT: For the PIC18 devices, the __CONFIG directive has been ; superseded by the CONFIG directive. The following settings ; are available for this device. ; ; PLL Prescaler Selection bits: ; PLLDIV = 1 No prescale (4 MHz oscillator input drives PLL directly) ; PLLDIV = 2 Divide by 2 (8 MHz oscillator input) ; PLLDIV = 3 Divide by 3 (12 MHz oscillator input) ; PLLDIV = 4 Divide by 4 (16 MHz oscillator input) ; PLLDIV = 5 Divide by 5 (20 MHz oscillator input) ; PLLDIV = 6 Divide by 6 (24 MHz oscillator input) ; PLLDIV = 10 Divide by 10 (40 MHz oscillator input) ; PLLDIV = 12 Divide by 12 (48 MHz oscillator input) ;
むむ。PIC18Fでは、__CONFIGではなくて、CONFIGを使え、とのご託宣であります。
パラメータの表記につきましても_PLLDIV_1_1Lではなくて、PLLDIV=1のように書け、とおっしゃってみえまする。
んでも、PLLDIV=1はしっかりとコメントアウトされているじゃありませんか。
その一方、_PLLDIV_1_1Lは普通に参照可能なかたちで置かれているわけでしょう。
なんで、それが参照できなくて、コメントアウトしてある方が参照されてしまうのさ。
それってルール違反じゃありませんかあ。
って、メーカーに文句を言ったって、メーカーは創造主であらせられますから、これはもう仕方の無いことです。
ともかく、PIC18Fについては、そのように書かなければアセンブラが通してくれませんので、そのように書くようにいたします。
ですから、前回もお見せしましたように、PIC18F2550テストプログラムのそこのところは、
CONFIG FOSC=INTOSC_EC,WDT=OFF,LVP=OFF,MCLRE=OFF
と書くことになります。
これで書き方はわかりましたけれど、しかし、それだけでは、いったいなんのこっちゃ、で意味不明のままですから、次はパラメータについて説明しなければなりません。
でも、その前に。
●PIC16F88について、MPLABのバグではありませんでした
以前、PIC16F88がMPLABでアセンブルするとエラーになってしまう([第410回])、と書いたことを、突然に思い出しました。
PIC16F88のために書いたテストプログラムなのですけれど、MPLABのConfigure→Select Deviceで、PIC16F88を選択してアセンブルすると、「CONFIGの表記が間違っている」とか何とか、そんなようなエラーメッセージが出てしまいます。
で、仕方が無いのでデバイスの設定を16F628にしておいて(これはウソなのですけれど)、アセンブルすると今度はエラーが出ないで正しくアセンブルされてHEXファイルが出来あがります。
ところが、そのHEXファイルを秋月のPICプログラマでPIC16F88に書き込もうとしますと、ここでも「CONFIGレジスタの設定ができていない」のような警告が出てしまいます。
それもこれもみんなバグですう、と書きました。
でも、ひょっとしたら…。
突然にひらめいてしまいましたので、p16f88.incを読んでみました。
おやまあ。
ちゃんと書いてありました。
; To use the Configuration Bits, place the following lines in your source code ; in the following format, and change the configuration value to the desired ; setting (such as CP_OFF to CP_ALL). These are currently commented out here ; and each __CONFIG line should have the preceding semicolon removed when ; pasted into your source code. ;Program Configuration Register 1 ; __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC ;Program Configuration Register 2 ; __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
まあご丁寧に、必要なところだけ直して(たとえばCP_OFFをCP_ALLにするように)、セミコロンを取ってコピー&ペーストしなさい、ですって。
PIC16F88はCONFIGではなくて、CONFIG1、CONFIG2と2つのCONFIGレジスタになったために、16F628などのように、__CONFIGだけの設定ではだめ、だったのです。
バグではありませんでした。
ちゃんと読まなかった私がダメだったのです。
おお。ひょっとしますと、秋月のPICプログラマで出たあの警告メッセージも、CONFIG1、CONFIG2の設定がまともにできていなかったために出されたのかも…。
ということで、[第410回]のテストプログラムを、ああ、それをちょいと直した[第411回]のプログラム(test6.asm)ですけれど、それもバグがありましたので([第416回])、そこのところも直したうえでCONFIGの表記も訂正いたしました。
;;;PIC 16F88 testprogram test6.asm ;09/12/31 10/01/02 1/9 4/27 ;clock=4MHz #include <p16f88.inc> ; ;Program Configuration Register 1 __CONFIG _CONFIG1,_CP_OFF & _LVP_OFF & _WDT_OFF & _INTRC_IO __CONFIG _CONFIG2, ; org 00 goto start ; org 05 start bsf STATUS,5 ;bank 1 movlw 6c;=4MHz movwf OSCCON movlw 0;port=out movwf TRISB bcf STATUS,5;bank 0 movlw 1 loop xorwf PORTB goto loop ; end ;
このようにしましたところ、Configure→Select Deviceで、PIC16F88を選択してアセンブルしても、エラーにならずに正しくアセンブルできました。
そしてそのようにしてできあがったHEXファイルを、秋月のPICプログラマでPIC16F88に書き込んでみましたところ、今度はなんの警告メッセージも出ないで、普通に書き込みできてしまいました。
なお、上記ソースプログラムリストの、
__CONFIG _CONFIG2,