1

私は mplab xc16 で dspic33fj128mc802 を使用しています。LCD を 4 ビット モードで使用したいのですが、初期化できないようで、何が間違っているのかわかりません。デバッグの助けをいただければ幸いです。私は他の例を見てきましたが、私のコードは他のものと似ていますが、それでも動作しません

    //LCD Control pins

    #define LCD_RS       _LATB11
    #define LCD_EN       _LATA4

    #define TRIS_EN      TRISAbits.TRISA4    /* TRIS for E */
    #define TRIS_RS      TRISBbits.TRISB11   /* TRIS for RS */

    #define D7           LATBbits.LATB15
    #define D6           LATBbits.LATB14
    #define D5           LATBbits.LATB13
    #define D4           LATBbits.LATB12

    #define D7_TRIS           TRISBbits.TRISB15
    #define D6_TRIS           TRISBbits.TRISB14
    #define D5_TRIS           TRISBbits.TRISB13
    #define D4_TRIS           TRISBbits.TRISB12

    //LCD Data pins
    #define lcdport     _LATB11,_LATA4,_LATB15,_LATB14,_LATB13,_LATB12


    void delay_ms();
    void delay_us();
    void LCD_Init();
    void LCD_Command(char cmd);
    void LCD_ClearDisp();
    void LCD_RetHome();
    void LCD_Display();
    void LCD_ShiftR();
    void LCD_ShiftL();
    void LCD_4BitMode();
    void LCD_Init();


    void delay_ms()
    {
        __delay32(40000);
    }

    void delay_us()
    {
        __delay32(40);
    }

    void LCD_Command(char cmd) //LCD Command routine
    { 
        lcdport = ((cmd >> 4) & 0x0F)|LCD_EN;
        delay_ms(20);
        lcdport = ((cmd >> 4) & 0x0F);
        delay_ms(20);
        lcdport = (cmd & 0x0F)|LCD_EN;
        delay_ms(20);
        lcdport = (cmd & 0x0F);
        delay_ms(20);
     }

    void LCD_ClearDisp()
    {
        delay_ms(20);
        LCD_Command(0b0000000001);
        delay_ms(20);
    }

    void LCD_RetHome() //set cursor to first digit
    {
        delay_ms(20);
        LCD_Command(0b0000000010);
        delay_ms(20);
    }

    void LCD_Display()//disp on, cursor on, blinking on
    {
        delay_ms(20);
        LCD_Command(0b0000001111);
        delay_ms(20);
    }

    void LCD_ShiftR()//shift right
    {
        delay_ms(20);
        LCD_Command(0b000001100);
        delay_ms(20);
    }

    void LCD_ShiftL()//shift right
    {
        delay_ms(20);
        LCD_Command(0b000001000);
        delay_ms(20);
   }

   void LCD_4BitMode()//4 bit mode, 2 line, 5x7 dots
   {
       delay_ms(20);
       LCD_Command(0b0000101000);
       delay_ms(20);
   }

   void LCD_EntrySet()
   {
       delay_ms(20);
       LCD_Command(0b0000000110);
       delay_ms(20);
   }

   void DDRAM_address()
   {
       delay_ms(20);
       LCD_Command(0b0010000000);
       delay_ms(20);
   }
   void LCD_Strobe(void)  //This function pulls the enable line high and then low
   {    
       LCD_EN = 1;
       delay_ms(20);
       LCD_EN =  0;
       delay_ms(20);
   }
  
   void write_lcd(char dat)
   {
       LCD_RS = 1; // RS = 1
       LCD_EN = 1; // E = 1
       lcdport = dat;
       delay_ms(20);
       LCD_EN = 0; // E = 0
       delay_ms(20);
   }

   void LCD_Write_String(char *ptr)
   {
       while(*ptr)
       {
           write_lcd(*ptr);
           delay_ms(1);
           ptr++;
       }
   }

   void LCD_Init()
   {
       delay_ms(20);
       LCD_RS = 0;
       LCD_4BitMode();
       delay_ms(1);
       LCD_Strobe();
       delay_ms(1);
       LCD_Strobe();
       delay_ms(1);
       LCD_Strobe();
       LCD_ShiftR();
       delay_ms(1);
       LCD_EntrySet();
       delay_ms(1);
       DDRAM_address();
       delay_ms(1);
       LCD_ClearDisp();
   }

   int main ()
   {
       while(1)
       {
           LCD_Init();                  //Intilize LCD in 4-Bit Mode
           delay_ms(20);
           LCD_Command(0X80);          // Start Cursor From First Line
           delay_ms(20);
           LCD_Write_String("Hello");  //Print HELLO on LCD
           delay_ms(20);
           LCD_Command(0XC0);         // Start Cursor From Second Line
           delay_ms(20);
           LCD_Write_String("World"); //Print HELLO on LCD
           delay_ms(20);
           LCD_Strobe();
           delay_ms(20);
       }
   }
