#include "msp430x20x3.h" //*** MSP430F2013 mit integriertem RC-Oszillator #define delay_1us() for (_counter1_Delay=0; _counter1_Delay<1; _counter1_Delay++); //*** 9us #define delay_5us() for (_counter1_Delay=0; _counter1_Delay<1; _counter1_Delay++); //*** 9us #define delay_50us() for (_counter1_Delay=0; _counter1_Delay<4; _counter1_Delay++); //*** 52us #define delay_1ms() for (_counter1_Delay=0; _counter1_Delay<90; _counter1_Delay++); //*** 1ms #define delay_5ms() for (_counter2_Delay=0; _counter2_Delay<5; _counter2_Delay++){delay_1ms()}; //*** 5ms #define delay_10ms() for (_counter2_Delay=0; _counter2_Delay<10; _counter2_Delay++){delay_1ms()}; #define delay_50ms() for (_counter2_Delay=0; _counter2_Delay<50; _counter2_Delay++){delay_1ms()}; #define delay_100ms() for (_counter2_Delay=0; _counter2_Delay<100; _counter2_Delay++){delay_1ms()}; #define delay_500ms() for (_counter2_Delay=0; _counter2_Delay<500; _counter2_Delay++){delay_1ms()}; //*** 500ms /*** Anschlussbelegung CPU-Pin LCD-Pin 1-16 P1.1 D4 11 P1.2 D5 12 P1.3 D6 13 P1.4 D7 14 P1.5 RS 4 P1.6 E 6 GND R/W 5 GND GND 1 Vo 3 Kontrast VCC VCC 2 ***/ #define LCDRS_ON P1OUT |= 0x20 //*** RS-Pin setzen //#define LCDRS_ON P1OUT |= (1<<5) #define LCDRS_OFF P1OUT &= 0xDF //*** RS-Pin ruecksetzen //#define LCDRS_OFF P1OUT &= ~(1<<5) #define LCDE_ON P1OUT |= 0x40 //*** E-Pin setzen #define LCDE_OFF P1OUT &= 0xBF //*** E-Pin ruecksetzen #define LCDD4_ON P1OUT |= 0x02 //*** D4-Pin setzen #define LCDD4_OFF P1OUT &= 0xFD //*** D4-Pin ruecksetzen #define LCDD5_ON P1OUT |= 0x04 //*** D5-Pin setzen #define LCDD5_OFF P1OUT &= 0xFB //*** D5-Pin ruecksetzen #define LCDD6_ON P1OUT |= 0x08 //*** D6-Pin setzen #define LCDD6_OFF P1OUT &= 0xF7 //*** D6-Pin ruecksetzen #define LCDD7_ON P1OUT |= 0x10 //*** D7-Pin setzen #define LCDD7_OFF P1OUT &= 0xEF //*** D7-Pin ruecksetzen void lcd_init(void); void lcd_clear(void); void lcd_cmd(unsigned char cmd); void lcd_pos(unsigned char zeile,unsigned char position); void lcd_char(unsigned char data); void lcd_string(const char *str); void lcd_stringpos(char zeile, char pos,const char *str); void lcd_ganzzahl(unsigned int zahl, unsigned int ziffern); void lcd_kommazahl (unsigned int zahl, unsigned int vorkommastellen, unsigned int nachkommastellen); void lcd_e(void); /*** Global Variables **/ unsigned int _counter1_Delay=0,_counter2_Delay=0; //*** fuer Delay int main(void) { // unsigned int temp=0; //*** Hilfsvariable WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR |= 0xff; // Set all ports to output direction //*** LCD initialisieren *** delay_500ms(); lcd_init(); delay_500ms(); delay_500ms(); lcd_clear(); //*** Display loeschen delay_500ms(); delay_500ms(); lcd_char('T'); delay_500ms(); delay_500ms(); //*** Display-Meldung lcd_stringpos(1,1,"Hello World"); for (;;) { volatile unsigned int i; // volatile to prevent optimization P1OUT ^= 0x01; // Toggle P1.0 using exclusive-OR i = 60000; // SW Delay do i--; while (i != 0); } return (0); } void lcd_init(void) { unsigned int i; //*** Schreibsignal vorbereiten LCDRS_OFF; //*** RS-Signal low (RS auf Kontrollregister statt Datenregister) LCDE_OFF; //*** E-Signal low //*** >15ms warten nach anlegen von Vcc bzw. >40ms nach Erreichen von 2.7V: vgl. Datenblatt S.46 oben //*** warten. nicht noetig, da uC-Reset lange genug dauert for(i=0; i<3; i++) //*** 3x function set: vgl. Datenblatt S.46 { //*** setze nur D4 und D5 auf H LCDD4_ON; //*** D4 LCDD5_ON; //*** D5 lcd_e(); //*** E-Signal um zu schreiben delay_5ms(); } //*** Ende Software Reset //*** der erste Schreibzugriff nach Reset ist ein 8 Bit-Zugriff ! //*** also nur einmal schreiben, nicht Low-High Nibble. //*** um die 4Bit Operation einzuschalten //*** Function set fuer 4-bit Interface: D4 auf L, D5 auf H LCDD4_OFF; //*** D4 low, D5 noch high lcd_e(); //*** E-Signal um zu schreiben delay_5ms(); lcd_cmd(0x28); //4 Bit Operation,2 Line,5x7 Font 5 delay_5ms(); lcd_cmd(0x14); //Cursor Move,Right Shift delay_5ms(); lcd_cmd(0x0C); //Display on, Cursor off ,Cursor no blink delay_5ms(); lcd_cmd(0x06); //Increment, Display Freeze delay_5ms(); lcd_cmd(0x02); //Cursor Home delay_5ms(); LCDRS_ON; //LCD-Datenregister delay_10ms(); } //***************************************** // E-Signal um Daten in LCD-Register zu schreiben //***************************************** void lcd_e(void) //*** E-Signal { LCDE_ON; delay_1us(); LCDE_OFF; } //***************************************** // loescht LCD Anzeige // Cursor steht dann auf Position 1, Zeile 1 // auch bei mehrzeiligen Anzeigen //***************************************** void lcd_clear(void) { lcd_cmd(0x01); //*** CLS delay_5ms(); //*** 5ms } //******************************************* // schreibt ein Byte in die LCD-Anzeige // schreibt in zwei 4 Bit Nibbles, RS=0 ! //******************************************* void lcd_cmd (unsigned char cmd) { LCDRS_OFF; //*** RS=0 //*** erst High Nibble bearbeiten: D4,D5,D6,D7 if (cmd&(1>>4)) //*** bit D4 gesetzt? LCDD4_ON; //*** setze D4 am Display H else LCDD4_OFF; //*** setze D4 am Display L if (cmd&(1>>5)) //*** bit D5 gesetzt? LCDD5_ON; //*** setze D5 am Display H else LCDD5_OFF; //*** setze D5 am Display L if (cmd&(1>>6)) //*** bit D6 gesetzt? LCDD6_ON; //*** setze D6 am Display H else LCDD6_OFF; //*** setze D6 am Display L if (cmd&(1>>7)) //*** bit D6 gesetzt? LCDD7_ON; //*** setze D7 am Display H else LCDD7_OFF; //*** setze D7 am Display L lcd_e(); //High Nibble nun schreiben //*** nun Low Nibble bearbeiten: D0,D1,D2,D3 if (cmd&(1>>0)) //*** bit D0 gesetzt? LCDD4_ON; //*** setze D4 am Display H else LCDD4_OFF; //*** setze D4 am Display L if (cmd&(1>>1)) //*** bit D0 gesetzt? LCDD5_ON; //*** setze D5 am Display H else LCDD5_OFF; //*** setze D5 am Display L if (cmd&(1>>2)) //*** bit D0 gesetzt? LCDD6_ON; //*** setze D6 am Display H else LCDD6_OFF; //*** setze D6 am Display L if (cmd&(1>>3)) //*** bit D0 gesetzt? LCDD7_ON; //*** setze D7 am Display H else LCDD7_OFF; //*** setze D7 am Display L lcd_e(); //Low Nibble nun schreiben delay_50us(); //etwas auf die Anzeige warten } //************************************************** // schreibt ein Zeichen in die LCD-Anzeige, RS=1 ! //************************************************** void lcd_char(unsigned char data) { LCDRS_ON; //*** RS=1 //*** erst High Nibble bearbeiten: D4,D5,D6,D7 if (data&(1>>4)) //*** bit D4 gesetzt? LCDD4_ON; //*** setze D4 am Display H else LCDD4_OFF; //*** setze D4 am Display L if (data&(1>>5)) //*** bit D5 gesetzt? LCDD5_ON; //*** setze D5 am Display H else LCDD5_OFF; //*** setze D5 am Display L if (data&(1>>6)) //*** bit D6 gesetzt? LCDD6_ON; //*** setze D6 am Display H else LCDD6_OFF; //*** setze D6 am Display L if (data&(1>>7)) //*** bit D6 gesetzt? LCDD7_ON; //*** setze D7 am Display H else LCDD7_OFF; //*** setze D7 am Display L lcd_e(); //High Nibble nun schreiben //*** nun Low Nibble bearbeiten: D0,D1,D2,D3 if (data&(1>>0)) //*** bit D0 gesetzt? LCDD4_ON; //*** setze D4 am Display H else LCDD4_OFF; //*** setze D4 am Display L if (data&(1>>1)) //*** bit D0 gesetzt? LCDD5_ON; //*** setze D5 am Display H else LCDD5_OFF; //*** setze D5 am Display L if (data&(1>>2)) //*** bit D0 gesetzt? LCDD6_ON; //*** setze D6 am Display H else LCDD6_OFF; //*** setze D6 am Display L if (data&(1>>3)) //*** bit D0 gesetzt? LCDD7_ON; //*** setze D7 am Display H else LCDD7_OFF; //*** setze D7 am Display L lcd_e(); //Low Nibble nun schreiben delay_50us(); //etwas auf die Anzeige warten } //************************************************** //Schreibt String (Text) in die LCD-Anzeige //************************************************** void lcd_stringpos(char Zeile, char Pos, const char *str) { char ps; lcd_pos(Zeile,Pos); ps = *str; while(ps>0) { str++; if (ps== 0) break; lcd_char(ps); ps = *str; } } //**************************************************** // springt auf Zeile x und Position y der LCD-Anzeige // gueltig für 2 Zeilen //**************************************************** void lcd_pos(unsigned char zeile,unsigned char position) { unsigned char buff=0; // wenn Zeile null ist, dann keine neue Position ausgeben if(zeile) { switch(zeile) { case 1: buff=0x7F+position; break; case 2: buff=0xBF+position; break; default : break; } lcd_cmd(buff); } }