list p=16F877 #include ;************************************************************************; ; Pin-Belegung: ; PORTA: 0 ; 1 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7 ; ; PORTB: 0 ; 1 ; 2 LCD ENABLE ; 3 ; 4 LCD R/W ; 5 LCD RS ; 6 PGC (ICSP) ; 7 PGD (ICSP) ; ; PORTC: 0 D0 LCD Datenleitungen ; 1 D1 ; 2 D2 ; 3 D3 ; 4 D4 ; 5 D5 ; 6 D6 ; 7 D7 ; ; PORTD: 0 Status LED1 ; 1 Status LED2 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7 ;************************************************************************; GOTO START ;************************************************************************; ; Variablen ;************************************************************************; ZEIT equ 0x20 ZEITA equ 0x21 ZEITB equ 0x22 LCD_DATEN equ 0x23 LCD_STATUS equ 0x24 ;************************************************************************; ; Konstanten ;************************************************************************; #define ENABLE PORTB, 2 ; LCD ENABLE #define RW PORTB, 4 ; LCD R/W #define RS PORTB, 5 ; LCD RS ;************************************************************************; START nop nop INIT bcf STATUS, RP0 bcf STATUS, RP1 bsf STATUS, RP0 movlw B'10001010' ; einstellung für option_reg movwf OPTION_REG bcf TRISD, 0 ; RD0 I/O bcf TRISD, 1 ; RD1 I/O bcf TRISB, 2 bcf TRISB, 4 bcf TRISB, 5 bcf STATUS, RP0 clrf PORTD clrf PORTB MAIN ; call STATUS_LED call INIT_LCD movlw 'H' movwf LCD_DATEN call OUT_LCD_DATEN movlw 'a' movwf LCD_DATEN call OUT_LCD_DATEN movlw 'l' movwf LCD_DATEN call OUT_LCD_DATEN movlw 'l' movwf LCD_DATEN call OUT_LCD_DATEN movlw 'o' movwf LCD_DATEN call OUT_LCD_DATEN ; sleep loop GOTO loop ;************************************************************************; ; Unterprogramme ;************************************************************************; STATUS_LED bsf PORTD, 0 bsf PORTD, 1 bcf PORTD, 1 bcf PORTD, 0 return INIT_LCD bsf STATUS, RP0 movlw B'00000000' movwf TRISC ; Alle Pins von PortC I/O bcf STATUS, RP0 clrf PORTC ; Alle Pins von PortC sind Ausgänge bcf RW bcf RS bcf ENABLE movlw D'250' movwf ZEIT call WAIT_1ms ; mindestens 15ms auf ende des internen reset warten (hier 20ms) decfsz ZEIT, 1 movlw B'00110000' ; Interface auf 8bit setzen call SCHREIBEN movlw D'50' movwf ZEIT call WAIT_1ms ; mindestens 4,1ms warten (hier 6ms) decfsz ZEIT, 1 movlw B'00110000' ; Interface auf 8bit setzen call SCHREIBEN movlw D'10' movwf ZEIT call WAIT_1ms ; mindestens 4,1ms warten (hier 6ms) decfsz ZEIT, 1 movlw B'00110000' ; Interface auf 8bit setzen call SCHREIBEN call WAIT_1ms ; mindestens 0,1ms auf ende des internen reset warten (hier 1ms) ; movlw B'00110000' ; Interface auf 8bit setzen ; call SCHREIBEN movlw B'00110000' ; Display 2-Zeilig call OutLCD movlw B'00111000' ;5x7-Punkte-Matrix call OutLCD movlw B'00001000' ; Display aus call OutLCD movlw B'00000001' ; Display löschen call OutLCD movlw B'00010100' ; Cursor nach rechts laufend call OutLCD movlw B'00001110' ; Display einschalten call OutLCD clrf PORTC return SCHREIBEN movwf PORTC bsf ENABLE nop nop bcf ENABLE ; call WAIT_1ms return OutLCD movwf LCD_DATEN call LCD_BUSY ; bsf RS movfw LCD_DATEN call SCHREIBEN return LCD_BUSY bsf PORTD, 0 ; Status_LED1 einschalten bsf STATUS, RP0 movlw B'11111111' ; PORTC als eingang iorwf TRISC, f bcf STATUS, RP0 bcf ENABLE BUSYLOOP bcf RS ; Daten ins Steuerregister nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop bsf RW ; RW auf lesen nop nop bsf ENABLE nop nop nop movf PORTC, w movwf LCD_STATUS bcf ENABLE nop nop nop btfsc LCD_STATUS, 7 goto BUSYLOOP ; wenn lcd beschäftigt, mache den ganzen spaß nochmal bcf RW bsf STATUS, RP0 movlw B'00000000' andwf TRISC, f bcf STATUS, RP0 ; bsf RS bcf PORTD,0 ; Status_LED1 aus return OUT_LCD_DATEN bsf PORTD, 1 ; Status_LED2 einschalten bsf RS ; Daten in Textpuffer RB5 bcf RW ; RW auf schreiben nop bsf ENABLE movwf LCD_DATEN call LCD_BUSY nop nop movfw LCD_DATEN movwf PORTC bsf ENABLE nop nop bcf ENABLE nop nop bcf RS bcf PORTD, 1 return WAIT_1ms ; Warteschleife mit delay=1ms delay_0.001_sec movlw D'7' movwf ZEITB movlw D'124' movwf ZEITA delay_0.001_sec_loop decfsz ZEITA, 1 goto delay_0.001_sec_loop decfsz ZEITB, 1 goto delay_0.001_sec_loop return end