//******************************** D E K L A R A T I O N E N ************************************** #include "int16CXX.H" // Notwendig für Interrupts #include "INLINE.H" // Notwendig für Assembler Befehle #define LCD_D6 PORTA.4 #define LCD_D7 PORTA.5 #define LCD_D5 PORTC.2 #define LCD_RS PORTC.3 #define LCD_E PORTC.4 #define LCD_D4 PORTC.5 unsigned char x; // unsigned char z; // unsigned char z2; // unsigned char LCD_DATA; // void AUSGABE(void); void LCD_INIT(void); void LCD_ZEICHEN(unsigned char zeichen); void LCD_BEFEHL(unsigned char befehl); //void LCD_BUSY(void); void LCD_STRING(const char *pString); void VERZ100US(unsigned char VerzZeit); //******************************** K O N F I G U R A T I O N ************************************** void INIT (void) { #pragma config |= 0b.11000111010100 // WDT aus & INTOSC an OSCCAL = 0x3414; // Kalibrierwert für internen Oszillator CMCON = 0b.0000.0111; // Pins auf Digital umschalten ANSEL = 0b.0000.0000; // Pins auf Digital umschalten TRISA = 0b.00.0011; // PortA 0...1 Eingänge, 2...5 Ausgänge TRISC = 0b.00.0110; // PortC 1...2 Eingänge, 0, 3...5 Ausgänge PORTA = 0b.00.0000; // PortA rücksetzen PORTC = 0b.00.0000; // PortC rücksetzen OPTION = 0b.1000.0001; // Pull-Ups aus & Vorteiler Timer0 auf 4 einstellen INTCON = 0b.0000.0000; // Interrupts sperren z = 0; z2 = 0; } //******************************** H A U P T P R O G R A M M ************************************** void main (void) { INIT (); // Konfiguration für PIC aufrufen LCD_INIT(); // LC-Display initialisieren endlosschleife: x = !x; while(1) { AUSGABE(); // Text (und/oder Werte) am Display ausgeben VERZ100US(200); // > 15 ms warten } goto endlosschleife; } /****************** Unterprogramme zur LCD-Ansteuerung **********************************/ /****************************************************************************************/ void AUSGABE(void) { LCD_BEFEHL(0x01); // Display loeschen LCD_ZEICHEN('H'); LCD_ZEICHEN('a'); LCD_ZEICHEN('l'); LCD_ZEICHEN('l'); LCD_ZEICHEN('o'); LCD_ZEICHEN(0x20); // Leerzeichen LCD_ZEICHEN('.'); LCD_ZEICHEN('.'); LCD_ZEICHEN('.'); LCD_BEFEHL(0xC0); // 2.Zeile LCD_STRING("... wie geht's?"); } /****************************************************************************************/ void LCD_INIT(void) { LCD_RS = 0; // Alle LCD-Steuerleitungen LOW LCD_E = 0; VERZ100US(250); // 250 ms warten LCD_D4 = 1; // Befehl für 8-Bit-Interface LCD_D5 = 1; LCD_D6 = 0; LCD_D7 = 0; LCD_E = 1; // Befehl an LCD LCD_E = 0; // (durch toggeln der LCD-Enable-Leitung) VERZ100US(10); // 100 ms warten LCD_E = 1; // Befehl (8-Bit-Interface) wiederholen LCD_E = 0; // (durch toggeln der LCD-Enable-Leitung) VERZ100US(10); // 100 ms warten LCD_E = 1; // Befehl (8-Bit-Interface) wiederholen LCD_E = 0; // (durch toggeln der LCD-Enable-Leitung) VERZ100US(10); // Sicherheitshalber warten LCD_D4 = 0; // Befehl für 4-Bit-Interface LCD_D5 = 1; LCD_D6 = 0; LCD_D7 = 0; LCD_E = 1; // Befehl an LCD LCD_E = 0; // (durch toggeln der LCD-Enable-Leitung) LCD_BEFEHL(0x01); // Display löschen und Cursor home LCD_BEFEHL(0x28); // 4 Bit, 2 Zeilen, 5x7 LCD_BEFEHL(0x08); // Display aus, Cursor aus, Blinken aus LCD_BEFEHL(0x06); // Shift aus LCD_BEFEHL(0x0C); // Display ein } /****************************************************************************************/ void LCD_BEFEHL(unsigned char befehl) { unsigned char temp; // LCD_BUSY(); // Warten bis LCD bereit ist VERZ100US(250); // Sicherheitshalber warten LCD_DATA = LCD_DATA & 0x0F; // Höherwertigeres Nibble löschen temp = befehl & 0xF0; // Höherwertiges Nibble ausmaskieren LCD_DATA = LCD_DATA | temp; // High-Nibble an LCD übergeben if(LCD_DATA.7 == 1) LCD_D7 = 1; else LCD_D7 = 0; if(LCD_DATA.6 == 1) LCD_D6 = 1; else LCD_D6 = 0; if(LCD_DATA.5 == 1) LCD_D5 = 1; else LCD_D5 = 0; if(LCD_DATA.4 == 1) LCD_D4 = 1; else LCD_D4 = 0; LCD_RS = 0; // LCD im Befehl-Mode LCD_E = 1; // Enable (LCD) LCD_E = 0; // toggeln LCD_DATA = LCD_DATA & 0x0F; // Höherwertigeres Nibble löschen SWAPF(befehl,1); // Höherwertige- und Niederwertige Nibbles vertauschen temp = befehl & 0xF0; // Niederwert. Nibble ausmaskieren LCD_DATA = LCD_DATA | temp; // High-Nibble an LCD übergeben if(LCD_DATA.7 == 1) LCD_D7 = 1; else LCD_D7 = 0; if(LCD_DATA.6 == 1) LCD_D6 = 1; else LCD_D6 = 0; if(LCD_DATA.5 == 1) LCD_D5 = 1; else LCD_D5 = 0; if(LCD_DATA.4 == 1) LCD_D4 = 1; else LCD_D4 = 0; LCD_E = 1; // Enable (LCD) LCD_E = 0; // toggeln } /****************************************************************************************/ void LCD_ZEICHEN(unsigned char zeichen) { unsigned char temp; // LCD_BUSY(); // Warten bis LCD bereit ist VERZ100US(250); // Sicherheitshalber warten LCD_DATA = LCD_DATA & 0x0F; // Höherwertigeres Nibble löschen temp = zeichen & 0xF0; // Höherwertiges Nibble ausmaskieren LCD_DATA = LCD_DATA | temp; // High-Nibble an LCD übergeben if(LCD_DATA.7 == 1) LCD_D7 = 1; else LCD_D7 = 0; if(LCD_DATA.6 == 1) LCD_D6 = 1; else LCD_D6 = 0; if(LCD_DATA.5 == 1) LCD_D5 = 1; else LCD_D5 = 0; if(LCD_DATA.4 == 1) LCD_D4 = 1; else LCD_D4 = 0; LCD_RS = 1; // LCD im Daten-Mode LCD_E = 1; // Enable (LCD) LCD_E = 0; // toggeln LCD_DATA = LCD_DATA & 0x0F; // Höherwertigeres Nibble löschen SWAPF(zeichen,1); // Höherwertige- und Niederwertige Nibbles vertauschen temp = zeichen & 0xF0; // Niederwert. Nibble ausmaskieren LCD_DATA = LCD_DATA | temp; // High-Nibble an LCD übergeben if(LCD_DATA.7 == 1) LCD_D7 = 1; else LCD_D7 = 0; if(LCD_DATA.6 == 1) LCD_D6 = 1; else LCD_D6 = 0; if(LCD_DATA.5 == 1) LCD_D5 = 1; else LCD_D5 = 0; if(LCD_DATA.4 == 1) LCD_D4 = 1; else LCD_D4 = 0; LCD_E = 1; // Enable (LCD) LCD_E = 0; // toggeln } /****************************************************************************************/ void LCD_STRING(const char *pString) { char zeichen; zeichen = *pString; while(zeichen > 0) { LCD_ZEICHEN(zeichen); // zeichen am LC-Display ausgeben pString++; // Zeiger um 1 erhoehen, er zeigt nun auf das // nächste Zeichen der auszugebenden Zeichen- // kette zeichen = *pString; // Den Inhalt dieses Zeigers in die Variable } // zeichen kopieren. } /****************************************************************************************/ void VERZ100US(unsigned char VerzZeit) { unsigned char temp; #asm top movlw .110 // timing adjustment variable (1ms) movwf temp top2 nop // sit and wait nop nop nop nop nop decfsz temp, F // inner loops complete? goto top2 // no, go again decfsz VerzZeit, F // outer loops complete? goto top // no, go again retlw 0 // yes, return from subWAIT #endasm }