Stackoverflow、あなたは以前私を助けてくれました。またあなたの助けが必要だと思います。PIC18F2550 で GPIO を使用して自分のシリアル出力をビットバンしようとしています。これはいくつかのシフト レジスタ (3x74LS595) に接続され、最後のシフト レジスタは標準の HD44780 LCD に接続されます。これまでのところ、クロッキングとラッチは正しく機能しており、長い戦いの後、データも正しく吐き出されています (バレルシフトがうまくいかず、範囲外のデータを喜んで吐き出しますが、余談)。
私の問題は、LCD を使用するには、イネーブル ピンをデータ クロックとしてトグルする必要があることです。そのため、コードを保存するために、2 回実行してイネーブル フラグをトグルする別のループを単純にネストし、それ以外の場合は同じバイトを吐き出します。これにより、理論的には吐き出されるバイト数が 12 から 24 の 2 倍になるはずです。何らかの理由で、このループが追加されると機能しません。2バイトを吐き出して終了します。それがなければ、12 バイトすべてを正常に吐き出します (ただし、有効化が存在しないため、LCD は適切にセットアップされません)。
ネストされた有効化ループなしで動作している画像を次に示します。
D0 はデータで、その下の D1/2 はそれぞれクロック/ロードです。
そして、ここに for ループがあります:
左端のエッジは、ラインの初期リセットです。意味のあるコードがすべて完了したことを示す小さなブザーが鳴るので、これらの 2 バイトの後に完了したことがわかります。
コードダンプは次のとおりです。
//First testing program for PIC18F2550
#include <p18f2550.h>
#include <stdlib.h>
#include <delays.h>
#define _XTAL_FREQ 4915200
#pragma config PLLDIV = 1
#pragma config CPUDIV = OSC1_PLL2
#pragma config FOSC = XT_XT
#pragma config MCLRE = ON
#pragma config BOR = OFF
#pragma config WDT = OFF
#pragma config IESO = OFF
#pragma config PBADEN = OFF
#pragma config LVP = OFF
unsigned char setupstream[12] = {0b0011, 0b0011, 0b0011, 0b0010, 0b0010, 0b1000, 0b0000, 0b0001, 0b0000, 0b1111, 0b0000, 0b0110};
unsigned char teststream[6] = {0xF0, 0x00, 0xFF, 0x00, 0xFF, 0x00};
unsigned char letterstream[2] = {0b0010, 0b0001};
unsigned char c1 = 0, c2 = 0, c3 = 0, outreg = 0, outmask = 0, feedout = 0;
void main(void){
//CONFIG4L = 0b01000001;
UCONbits.USBEN=0;
UCFGbits.UTRDIS=1;
//OSCCONbits.IRCF2=1;
//OSCCONbits.IRCF1=1;
//OSCCONbits.IRCF0=1;
OSCCONbits.SCS1 = 0;
OSCCONbits.SCS0 = 0;
BAUDCONbits.TXCKP=0;
SPBRG = 0x3F; //1200 baud
TRISA = 0x00;
TRISB = 0xFF;
TRISC = 0x00;
LATCbits.LATC0 = 1; //Start: beep the speaker
Delay10KTCYx(8);
LATCbits.LATC0 = 0;
Delay10KTCYx(8);
LATA = 0; //reset
Delay10KTCYx(8);
LATAbits.LATA2 = 1; //load the reset
Delay10KTCYx(8);
LATAbits.LATA3 = 1; //stop reset
LATAbits.LATA2 = 0;
Delay10KTCYx(123);
for(c1==0; c1<12; c1++){
for(c2==0; c2<2; c2++){
outreg = setupstream[c1] << 2; //nibble of data needs to be in the middle
//outreg |= 0b00000010; //set flags
//outreg ^= 0b00000001;
outmask = 0x80;
for(c3=0; c3<8; c3++){
LATAbits.LATA0 = (outreg & outmask) ? 1:0;
outmask >>=1;
Delay10KTCYx(8);
LATAbits.LATA1 = 1; //clock the data out
Delay10KTCYx(8);
LATAbits.LATA1 = 0;
}
Delay10KTCYx(8);
LATAbits.LATA2 = 1; //one byte fed out; load it into shift regs
Delay10KTCYx(8);
LATAbits.LATA2 = 0;
}
}
LATAbits.LATA0 = 0; //Done, clear the line and
LATCbits.LATC0 = 1; //Beep the speaker
Delay10KTCYx(8);
LATCbits.LATC0 = 0;
Delay10KTCYx(8);
while(1){ //Idle
}
}
上記のコードでは、トグルを無効にして、すべてのバイトが吐き出されるかどうかを確認しました。ないと思います。私はこれをすべてアセンブリで行うことを真剣に考えています。なぜなら、C では一見単純なもので多くの問題を抱えていたからです。このことの背景で何が起こっているのか、私にはコントロールできないように感じます。私は Pickit 3 を使用していますが、実際に何が起こっているのかをよく知りたい場合は、ICD2 を掘り下げる必要があるかもしれません。