2015-09-01 5 views
0

Я использую dspic33fj128mc802 с mplab xc16. Я хочу использовать ЖК-дисплей в режиме 4 бит, но, похоже, он не инициализирует его и не знает, что я делаю неправильно. Любая помощь будет оценена при отладке. Я посмотрел на других примерах и мой код похож на другой, но по-прежнему не будет работатьdspic33f 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); 

    } 
} 
+0

Где вы застряли? Скомпилирует ли он? Можете ли вы предоставить более подробную информацию о том, как это не работает? –

+0

На данный момент не похоже, что он инициализирует ЖК-дисплей. Код компилируется, и я могу пройти через бит. Я не могу найти ошибку. ЖК-дисплей 16x2, и в настоящее время только первая строка отображает все черные блоки – JBH

ответ

0

Таким образом, код компилируется, вы можете пройти через него (предположительно с отладчиком внутрисхемным), но это не делает что вы ожидаете. Описание, которое вы указали в этой проблеме, а точнее, несоответствие между фактическим и ожидаемым поведением заключается в том, что ЖК-дисплей не кажется инициализированным, и он отображает нечто иное, чем вы ожидаете.

Чтобы отладить это, разложите проблему. Проверьте свои предположения и ожидания. Я предлагаю вам пройти через программу и проверить каждую инструкцию (по крайней мере, на начальном этапе), что программа делает то, что вы ожидаете. Если что-то еще происходит, выясните, почему, попробуйте исправить и снова проверьте. Теперь это быстро станет утомительным, поэтому используйте контрольные точки или «бегите к курсору» в отладчике, чтобы пропускать разделы с хорошо известными разделами и дома в разделах, находящихся под пристальным вниманием.

Ваш 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-битный двоичный литерал параметра полукокса, верхние 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 - 0b0010, и это «побитовое» значение со значением _LATA4, то есть 0 или 1 (но назовем его Y), поэтому вы назначаете 0b001Y. Теперь, думаю, что вы намерены установить строки данных на верхнем полубайте cmd и бит LCD_EN. Но в C вы не можете сделать это таким образом.

    3.2. Глядя на левую сторону, вы назначаете это только _LATB12 - оператор запятой не делает то, что вы, по-видимому, думаете.Не зная, как xc16 обрабатывает назначения int для битовой переменной (бит является нестандартным), я бы предположил, что вы либо назначаете 1, потому что значение отличное от нуля, либо назначаете LSB, который будет _LATA4

Я собираюсь остановиться там с анализом вашего кода. Надеюсь, это поможет вам в отладке и исправлении кода и, вероятно, вызовет больше вопросов.

Как только вы получите код, который соответствует вашим намерениям и ожиданиям, вы будете готовы к отладке во втором раунде - соответствует ли код (и ваши намерения/ожидания) тому, что ожидает оборудование? Это будет разрешено с помощью аналогичных методов - разложите проблему, проверьте фактическое и ожидаемое поведение, узнайте, является ли это фактическим или ожидаемым поведением, которое требует исправления, исправления и повторного тестирования.

Надеюсь, что это поможет.