0

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 を掘り下げる必要があるかもしれません。

4

1 に答える 1

1

比較 ( double == ) ではなく代入 (single =) で for ループ変数を初期化してみてください

使用する

for(c1=0; c1<12; c1++){
    for(c2=0; c2<2; c2++){

それ以外の

for(c1==0; c1<12; c1++){
    for(c2==0; c2<2; c2++){
于 2013-02-14T17:09:20.933 に答える