4

1 に答える 1

0

そのため、コードがコンパイルされ、(おそらくインサーキット デバッガーを使用して) ステップ実行できますが、期待どおりの動作はしません。あなたが問題について述べた説明 - または、実際の動作と予想される動作の不一致は、LCD が初期化されていないようで、期待したものとは異なるものを表示することです。

したがって、これをデバッグするには、問題を分解します。あなたの仮定と期待を確認してください。プログラムをステップ実行し、各命令で (少なくとも最初は) プログラムが期待どおりに動作することを確認することをお勧めします。他の問題が発生した場合は、その原因を突き止め、修正を試みて、もう一度テストしてください。さて、これはすぐに面倒になるので、デバッガーでブレークポイントまたは「カーソルまで実行」を使用して、既知の適切なセクションをスキップし、精査中のセクションに戻ります。

あなたmain()には無限ループが含まれており、ループ本体は の呼び出しで始まるLCD_Init()ので、ここではそれに焦点を当てましょう。以下では、いくつかの呼び出しを「インライン化」したので、プログラムの流れがよくわかります。

void LCD_Init()
{
    delay_ms(20);
    LCD_RS = 0;
    //LCD_4BitMode();
        delay_ms(20);
        //LCD_Command(0b0000101000);
            lcdport = ((cmd >> 4) & 0x0F)|LCD_EN;
            delay_ms(20);
            lcdport = ((cmd >> 4) & 0x0F);
            delay_ms(20);
            lcdport = (cmd & 0x0F)|LCD_EN;
            delay_ms(20);
            lcdport = (cmd & 0x0F);
            delay_ms(20);
        // end of LCD_Command(0b0000101000);
        delay_ms(20);
    // end of LCD_4BitMode();
    /*...*/
}
  1. delay_ms(20);これが実際に20ミリ秒の遅延を行うことを確認しましたか? これを行うには、ピンを設定し、delay_ms(20) を呼び出してピンをクリアし、オシロスコープやロジック アナライザなどでパルス持続時間を測定します。(これは少し基本的なことかもしれませんが、引数なしで定義されているため、これを取り上げました。これによりdelay_ms()、コンパイラーが文句を言うかもしれないと思いました)。delay_ms(20) には複数の呼び出しがあります。後で上記の一部を切り取りました。スキップします。

  2. LCD_RS = 0;これを実行すると実際のピンが変化することを確認しましたか?ピンアップを設定しているのが見えないので、再度お願いします。設定が間違っている可能性があります。

  3. 次に、ステップLCD_Command( 0b0000101000 )インします (ちなみに、10 ビットのバイナリ リテラルを char パラメーターに渡します。上位 2 ビットは渡されません)。そこの最初のステートメントは ですlcdport = ((cmd >> 4) & 0x0F)|LCD_EN;。そのステートメントのプリプロセッサ置換を行いましょう。最終的には次の怪物になり_LATB11,_LATA4,_LATB15,_LATB14,_LATB13,_LATB12 = ((cmd >> 4) & 0x0F)|_LATA4;ます。

    3.1. 代入演算子の右側を見ると、 があり((cmd >> 4) & 0x0F)|_LATA4;ます。cmd >> 4であり、これは の値、つまりor (ただし、Y と呼びましょう) で0b0010「ビット単位の論理和」をとっているため、 を割り当てます。さて、あなたが意図しているのは、データラインを一番上のニブルに設定し、LCD_ENビットを設定することだと思います。しかし、C では、この方法では実行できません。_LATA4010b001Ycmd

    3.2. 左側を見ると、これだけを割り当てます_LATB12- コンマ演算子は、あなたが思っていることをしていません。xc16 がビット変数 (ビットは非標準) への int の代入をどのように処理するかを知らなくても、値がゼロでないために 1 を代入するか、LSB を代入すると推測できます。_LATA4

私はあなたのコードの分析でそこで止まるつもりです。うまくいけば、これでコードのデバッグと修正に取りかかることができ、さらに多くの疑問が生じる可能性があります。

意図と期待に一致するコードを取得したら、第 2 ラウンドのデバッグの準備が整います。コード (および意図/期待) は、ハードウェアが期待するものと一致しますか? これは、同様の手法で解決されます。問題を分解し、実際の動作と予想される動作を確認し、修正が必要なのが実際の動作なのか予想される動作なのかを調べ、修正して再テストします。

それが役立つことを願っています。

于 2015-09-02T18:57:47.490 に答える