RX62N 用FM音源プログラム -- TGRX62N (4)
RX62N 基板にキャラクタ LCD / 入力スイッチをつなぐのに、どういう方法をとろうか迷っていましたが、8 ビット MCU を介在させて接続することにしました。
LCD 表示させた基板の写真を下に示します。
キャラクタ表示 LCD の R/W 信号を GND レベルに固定し、ライト・オンリで 4 ビット・モードでインターフェースした場合でも、LCD との接続は DB7 〜 DB4、RS、E の合計 6 本の信号線が必要です。
ライト・オンリなので、LCD 側から信号線をドライブされることはありませんが、E 以外の 5 本の線は PMOS による弱いプルアップがされているので、マイコン側が 3.3 V 電源、LCD 側が 5 V 電源の場合に、マイコン側の出力端子が 5 V に向かってプルアップされることになります。
プルアップは抵抗値に換算すると数十 kΩ の程度なので、デバイスを破壊するようなことはなく、保護回路で十分吸収される程度のものですが、気持ち良くはありません。
LCD 側も 3.3 V 電源で使用すれば問題ありませんが、次のような理由で LCD 側は 5 V 電源で使用する方がメリットがあります。
- 液晶デバイスのバイアス電圧 (Vo) は Vdd 基準で -4 V 程度になるので Vdd = 3.3 V だと Vo に -1 V 程度のマイナス電圧が必要になる
5 V 電源の LCD を 3.3 V 電源のマイコンで「安心」して使うには 5V トレラント対応のポートを使うか、レベル変換用バッファを介することになります。
インターフェース誌 2011 年 5 月号の pp.70 〜 71 のコネクタ・ピン配置一覧表には、LCD 拡張ボードと組み合わせて使う場合の信号名が併記されています。
これを見ると、ほとんどの信号線は拡張ボードで使われており、空欄となっていて使われいないと思われる信号線は 4 本ほどしかありません。
拡張ボードの価格はインターフェース本誌の価格の 10 倍以上であり、決して購入することはないと思うので、実際のところは分かりませんし、回路図も公開されていないので、「未割り当て」の信号線だけを使うことにしました。
未割り当ての信号線だけでは、LCD インターフェースに必要な 6 本の信号線を確保できないので、8 ビット MCU を介在させ、RX62N 基板とのインターフェースは調歩同期式のシリアル形式で行うことにしました。
このために、
- P00 / TxD6-A (CN2-29)
- P01 / RxD6-A (CN2-30)
の 2 本の 5 V トレラント IO を使います。
5 V トレラントなので、安心して LCD モジュールと 8 ビット MCU を 5 V 電源で使えます。
FM音源プログラムでは、約 2 ms に一回のレートで 4 ビット・モードの LCD への書き込みを行っています。
後に示すように、8 ビット MCU として PIC16F628 を内蔵 4 MHz RC クロックで動作させているので、ボーレイトとして 1 [MHz] / 64 = 62.5 [kbps] の設定にしています。
データのフォーマットとしては、RX62N 基板側からは、単純に RS、D7 〜 D4 の 5 ビットをシリアルで渡すだけとし、LCD の E 信号については 8 ビット MCU 側で自動作成することにしました。
5 ビット・データは LSB 側に詰め、上位 3 ビットの「空き」のデータには、ストップ・ビットの値と同じ「1」を詰めています。
これは、実質的にデータ長が 5 ビットのフォーマットとすることで、全体のビット長を短くし、ボーレイトの誤差の影響を受けにくくするためです。
入力スイッチの状態についても、チャタリング除去などはせずに、単純にスイッチの接続されたポートを読み出し、シリアルで RX62N 基板側に送るようにしました。
8 ビット MCU では、RX62N 基板側からの LCD データを受信するたびに、スイッチ・データを送信するようにしてあります。 自発的には RX62N 基板側には送信しません。
この 8 ビット MCU として、手持ちの PIC16F628 (18 ピン) を使った場合の回路を下に示します。
後で示すように、MCU のプログラムは非常に簡単なので、LCD への信号線が確保できるだけのピン数があるチップなら何でも実現可能だと思います。
AVR についても、手持ちの ATtiny2313 (20 ピン) を使って実験したいと思っています。
RX62N も PIC16F628 も、シリアルで 9 ビット・データを送受できるモードがあるので、8 ビット・モードでの LCD とインターフェース可能ですが、配線が 4 本増えることと、ボーレイト誤差の影響を受けやすくなるために 8 ビット・モードは採用しませんでした。
ちなみに、PIC16F628 の 4 MHz 内部 RC クロックを 4 分周したクロックを外部に出力する config で実測したところ、約 973 kHz、つまり約 -3 % のクロック誤差となっていて、ビット長が長くなるとマージンが少なくなります。
最後に PIC16F628 用のプログラムを示します。
; ; lcd4uart: 4-bit mode character LCD and keySW I/F ; using UART (62.5 kbps) to HOST ; ; 2011-Apr-19, created by pcm1723 ; ; CLOCK FREQUENCY: 4 MHz (internal RC osc) ; ; INPUT SIGNAL: ; ; RB1/RX (Pin 7) -- connect to HOST TxD ; ; OUTPUT SIGNAL: ; ; RA4 (Pin 3) -- connect to LCD RS ; RA3 (Pin 2) -- connect to LCD DB7 ; RA2 (Pin 1) -- connect to LCD DB6 ; RA1 (Pin 18) -- connect to LCD DB5 ; RA0 (Pin 17) -- connect to LCD DB4 ; ; RB0 (Pin 7) -- connect to LCD E ; ; RB2/TX (Pin 8) -- connect to HOST RxD ; processor pic16f628 ; List p=pic16f628,f=inhx8m include "p16f628.inc" __config _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_OFF ; udata 0020h rxdata res 1 ; Rx data buffer txdata res 1 ; Tx data buffer ; ; code 0000h goto start ; reset vector res 1 res 1 res 1 goto start ; interrupt vector ; start: call port_setup ; setup for PORT call usart_setup ; setup for USART and BRG banksel PIR1 ; PIR1, RCREG, PORTA, ; PORTB, TXREG on BANK0 rxloop0: btfss PIR1,RCIF ; skip if RCIF=1 (RCREG full) goto rxloop0 ; loop if RCIF=0 (RCREG empty) movfw RCREG ; read the received data movwf PORTA ; out data to LCD RS, D7..D4 bsf PORTB,0 ; output '1' to LCD_E (RB0) swapf PORTB,w ; PORTB[7:4] --> w[3:0] iorlw b'11110000' ; fill "1" in w[7:4] movwf TXREG ; output to USART txloop1: banksel TXSTA ; TXSTA on BANK1 btfss TXSTA,TRMT ; skip if TRMT=1 (TSR empty) goto txloop1 ; loop if TRMT=0 (TSR full) banksel PORTB ; PORTB, PIR1 on BANK0 bcf PORTB,0 ; output '0' to LCD_E (RB0) goto rxloop0 ; ; ; port setup for LCD interface ; port_setup: banksel TRISA ; TRISA, TRISB, OPTION on BANK1 bcf TRISA,4 ; RA4 output enable (LCD RS) bcf TRISA,3 ; RA3 output enable (LCD DB7) bcf TRISA,2 ; RA2 output enable (LCD DB6) bcf TRISA,1 ; RA1 output enable (LCD DB5) bcf TRISA,0 ; RA0 output enable (LCD DB4) bcf TRISB,0 ; RB0 output enable (LCD E) bcf TRISB,2 ; RB2/TX output enable bcf OPTION_REG,NOT_RBPU ; enable PB weak pull up banksel PORTB ; PORTB on BANK0 bcf PORTB,0 ; RB0 = '0' (LCD E) return ; ; setup for USART and Baud Rate Generator ; for 62.5 kbps at 4 MHz osc ; usart_setup: movlw b'00100000' ; TX enable, async, BRGH=0 banksel TXSTA ; TXSTA, SPBRG on BANK1 movwf TXSTA ; set Tx config movlw d'0' ; 4 [MHz]/64/(0+1)=62.5 [kbps] movwf SPBRG ; set Baud rate movlw b'10010000' ; SPEN=1, CREN=1 banksel RCSTA ; RCSTA on BANK0 movwf RCSTA ; set Rx config return ; end