; 85RC5LCD.asm version Affichage LCD SEULEMENT ; rev 24 /07/03 rajout affichage libelleé du code IR recu ; inclu routine LCD 2lignes de 8 car 6 bits I/O : PortB 7 6 5 4 et PortA 0 1 ; inclus routine delai4m.inc @4MHz ; ex readrc7L.asm ; programme simple pour decoder/ lire Telecommande Infrarouge Marantz 5200 ;******************************************************* ; Quartz = 4MHz ; Cycle = 1/Fosc = 1uSec ;******************************************************* ;#define miniSimDE include ifdef miniSimDE p=16F84 else ERRORLEVEL -302 Processor 16F84 endif Radix DEC EXPAND __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;***************************************************************************** ; Equates, I/O, vars ;***************************************************************************** RESET_V EQU 0x0000 ; Address of RESET Vector ISR_V EQU 0x0004 ; Address of Interrupt Vector OSC_FREQ EQU D'4000000' ; Oscillator Frequency is 4 MHz ; constantes a definir dans le programme principal: LCD_DATA_TRIS EQU TRISB ; LCD DATA Port B LCD_DATA EQU PORTB ; LCD DATA 11,12,13,14 bits 4,5,6,7 LCD_CTRL_TRIS EQU TRISA ; LCD CTRL Port A LCD_CTRL EQU PORTA ; LCD CTRL 4,5,6 bits 0,1,2 LCD_E EQU 1 ; LCD: Ligne de commande de controle de l'afficheur LCD_RS EQU 0 ; LCD: Ligne de selection de l'afficheur-> RA0 ;LCD_RW EQU x ; LCD: Ligne de Lecture/Ecriture de l'afficheur ; PORTA bits DATA_IN EQU 4 ; Input data from IR pickup ; misc. LINE1 EQU 0x080 ; Set display to line 1 character 0 LINE2 EQU 0x0C0 ; Set display to line 2 character 0 #DEFINE RAMstart 0x0C ; pour 16F84 IndexP EQU RAMstart ; LCD subroutines internal use COUNT EQU RAMstart+1 ; A counter, used multiple places DELAY EQU RAMstart+2 ; Used in DELAYxxx routines X_DELAY EQU RAMstart+3 ; Used in X_DELAYxxx routines TOGGLE EQU RAMstart+4 ; The RC5 Toggle bit SYSTEM EQU RAMstart+5 ; The RC5 System word COMND EQU RAMstart+6 ; The RC5 Command word MZDATA EQU RAMstart+7 ; The RC5 extra Data word POINTER EQU RAMstart+8 ; Used in TABLE_MSG subroutine ASCII_O EQU RAMstart+9 ; ASCII One's digit to print ASCII_T EQU RAMstart+10 ; ASCII Ten's digit to print ASCII_H EQU RAMstart+11 ; ASCII Hundred's digit to print BIT_COUNT EQU RAMstart+12 ; Counter for incoming bits BYTE_COUNT EQU RAMstart+13 ; Counter for buffer bytes TEMP EQU RAMstart+14 ; Used by ANALYSE to hold the 2-bit pattern SERIAL_BUF EQU RAMstart+15 ; Buffer for incoming bitstream SERIAL_2 EQU RAMstart+16 SERIAL_3 EQU RAMstart+17 SERIAL_4 EQU RAMstart+18 SERIAL_5 EQU RAMstart+19 SERIAL_6 EQU RAMstart+20 FIELD EQU RAMstart+21 ; Temporary storage for field bit ANALYSE_FLAGS EQU RAMstart+22 ; DECODE returns its data in this MZ_FLAG EQU RAMstart+23 ; Set if there is an extra data word in the bitstream LCDtmp EQU RAMstart+24 LCDtmp1 EQU RAMstart+25 count1 EQU RAMstart+26 count2 EQU RAMstart+27 count3 EQU RAMstart+28 Cpt1 EQU RAMstart+29 VOLUME EQU RAMstart+30 ; variable pour convertion binaire --> BCD 16bits bcent EQU RAMstart+31 bdix EQU RAMstart+32 bun EQU RAMstart+33 btmp EQU RAMstart+34 btmp1 EQU RAMstart+35 LastRam EQU RAMstart+35 IF ( (LastRam) > 0x2F ) ERROR "Attention debordement zone RAM" ENDIF ;************************************************ w EQU 0 f EQU 1 ONE EQU B'00000001' ; 2-bit incoming pattern matches ZERO EQU B'00000010' ;***************************************************************************** ; Program start ;***************************************************************************** ORG RESET_V ; RESET vector location RESET GOTO DEBUT ;***************************************************************************** ; This is the Periperal Interrupt routine. Should NOT get here ;***************************************************************************** ORG ISR_V ; Interrupt vector location INTERRUPT BCF STATUS, RP0 ; Select bank 0 GOTO INTERRUPT ;============================================================================= TABLE_ST MOVWF PCL MSG_T RETLW 'T' RETLW 'O' RETLW 'G' RETLW '=' RETLW ' ' RETLW 0x00 MSG_S RETLW 'S' RETLW 'Y' RETLW 'S' RETLW '=' RETLW ' ' RETLW 0x00 MSG_C RETLW 'C' RETLW 'M' RETLW 'D' RETLW '=' RETLW ' ' RETLW 0x00 MSG_V RETLW 'V' RETLW 'O' RETLW 'L' RETLW '=' RETLW 0x00 #define MaxMsgT 15 LibelleTouche ; libelles sur 7 car + terminateur 0 => modulo 8 pour LCD addwf PCL ,F retlw 'M' ;0 retlw 'U' retlw 'T' retlw 'E' retlw '_' retlw ' ' retlw ' ' retlw 0 retlw 'O' ;1 retlw 'S' retlw 'D' retlw '_' retlw ' ' retlw ' ' retlw ' ' retlw 0 retlw 'V' ;2 retlw 'O' retlw 'L' retlw 'U' retlw 'M' retlw ' ' retlw '+' retlw 0 retlw 'V' ;3 retlw 'O' retlw 'L' retlw 'U' retlw 'M' retlw ' ' retlw '-' retlw 0 retlw 'B' ;4 retlw 'A' retlw 'S' retlw 'S' retlw 'E' retlw ' ' retlw '+' retlw 0 retlw 'B' ;5 retlw 'A' retlw 'S' retlw 'S' retlw 'E' retlw ' ' retlw '-' retlw 0 retlw 'U' ;6 retlw 'P' retlw '_' retlw ' ' retlw ' ' retlw ' ' retlw ' ' retlw 0 retlw 'D' ;7 retlw 'O' retlw 'W' retlw 'N' retlw '_' retlw ' ' retlw ' ' retlw 0 retlw 'T' ;8 retlw 'V' retlw '_' retlw ' ' retlw ' ' retlw ' ' retlw ' ' retlw 0 retlw 'R' ;9 retlw 'I' retlw 'G' retlw 'H' retlw 'T' retlw '_' retlw ' ' retlw 0 retlw 'L' ;10 retlw 'E' retlw 'F' retlw 'T' retlw '_' retlw ' ' retlw ' ' retlw 0 retlw 'M' ;11 retlw 'E' retlw 'N' retlw 'U' retlw '_' retlw 'O' retlw 'N' retlw 0 retlw 'M' ;12 retlw 'E' retlw 'N' retlw 'U' retlw '-' retlw 'O' retlw 'F' retlw 0 retlw 'O' ;13 retlw 'K' retlw '_' retlw ' ' retlw ' ' retlw ' ' retlw ' ' retlw 0 retlw 'B' ;14 retlw 'P' retlw '_' retlw 'R' retlw 'O' retlw 'U' retlw 'G' retlw 0 retlw '?' ;15 retlw '?' retlw '?' retlw '?' retlw '?' retlw '?' retlw '?' retlw 0 CodeTouche addwf PCL,f RETLW 13 RETLW 15 RETLW 16 RETLW 17 RETLW 22 RETLW 23 RETLW 28 RETLW 29 RETLW 63 RETLW 43 RETLW 44 RETLW 82 RETLW 83 RETLW 87 RETLW 12 RETLW 0 Chiffre ADDWF PCL,F retlw 'C' retlw 'H' retlw 'I' retlw 'F' retlw 'F' retlw 'R' retlw 'E' retlw 0 TABLE_END RETLW 0X00 IF ( (TABLE_ST & 0x0FF) >= (TABLE_END & 0x0FF) ) MESSG "Warning - Message table 'TABLE_ST' crosses page boundary" ENDIF ;***************************************************************************** ; Initialize processor registers ;***************************************************************************** DEBUT ; POWER_ON Reset (Beginning of program) CLRF STATUS ; Do initialization, Select bank 0 CLRF INTCON ; Clear int-flags, Disable interrupts CLRF PCLATH ; Keep in lower 2KByte CLRF PORTA ; ALL PORT outputs should output Low. CLRF PORTB bank1 MOVLW 0x0FC ; RA1-0 outputs, RA4-3-2 inputs MOVWF TRISA MOVLW 0x000 ; RB7-0 outputs MOVWF TRISB MOVLW B'10010001' ; Option register setup: ; No RB Pullups ; TMR0 fed from internal clock ; Assign prescaler to TMR0 ; use 1:4 prescaling ratio MOVWF OPTION_REG bank0 CLRF VOLUME CALL LCD_Init ; Initialize LCDisplay ;============================ Pres call LCD_Cls clrf Cpt1 MOVLW LINE1 ; CALL LCD_Cde ; Set to first line Pres1 movf Cpt1,w CALL read_EE incf Cpt1,f ANDLW 0x0FF ; test sur (W) BTFSC STATUS, Z ; zero= fin de message ? GOTO Pres2 Call LCD_Putchar goto Pres1 Pres2 MOVLW LINE2 ; CALL LCD_Cde ; Set to first line movlw EE1-EE0 MOVWF Cpt1 Pres3 movf Cpt1,w CALL read_EE incf Cpt1,f ANDLW 0x0FF ; test sur (W) BTFSC STATUS, Z ; zero= fin de message ? GOTO Pres4 Call LCD_Putchar goto Pres3 Pres4 call delay_2_5s MOVLW LINE1 ; CALL LCD_Cde ; Set to first line movlw EE2-EE0 MOVWF Cpt1 Pres5 movf Cpt1,w CALL read_EE incf Cpt1,f ANDLW 0x0FF ; test sur (W) BTFSC STATUS, Z ; zero= fin de message ? GOTO Pres6 Call LCD_Putchar goto Pres5 Pres6 call delay_2_5s Capture_IR call POLL_IR ; Affichage de la donnée capturée call LCD_Cls MOVLW LINE1 CALL LCD_Cde ; Position cursor leftmost on first line MOVLW MSG_T ; Point to Toggle message CALL TABLE_MSG ; Display message MOVF TOGGLE,w ; Load the toggle bit to display MOVWF ASCII_O ; Send data to conversion routine CALL HEX_TO_ASC ; Convert to ascii MOVF ASCII_O,w ; Ones digit is in ascii_o CALL LCD_Putchar ; Display TOGGLE MOVLW LINE1+8 CALL LCD_Cde ; Position cursor leftmost on first line MOVLW MSG_S ; Point to Toggle message CALL TABLE_MSG ; Display message MOVF SYSTEM,w ; Load the SYSTEM dat to display MOVWF ASCII_O ; Send data to conversion routine CALL HEX_TO_ASC ; Convert to ascii MOVF ASCII_O,w ; Ones digit is in ascii_o CALL LCD_Putchar ; Display SYSTEM data MOVLW LINE2 CALL LCD_Cde ; Set cursor leftmost on line 2 MOVLW MSG_C ; Point to Command message CALL TABLE_MSG ; Display the message MOVF COMND,w ; Load the command byte to display MOVWF ASCII_O ; Send data to conversion routine CALL HEX_TO_ASC ; Convert to ascii ; MOVF ASCII_H,w ; Hundreds digit ; CALL LCD_Putchar ; Display it MOVF ASCII_T,w ; Tens digit CALL LCD_Putchar ; Display it MOVF ASCII_O,w ; Ones digit CALL LCD_Putchar ; Display COMMANDE ;----------------------------------- ; decodage code et association libellé ;---------------------------------- call LCD_Clear1 MOVLW LINE1 CALL LCD_Cde ; Set cursor leftmost on line 2 MOVf COMND,W SUBLW 9 ; si COMND<10 c'est un chiffre, sinon une commande BTFSC STATUS,C goto UnChiffre ; decodage pour affichage libelle de la commande IR clrf IndexP movf COMND,W PosNotFind movf IndexP,W ; recherche index correspondant au code lu call CodeTouche ; dans la liste (limitée) des codes possibles xorwf COMND,w ; valeur pointée = code lu ? btfsc STATUS,Z goto FundPosCode incf IndexP,f movlw MaxMsgT xorwf IndexP,W ; limite nb de msg ou codes BTFSS STATUS,Z goto PosNotFind movlw MaxMsgT movwf IndexP ; dernier message par defaut FundPosCode ; position code trouvé bcf STATUS,C ; calcul deplacement dans la table des msg touches rlf IndexP,f ; * par 8 (message modulo 8) rlf IndexP,f rlf IndexP,f NextCarLib movf IndexP,W ; deplacement + table = pointe message call LibelleTouche ANDLW 0xFF ; 0 = fin de message BTFSC STATUS,Z goto FinLibel call LCD_Putchar incf IndexP,f goto NextCarLib FinLibel goto TraiteCde ;------------------------------- UnChiffre ; si COMND<10 c'est un chiffre clrf IndexP ; affiche message "Chiffre" NextChiffre movf IndexP,W call Chiffre ANDLW 0xFF BTFSC STATUS,Z goto FinChiffre call LCD_Putchar incf IndexP,f goto NextChiffre FinChiffre ;------------------------- TraiteCde ; traitement code telecommande movf COMND,W xorlw 16 ;+V btfsc STATUS,Z goto trait1 movf COMND,W xorlw 17 ;-V btfsc STATUS,Z goto trait2 movf COMND,W xorlw 12 ;BP ROUGE btfsc STATUS,Z goto trait3 goto Capture_IR trait1 incf VOLUME,f call affvolume goto Capture_IR trait2 decf VOLUME,f call affvolume goto Capture_IR trait3 clrf VOLUME goto Pres ; Fin du programme principal ;************************************************************* affvolume MOVLW LINE2 + 8 ; Position 8 CALL LCD_Cde ; Set cursor MOVLW MSG_V ; Point to Data message CALL TABLE_MSG ; Display the message MOVF VOLUME,w ; Load the data byte to display call bcd3 return ;************************************************************** ; Envoi de message via table de message dans la zone programme ;************************************************************** TABLE_MSG MOVWF POINTER ; Point to the first char. we want LOOP_WR MOVF POINTER ,W ; Renew the pointer CALL TABLE_ST ; Initiate table lookup XORLW 0x00 ; Is this the terminating char? BTFSC STATUS,Z GOTO END_WR CALL LCD_Putchar ; Actually put the char on display INCF POINTER,f ; Point to the next char GOTO LOOP_WR ; Do next character END_WR RETURN ;********************** ;external Subroutines ;********************** ;-------------------- #include "../common/lcd4c.inc" #include "../common/delais4m.inc" #include "../common/bcd3.inc" #include "../common/84_IRC5_.inc" ;================================================================== ; HEX_TO_ASC .. Converts a hex digit to three ASCII characters ; Enter with the hex digit in ASCII_O ; Exit with Hundreds ascii digit in ASCII_H, ; Tens ascii digit in ASCII_T, ; and Ones ascii digit in ASCII_O. ; The incoming byte is not preserved. ;================================================================== HEX_TO_ASC MOVLW '0' ; Preload a zero into 10's & 100's MOVWF ASCII_T MOVWF ASCII_H DO_100s MOVLW D'100' SUBWF ASCII_O,w ; Subtract 100 to test size BNC DO_10s ; It's less than 100, so branch MOVWF ASCII_O ; It was bigger, so decrement it INCF ASCII_H,f ; Bump up the 100's digit GOTO DO_100s ; Loop again till < 100 DO_10s MOVLW D'10' SUBWF ASCII_O,w ; Subtract 10 to test size BNC ADJUST ; It's less than 10, so branch MOVWF ASCII_O ; It was bigger, so decrement it INCF ASCII_T,f ; Bump up the 10's digit GOTO DO_10s ; Loop again till < 10 ADJUST MOVLW '0' ; The # in ASCII_O is now < 10 ADDWF ASCII_O,f ; Turn it into an ASCII character BLANK_ZEROS MOVLW '0' XORWF ASCII_H,w ; Is the 100's char a 0? BTFSS STATUS,Z GOTO HEX_DONE ; No. MOVLW ' ' ; Yes, MOVWF ASCII_H ; So replace it with a space. MOVLW '0' XORWF ASCII_T,w ; Is the 10's char a 0? BTFSS STATUS,Z GOTO HEX_DONE ; No. MOVLW ' ' ; Yes, MOVWF ASCII_T ; So replace it with a space HEX_DONE RETURN ;**************************************************************************** read_EE movwf EEADR ; defini offset addresse bank1 ; 16F84 !!!! bsf EECON1,RD ; mode lecture bank0 ; 16F84 !!!! movf EEDATA,W ; recupere lecture return ORG EEPROM ;"1234567890123456" EE0 DT "PIC16F84-04-0143",0 EE1 DT "85RC5LCD.asm ",0 EE2 DT "24 juill 2003 ",0 END libelle code hexa pos depl MUTE_ 13 0Dh 0 0 OSD_ 15 0Fh 1 8 VOLUP_ 16 10h 2 16 VOLDOWN_ 17 11h 3 24 BASSUP_ 22 16h 4 32 BASSDOWN_ 23 17h 5 40 UP_ 28 1Ch 6 48 DOWN_ 29 1Dh 7 56 TV_ 63 3Fh 8 64 RIGHT_ 43 2Bh 9 72 LEFT_ 44 2Ch 10 80 MENUON_ 82 52h 11 88 MENUOFF_ 83 53h 12 96 OK_ 87 57h 13 104 ??????? >=14 112