PIC18F47Q43のUARTで悩む

PIC18F47Q43をZ80につないでIC2個のみのコンピュータを作ろうと考えている。PICはZ80に対し、NCOでクロックを生成、ポートでリセットして起動、Z80からアクセスが来たらCLCでウェイトを出しておいてベクタ割り込みでメモリやUARTの働きをする。UARTを除くモジュールの雑なテストはすでに成功。ところが、ちょろいと思ったUARTがダメ。PICで普通に動かしてみるだけの試みがいまだ成功していない。

UARTのテストは慣例にしたがい端末にハローワールドを表示したあと入力のエコーバックをやってみるやつ。ハローワールドは成功。しかし入力のエコーバックができない。見てもしかたがないと思うが、いちおうスクショを貼っておく。受信ピンは製造元推奨のRA7、初期設定から受信までマニュアルどおりの手順。不幸中の幸いで送信はできるからあちこちのフラグを表示してみたら入力をしても受信可フラグが立たない模様。

ソフトウェアに間違いが見付からないのでハードウェアをテスト。RA7にLEDをつなぎ、ビデオカメラで撮影しながら端末のキーを押し、コマ送りして見るとLEDが一瞬点灯している。すなわち、入力した信号はRA7に届いており、ハンダ不良などハードウェアに起因する誤りもなさそう。結局、思いつく限りの怪しいところを全部調べて何ひとつ間違いがないのに受信をやらないという、たいへん困った状況に直面している。

デバッグが難航するとついシリコンエラータを疑ってしまう。これはまずい。自分以外の何かが悪いと考える癖がついたら今後ほかの問題も解決できない。そろそろ決着を付けようと思い、最後にもう1回、余ったプリント基板で最初から組み立てた。部品は必要最小限にとどめてミスの紛れ込む余地を減らす。RA7には信号が電源へ回り込むのを防ぐ回路があり、これも確実に迂回したいので、安直な方法として受信ピンをRA5に切り替えた。

結果がこちら。あら不思議、RA5がちゃんと受信をやっている。信号が電源へ回り込むのを防ぐ回路が悪さをしていたのかと思い、RA5にもそれをつないでみたが、やはり正しく動く。その後あれこれ確認したら、RA7で受信したときだけがNGで、ほかはすべてOK。とにかく動いたのだから、それに沿ってプリント基板を作り直せばいい。現状のプリント基板は書き込み端子が裏返しになっていて、いずれにしろ作り直しが確定なのだ。

RA7で受信するとNGで、ほかがOKな理由は、まったくわからない。誰かが指摘してくれたら嬉しいから情報をまとめておく。ハードウェアは送受信とも信号をピンに直結したので間違えようがない。ソフトウェアは全体をGistに貼り抜粋を下に示す。抜粋はブログの調子がいいと行番号を表示する。その行番号で30~32のコメントアウトしてあるところがRA7による受信、34~36がRA5による受信。さあRA7とRA5の違いはどこだ。

#include <xc.h>
#include <stdio.h>

// UART3 Transmit
void putch(char c) {
    while(!U3TXIF); // Tx interrupt flag not set
    U3TXB = c;
}

// UART3 Recive
char getch(void) {
    while(!U3RXIF); // Rx interrupt flag not set
    return U3RXB;
}

void main(void) {
    // System initialize
    OSCFRQ = 0x08; // 64MHz internal OSC

    // UART3 initialize
    U3BRG = 416; // 9600bps @ 64MHz
    
    U3TXEN = 1; // Transmitter enable
    U3RXEN = 1; // Receiver enable
    
    RA6PPS = 0x26;  // RA6->UART3TX
    TRISA6 = 0; // TX set as output
    ANSELA6 = 0; // Disable analog function

//    U3RXPPS = 0x07; // UART3RX->RA7
//    TRISA7 = 1; // RX set as input
//    ANSELA7 = 0; // Disable analog function

    U3RXPPS = 0x05; // UART3RX->RA5
    TRISA5 = 1; // RX set as input
    ANSELA5 = 0; // Disable analog function
    
    U3ON = 1; // Serial port enable
    
    printf("hello, world\r\n");
    while(1) putch(getch()); 
}

ボクが間違っているという指摘がないか、間違っていないと言ってもらえたら、そのときはシリコンエラータを疑ってもいいと思う。今そういう報告をどこで受け付けているのか調査中。にしてもさ、世界中で無数に使われているであろう製品の、こんなにあからさまな問題をボクが最初に報告するなんて、ちょっと考えられないよね。ボクが間違っていたときごめんなさいをいう心の準備のほうが優先かもね。

[2022/1/14追記]
ツイッターのほうにskyriverさんからご指摘があり、ボクの間違いが判明しました。コンフィグのFEXTOSCをOFFにしたらRA7で受信しました。ありがとうございます。Gistに貼った全ソースの1行目(行番号5)でやらかしています。お騒がせ致しました。

カテゴリー: PIC, Z80, 世間話 パーマリンク

コメントを残す