;88PicTTYraz040612.asm philippe.loutrel@laposte.net ;Avec Version affichée au démarrage ;affiche 8 valeurs de w sur le LCD, 4 par ligne. ;Detecte une demande de RAZ si reçoit 255 4 fois consécutives ;26/4/2010 ;Outil d'affichage d'une valeur de 8 bits (série, 9600bps) sur un LCD ;Ce logiciel s'execute ds un Pic 16F88 connecté à un LCD ;Il recueil sur l'entrée RX de son USART un car émis par un autre PIC/DUT(Device Under Test) ;Il permet d'afficher à l'écran, en decimal et hexadécimal le caractère reçu ; Le car est émis sur la ligne TX de l'USART du DUT ;Plus generalement, il affiche tout car reçu sur son entrée série, RX, à 9600bps. ;;;;;;;;;*****************CONNEXION************** ;Au minimum, il faut une masse commune et un fil entre la patte TX du DUT et le PicTTY ;Le +9V à 12V peut être fourni par le DUT ou séparémént. ;;;;;;;;************LOGICIEL sur le DUT****************** ;Le DUT doit inclure environ 30 instructions (LCD_TTY.inc) pour configurer l'USART et TX. ;Il doit executer CALL INIT_USART au moins une fois en début de programme ;Ensuite il émet quand necessaire la valeur de w par CALL XEMET ;Tecniques recommandée: ;Le DUT attend 1s mini après émission ou alors ;une pression sur un BP du DUT entre chaque émission ;;;;;;;;;;;;;;EXEMPLE de logiciel sur le DUT ************************ ; list p=16F88 ; list directive to define processor ; #include ; processor specific variable definitions ;Program Configuration Register 1 PIEGE sur 16F88: il FAUT _HS_OSC meme à 4MHzou comme ici INTRC_IO osc interne ; __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO ;Program Configuration Register 2 ; __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;Mclr_on= habituel( =off connection interne du reset à Vdd, Mclr devient RA5). CCP_RB0, RB0 est l'entrée du module COMPARE. SURTOUT oscllateur HS,bug avec XT! ; ERRORLEVEL -302 ; cblock h'20' ; XTMP ;pour XWAIT_1s, si utilisée ; TMP ; endc ; org 0 ;MAIN ; call INIT_USART ;ex d'utilisation: on emet w qd le BP est poussé ; clrf TMP ;deb ; incf TMP,f ; movfw TMP ; call XEMET ; call XWAIT_5ms ; call XWAIT_5ms ; nop ; btfsc PORTB,0 ; 0 si bp poussé ; goto $-1 ; goto deb ; ; #INCLUDE ;Détaillé ci-après ; end ;********** ;PRIMITIVES: INIT_USART, XEMET, (XWAIT_1s) ;ATENTION!!!!! declarer XTMP en RAM ds le programme principal, si on utilise CALL XWAIT_1s ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;INIT_USART ;SUB d'initialisation de l'USART en émission ; banksel TRISB ;bk1 ; bcf PORTB,5 ;out TX, pin 11 ; ;bsf PORTB,0 ;debug, uniquement, pour BP ; movlw d'25' ;set baud generator 9600bps ; movwf SPBRG ; clrf TXSTA ; clrf RCSTA ; bsf TXSTA,BRGH ;b2 de TXSTA pour Hi speed ; bcf TXSTA,SYNC ;b3 de TXSTA pour Asynchrone ; bsf TXSTA,TXEN ;b4 de TXSTA,enable transmission, also sets bit TXIF de PIR1 ; banksel PIR1 ;bk0 ; clrf PORTB ; bsf RCSTA,SPEN ;b7 de RCSTA,Set Serial Port RD et TX ; return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;XEMET ;SUB de TX ; btfss PIR1,TXIF ;attendre tant que flag=0 ; goto $-1 ; movwf TXREG ;il lui sera ajouté 1 bit de Start et 1 de Stop ; return ;;;;;;;;;;;;;;;;;;;OPTIONNEL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;XWAIT_5ms ;SUB d'attente 250*20µs=5ms ; movlw d'250' ;xsd ; addlw -1 ; 20µs ; goto $+1 ; goto $+1 ; goto $+1 ; goto $+1 ; goto $+1 ; goto $+1 ; goto $+1 ; goto $+1 ; nop ; btfss STATUS,Z ; 1 ; goto xsd ; 2 ; return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;XWAIT_1s ;Sub attente 1s soit 250*5ms ; movlw d'192' ; movwf XTMP ;xxw ; decfsz XTMP,f ; goto $+2 ; return ; call XWAIT_5ms ; goto xxw ;;;;;;;;;;;;;;;;;;;;;;;; ;***************DEBUT de PICTTY****************************** ;NOTA: les lib Biblcd2 et 88_PC ont été recopiées sinon il y avait double decla des subs HEX to Ascii et Daddk ;********************************************************************** list p=16F88 ; list directive to define processor #include ; processor specific variable definitions radix hex ;Program Configuration Register 1 PIEGE sur 16F88: il FAUT _HS_OSC meme à 4MHzou comme ici INTRC_IO osc interne ;ET BUG!!!!!!!!!!!!!!!!!!!! OSCCON=h'60'sinon on tourne à 32kHz!!!!!!!!! __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO ;Program Configuration Register 2 __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;Mclr_on= habituel( =off connection interne du reset à Vdd, Mclr devient RA5). CCP_RB0, RB0 est l'entrée du module COMPARE. SURTOUT oscllateur HS,bug avec XT! ERRORLEVEL -302 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; cblock h'20' CS INSCAR DFLAG ;(sans s) TO_R_F ;mis à 1 par XRECOIT si attente d'un caractère au clavier > 3s; HEX_H HEX_L ZC_H ZC_L DIXMIL MIL ;utilisée en temp par ce programme CENT DIX UNIT ACCaLO ;Accumulateurs pour D-arith ACCaHI ACCbLO ACCbHI ;ACCa+ACCb -> ACCb Si overflow, C=1 ACCcLO ACCcHI ACCdLO ;ACCa*ACCb -> ACCb(16 bits MSB), ACCc(16 bits LSB) ACCdHI ;ds cette appli, ACCb=0 systematiquement Dtemp Dflags ;;;;;;;;;;;;;;;; XD1 ;stock 5 chiffres entrés au clavier XD2 XD3 XD4 XD5 XA1 ;Entrée de DEC_to_HEX LSB XA2 XA3 XA4 XA5 ;MSB XRCF ;flag pour CR XFL ;flag ovflow, et par CLR_EEP XTMP ;temporaire, pour les XWAIT et WR_w_EEP XCT ;temp stock car reçu du DUT XCCT ;nb de 255 consécutifs endc ;VALEURS NUMERIQUES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #DEFINE xb9600 d'25' ;pour baud generator, 9600bps25) 19200 (12) #DEFINE XTX TRISB,5 ;emission vers RB5, pin 11 #DEFINE XRX TRISB,2 ;reception venant de RB2,pin 8 ;;;;;;;;; pour USART xCR equ d'13' ;carriage return prefixe 'x' pour var locales xLF equ d'10' ;line feed ;xb1200 equ d'207' ;avec BRGH=1 pour Hi ;xb2400 equ d'103' ORG 0 goto MAIN org h'30' MAIN call INIT ;I/O et USART call INIT_LCD debl1 movlw h'80' ;ligne 1, col 1 call envins ;est la ligne courante movlw 4 movwf XD1 ;compteur de car par ligne call AFF_4w ;affiche 4 car sur ligne courante movf XCCT,f ;sur place,si zero, c'était 4*255 btfsc STATUS,Z goto debl1 ;il y a eu CLS, aller en ligne 1 movlw h'C0' ;pas zero, on continu en L2, col 1 call envins ;est la ligne courante movlw 4 movwf XD1 ;compteur de car par ligne call AFF_4w ;affiche 4 car sur ligne courante goto debl1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AFF_4w ;SUB affiche 4 car sur ligne courante ;et si 4 fois 255, efface tout, retourne L1,C1 movlw -d'4' movwf XCCT bed call GET_CAR movwf XCT incfsz XCT,f goto $+2 ;pas 255 incf XCCT,f ;255, le compter call Aff_w ;convertit en ASCII et affiche,+ espace decfsz XD1,f goto bed ;1,2,3,4 car movf XCCT,f ;sur place,si zero, c'était 4*255 btfsc STATUS,Z call CLS ;raz demandé return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LES SUB ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AFF_HEXA ;Affiche sur deux car en hexa movlw ' ' call envcar movlw ' ' call envcar movlw 'h' call envcar movlw ' ' call envcar swapf CS,w ;get first nibble andlw h'0F' bsf PCLATH,1 ;page h'300' bsf PCLATH,0 call TL ; 0 à F, en sortie h'30' à h'46' call envcar movfw CS andlw h'0F' ;deuxième nibble call TL call envcar return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INIT ;SUB d'Initialisation des I/O et USART bsf STATUS,RP0 ;Aller dans Bank 1(set bit 5 de Status(adr 03)) movlw b'00000100' ; ; RB2 Input RX (pin8) ; RB3 OUTPUT (pin 9)Enable du LCD 0 pour 0utput ; RB4 OUTPUT (pin 10)R/S du LCD 0 pour une instruction ; 1 pour un affichage movwf TRISB movlw h'60' movwf OSCCON ;pour 4MHz d'horloge interne movlw b'00010000' ;Make RA0 à RA3 OUTPUT(pins 17,18,1,2)pour 4 fils de data LCD movwf TRISA bcf STATUS,RP0 ;Revenir à Bank 0 Reset bit de Status clrf PORTB call wait_1ms ;0.1s d'attente pour LCD call INIT_PC ;en réalité, c'est l'USART return ;;;;;;;;;;les SUB de BibLCD2 INIT_LCD ;SUB d'initialisation pour LCD movlw 3 movwf cs ;on va repeter 3 fois cette sequence de mode 8 fils et1 movlw 3 ; movwf PORTA ;3 est l'instruction pour 8 fils bsf PORTB,3 ;Enable on bcf PORTB,3 ;off call Wait_1ms;attente 5ms call Wait_1ms call Wait_1ms call Wait_1ms call Wait_1ms decfsz cs,f goto et1 movlw 2 ;instruction pour mode 4 fils movwf PORTA bsf PORTB,3 ;Enable on bcf PORTB,3 call Wait_1ms movlw h'28' ;28= 4fils,2 lignes de texte,5X7 ;2A= 4fils,2 lignes de texte,5X10 movwf inscar call envins ;envoyer cette instruction movlw h'0C' ;Aff visible, curseur invisible movwf inscar call envins movlw 6 ;curseur vers la droite,sans deplact de texte movwf inscar call envins movlw 1 ;CLS call envins movlw 2 ;cursor home= li 1 ,col 1 IMPORTANT!! call envins movlw h'84' ;Positionnement sur la 1ere ligne call envins ;Ben vas-y alors ! (Ludo!) movlw 'P' call envcar movlw 'i' call envcar movlw 'c' call envcar movlw 'T' call envcar movlw 'T' call envcar movlw 'Y' call envcar movlw h'C6' ; Pareil 2eme ligne call envins movlw 'v' call envcar movlw '1' call envcar movlw '.' call envcar movlw '0' call envcar return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AFF_wcls ;SUB Efface le LCD puis affiche w en li 1, col 1 movwf Cs call cls movfw Cs AFF_w ;SUB sans effacer l'écran, affiche w à la suite clrf hex_H ;w tj <=255 movwf hex_L call hex_to_ascii ;décompose en cent,dix et unit movfw cent ;afficher le resultat call envcar movfw dix call envcar movfw unit call envcar movlw ' ' call envcar ;separateur pour le prochain w return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CLS ;SUB d'effacement de l'ecran movlw 1 ;fill with spaces call envins movlw 2 call envins ;cursor home IMPORTANT pour premier adressage return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EFF_car ;SUB efface à la position du curseur( dans w) call envins movlw ' ' ;ASCII pour un espace call envcar return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENVINS ;SUB envoi d'une INSTRUCTION(commande) au LCD bcf PORTB,4 ;R/S = 0 pour le mode instruction goto $+2 ENVCAR ;SUB envoi d'un CARACTERE à afficher au LCD bsf PORTB,4 ;R/S = 1 pour le mode affichage ENV_8bit movwf inscar ;SUB envoi de 8 bits sur 4 fils du LCD swapf inscar,w ;d'abord les 4 bits de poids fort andlw h'0F' movwf PORTA bsf PORTB,3 ;Enable on bcf PORTB,3 ;off movfw inscar ;puis les 4 bits de poids faible andlw h'0F' movwf PORTA bsf PORTB,3 ;Enable on bcf PORTB,3 ;off call Wait_1ms return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HEX_to_ASCII ;SUB de conversion 0 - 65535 en ASCII movlw h'30' ;Entrée: HEX_H et _L la valeur à convertir ;Sortie: Dixmil, mil,cent,dix,unit:code ASCII movwf dixmil ; 0 en ASCII= h'30', 5 = h'35' etc movwf mil movwf cent movwf dix movlw h'D8' ;-10 000 movwf zc_H movlw h'F0' movwf zc_L ;soustraire 10 000 call daddk ;hex + zc -> hex btfss STATUS,C goto $+3 incf dixmil,f goto $-4 movlw h'27' ;+10 000, compense une soustraction en trop movwf zc_H movlw h'10' movwf zc_L call daddk movlw h'FC' ;-1000 movwf zc_H movlw h'18' movwf zc_L ;soustraire 1000 call daddk ;hex + zc -> hex btfss STATUS,C goto $+3 incf mil,f goto $-4 movlw h'3' ;+1000,compense movwf zc_H movlw h'E8' movwf zc_L call daddk movlw h'FF' ;-100 movwf zc_H movlw h'9C' movwf zc_L ;soustraire 100 call daddk ;hex + zc -> hex btfss STATUS,C goto $+3 incf cent,f goto $-4 clrf zc_H movlw h'64' ;+100,compense movwf zc_L call daddk movlw h'FF' ;-10 movwf zc_H movlw h'F6' movwf zc_L ;soustraire 10 call daddk ;hex + zc -> hex btfss STATUS,C goto $+3 incf dix,f goto $-4 clrf zc_H movlw h'0A' ;+10,compense movwf zc_L call daddk movfw HEX_L ;il reste les unités ds hex_L addlw h'30' ; + h'30' pour ASCII movwf unit movfw dixmil ;Sequences de test des leading zeroes addlw -h'30' ;leading 0 ? btfss STATUS,Z return bcf dixmil,4 ; cad h'20' = espace movfw mil addlw -h'30' btfss STATUS,Z return bcf mil,4 ; passe de h'30' à h'20' = espace movfw cent addlw -h'30' btfss STATUS,Z return bcf cent,4 ; cad h'20' = espace movfw dix addlw -h'30' btfsc STATUS,Z bcf dix,4 ; cad h'20' = espace return daddk ;SUB add, double precision, (cte ZC + hex) =>hex bcf Dflags,0 ;flag de carry sortant des 16 bits movfw zc_L addwf hex_L,f movlw 1 btfsc STATUS,C addwf hex_h,f btfsc STATUS,C ;déjà C=1 ? bsf Dflags,0 ;oui, à memoriser pour la sortie movfw zc_H addwf hex_H,f ;sets C mais si btfsc Dflags,0 ;l'ancien C etait 1, bsf STATUS,C ;alors forcer C=1 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WAIT_1ms ;SUB d'attente 1 ms movlw d'250' ;attendre 1ms = 250X4mus sd addlw -1 ; 1mus btfss STATUS,Z ; 1 goto sd ; 2 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WAIT_wms ;SUB attente w ms movwf cs call wait_1ms decfsz cs,f goto $-2 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;LES SUB de 88_PC.inc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CLR_EEP ;SUB RAZ de l'EEP 256 car banksel EEADR ;bk2 clrf EEADR banksel PIR1 ;bk0 ; movlw d'128' ; movwf XTMP clrf XFL x25 movlw 0 call WR_w_EEP incfsz XFL,f goto x25 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DEC_to_HEX ;SUB convertit 5 chiffres decimaux XA1-5 ;en valeur sur 16 bits ds HEX clrf HEX_H clrf HEX_L clrf XFL ;flag overflow movfw XA1 ;chiffre des unités movwf HEX_L movfw XA2 ;dizaines movwf ACCaLO clrf ACCaHI movlw d'10' movwf ACCbLO clrf ACCbHI call MPAD movfw XA3 ;centaines movwf ACCaLO clrf ACCaHI movlw d'100' movwf ACCbLO clrf ACCbHI call MPAD movfw XA4 movwf ACCaLO clrf ACCaHI movlw h'E8' movwf ACCbLO ;d'1000'= h3E8 movlw h'3' movwf ACCbHI call MPAD movfw XA5 movwf ACCaLO clrf ACCaHI movlw h'10' movwf ACCbLO movlw h'27' ;d'10 000 = h2710 movwf ACCbHI call MPAD btfsc STATUS,C bsf XFL,0 ;ovflow return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GET_CAR ;SUB lecture d'un car de l'USART, sans Time-Out! ; clrf CAR_F ;flag de car reçu movfw RCREG ;clear buffer bsf RCSTA,CREN ;Continuous receive enabled btfss PIR1,RCIF ; flag 1, ie 1 car reçu goto $-1 ;non, attendre encore un car movfw RCREG ;oui, purger ; bsf CAR_F,0 ;set flag de car reçu bcf RCSTA,CREN ;Continuous receive disable return ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INIT_PC ;SUB d'initialisation de la liaison banksel TRISB ;bk1 modifier pour autres Pic bcf XTX ;out TX bsf XRX ;in RX movlw xB9600 ;set baud generator 9600bps movwf SPBRG clrf TXSTA clrf RCSTA bsf TXSTA,BRGH ;b2 de TXSTA pour Hi speed bcf TXSTA,SYNC ;b3 de TXSTA pour Asynchrone bsf TXSTA,TXEN ;b4 de TXSTA,enable transmission, also sets bit TXIF de PIR1 banksel PIR1 ;bk0 clrf PORTB bsf RCSTA,SPEN ;b7 de RCSTA,Set Serial Port RD et TX return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MPAD ;SUB multiplie et additionne call D_mpy ;a*b ->c(LSB) movfw ACCcHI movwf ACCaHI ;c ds a movfw ACCcLO movwf ACCaLO movfw HEX_H movwf ACCbHI movfw HEX_L movwf ACCbLO call D_add movfw ACCbHI movwf HEX_H movfw ACCbLO movwf HEX_L clrf ACCaHI ;jamais plus de 16 bits return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RD_CAR_PC ;SUB lecture d'un car au clavier et écho call XRECOIT btfsc TO_R_F,0 ;si time out >3s sans car au clavier goto xto call XEMET return xto call XEMET_TO ;ecrire "TM OUT" return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RD_HEX_PC ;SUB lecture de 16 bits du clavier ;transmis au Pic ds HEX clrf HEX_H clrf HEX_L clrf XA1 clrf XA2 clrf XA3 clrf XA4 clrf XA5 call XRDS ;get 1 chiffre 0-9 et flag CR btfsc TO_R_F,0 ;si time out, sortir return btfsc XRCF,0 goto xERR ;erreur, w=h'FF, pas de chiffre entré ou overflow movwf XD1 ;premier chiffre call XRDS btfsc TO_R_F,0 ;si time out, sortir return btfsc XRCF,0 goto x1ch movwf XD2 call XRDS btfsc TO_R_F,0 ;si time out, sortir return btfsc XRCF,0 goto x2ch movwf XD3 call XRDS btfsc TO_R_F,0 ;si time out, sortir return btfsc XRCF,0 goto x3ch movwf XD4 call XRDS btfsc TO_R_F,0 ;si time out, sortir return btfsc XRCF,0 goto x4ch movwf XD5 call XRDS btfsc TO_R_F,0 ;si time out, sortir return btfss XRCF,0 ; nop goto xerr ;6 chiffres, erreur movfw XD1 ;5 chiffres movwf XA5 movfw XD2 movwf XA4 movfw XD3 movwf XA3 movfw XD4 movwf XA2 movfw XD5 movwf XA1 xconv call DEC_to_HEX movlw 0 btfss XFL,0 return ;OK, sortir xerr movlw h'FF' ;pb return x1ch movfw XD1 ;1 seul chiffre movwf XA1 goto xconv x2ch movfw XD1 ;2 chiffres movwf XA2 movfw XD2 movwf XA1 goto xconv x3ch ;3 chiffres movfw XD1 movwf XA3 movfw XD2 movwf XA2 movfw XD3 movwf XA1 goto xconv x4ch ;4 chiffres movfw XD1 movwf XA4 movfw XD2 movwf XA3 movfw XD3 movwf XA2 movfw XD4 movwf XA1 goto xconv ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RD_w_EEP ;SUB lit ds w l'EEP pointée par EEADR, EEADR++ banksel EECON1 ;Bank 3 bcf EECON1,EEPGD ;b7=0 pointe vers EEP bsf EECON1,RD ;b0 =1 pour ReaD banksel EEDATA ;bk2 movfw EEDATA ;charger car incf EEADR,f ;EEADR++ banksel PIR1 ;bk0 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PUT_CAR WR_CAR_PC ;SUB ecrit un car à l'écran call XEMET return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WR_HEX_PC ;SUB ecrit val de 16 bits à l'écran call HEX_to_ASCII ;convertit en decimal puis ASCII movfw dixmil call XEMET movfw mil call XEMET movfw cent call XEMET movfw dix call XEMET movfw unit call XEMET movlw ' ' call XEMET return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WR_VW_PC ;SUB ecrit la val 8 bits de w clrf HEX_H movwf HEX_L call WR_HEX_PC return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WR_w_EEP ;SUB ecrit w en EEP, là ou pointe EEADR. w detruit ;NOTA: respecte les IT de l'appelant et EEADR++ banksel EECON1 ;bk3 btfsc EECON1,WR ;encore occupée à ecrire? goto $-1 ;oui, ne pas toucher à EEADR!!! banksel EEDATA ;bk2 movwf EEDATA ;met car ds EEDATA banksel EECON1 ;bk3 bcf EECON1,EEPGD ;OK,b7=0 pointe vers EEP bsf EECON1,WREN ;enable Write ;w utilisé comme flag pour les IT bsf XTMP,0 ;assume IT enabled ds prog appelant btfss INTCON,GIE ;GIE vraiment 1 ? bcf XTMP,0 ;non ,c'etait 0, le noter ds XTMP bcf INTCON,GIE ;stop IT, ds ts les cas movlw h'55' ;magic sequence movwf EECON2 ;registre virtuel movlw h'AA' movwf EECON2 bsf EECON1,WR ;set bit Write bcf EECON1,WREN ;disable Write ;XTMP,0=1 si IT à remettre btfsc XTMP,0 ;verif si on doit remettre les IT bsf INTCON,GIE ;oui, elles y etait en arrivant nop ;securité? movlw d'10' ;pour simulateur!!!!!!! call XWAIT_wms ;et aussi NE PAS toucher EEADR trop vite! banksel EEADR incf EEADR,f ;EEADR++ banksel PIR1 ;retour bk0 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XEMET ;SUB de TX btfss PIR1,TXIF ;attendre tant que flag=0 goto $-1 movwf TXREG ;il lui sera ajouté 1 bit de Start et 1 de Stop return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XEMET_TO ;SUB ecrit "TIME OUT" movlw xcr call xemet movlw xlf call xemet movlw 'T' call xemet movlw 'I' call xemet movlw 'M' call xemet movlw 'E' call xemet movlw ' ' call xemet movlw 'O' call xemet movlw 'U' call xemet movlw 'T' call xemet movlw xcr call xemet movlw xlf call xemet return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XRDS ;SUB read & strip ;à partir d'un ASCCI donne un chiffre decimal call RD_CAR_PC btfsc TO_R_F,0 ;si time out, sortir return clrf XRCF ;flag pour CR movwf cs ;sauver sublw xCR btfsc STATUS,Z bsf XRCF,0 ;c'est un CR movfw cs ;restitue ASCII andlw h'F' ;garder 4 bits pour 0-9 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XRECOIT ;SUB reception un car movfw RCREG ;clear buffer (1 jour!) clrf TO_R_F ;flag de time out bsf RCSTA,CREN movlw d'50' ;pour 5s d'attente maxi pour 1 car au clavier movwf XTMP xwt movlw d'100' call XWAIT_wms ;100ms*50 = 5s clrwdt ;reset WDT et ttes les 100ms tester si btfss PIR1,RCIF ; flag 1, ie 1 car reçu goto xwtt ;non btfsc RCSTA,OERR ;oui, over run error ? goto xerrcar btfsc RCSTA,FERR ;non, Frame error? goto xerrcar movfw RCREG ;pas d'erreurs, le mettre ds w xout bcf RCSTA,CREN ;Continuous receive disable return ; xwtt decfsz XTMP,f goto xwt ;attendre encore bsf TO_R_F,0 ;plus de 3s sans car donc time out goto xout xerrcar bcf RCSTA,CREN ;clear OERR et FERR,ignorer ce car à pb bsf RCSTA,CREN movfw RCREG movfw RCREG ;purge buffer goto xwt ;get next car ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XWAIT_1ms ;SUB d'attente 1 ms movlw d'250' ;attendre 1ms = 250X4mus addlw -1 btfss STATUS,Z goto $-2 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XWAIT_wms ;SUB attente w ms movwf cs movlw d'250' ;attendre 1ms = 250X4mus addlw -1 btfss STATUS,Z ;idem sub XWAIT_1ms mais sauve un niveau de stack! goto $-2 decfsz cs,f goto $-2 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org h'300' TL ;Table de conversion en ASCII addwf PCL,f dw 3430, 3431,3432,3433,3434,3435,3436,3437,3438,3439 ;0 à 9 dw 3441,3442,3443,3444,3445,3446 ;A à F #include ;arith sur 16 bits end ;;;;;;;;;;;;;;;;;;;;;;;;BIBLI DE GESTION DU LCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Il faut RB4 connecté sur R/S (pin 4 du LCD) et RB3 sur Enable(pin 6 du LCD) ;RA0 à RA3 sur les lignes data (pin 11 à 14 du LCD) ;Variables: cs,inscar,Dfags,hex_H,hex_L,zc_H,zc_L,dixmil,mil,cent,dix,unit ;Exemples: ; call init_lcd ;une seule fois, en début de programme ; mowlw 'A' ; call envcar ;affiche A en ligne 1, colonne 1 ; movlw ' ' ; call envcar ;affiche un espace à la suite de A ; movlw h'C2' ;voir la carte memoire ci-dessous ; call envins ;curseur (invisible) en li 2, col 3 ; movlw '/' ;affiche un slash en li 2, col 3 ; call envcar ; movlw d'1' ;admettons que hex=d'258',donc hex_H=1 ; movwf hex_H ; movlw d'2' ;et hex_L=2 ; movwf hex_L ; call hex to_ascii ;decompose en cent=h'32',dix=h'35,unit=h'38' ;pour pouvoir afficher "258" sur le LCD ; movfw cent ; call envcar ;affiche le chiffre 2 ; movfw dix ; call envcar ;affiche ensuite le chiffre 5 ; etc ; movfw toto ;pour debugger un programme, affichage de w ; ;si toto= d'178' ; call aff_wcls ;on voit "178" en debut de LCD ; movfw titi ;si titi= d'125' l'affichage est maintenant ; call aff_w ;"178-125" ; call cls ;raz du LCD ; Carte Memoire DDRAM du LCD ; ************************************************* ; * * ; *80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F* ; * * ; ************************************************* ; * * ; *C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF* ; * * ; ************************************************* ; Exemple: pour ecrire "%" en ligne 1 colonne 15 ; movlw h'8E' ; call envins ;positionne le curseur invisible ; movlw '%' ; call envcar ;affiche ce symbol en li 1, col 15 ;File name 88_PC.inc necessite aussi D_arith.inc, math 16 bit ;Devrait se nommer 88_UART.inc, car utilisable avec PC, ou modem ou autre Pic ; philippe.loutrel@laposte.net 27/10/6 ;valable pour 16F88 ;pour d'autres Pic modifier les deux DEFINE et INIT_PC ;Mode d'emploi: ;1 copier coller les 12 variables CS à UNIT ds le prog à mettre au point, en bank 0 ; et enlever les ";" de commentaire ; ATTENTION!!!!!!!!!il y a 23 autres variables propres à cette bibli(et D_arith, incluse) ; qui doivent aller aussi en bank 0, donc verifier qu'il y a de la place ; sachant que ICD2 se reserve la mémoire h'70 ; ;2 au besoin adapter 9600 ou 19200 bps ds xb9600 ; ;3 ajouter #INCLUDE<88_PC.inc> en fin de programme ; ;4 les ports RB2(pin 8) et RB5(pin 11) sont à relier à un MAX32 et une prise femelle RS232 ; XXXXXAvec Picdem+ relier RB2 à RC7 et RB5 à RC6XXXXXXXXXXXXXXXXXXXXXXX ;5 Cordon normal (non croisé) vers PC sous HYPERTERMINAL (ou equivalent) ; Parametrer la liaison: port COM, 8 bits sans parité, 1 de stop,9600bps(ou 19200, voir xb9600) ; pas de controle de flux ;On peut utiliser des modems, leur mise en relation(AT...) étant assurée par le prog principal ;NOTA:la SUB XRECOIT execute CLRWDT au cas où le WDT a été activé ;Avec RD_CAR_PC il y a un Time Out de 3s sur les entrées au clavier du PC ;A METTRE DANS LE PROGRAMME PRINCIPAL les 12 variables suivantes en bank 0 ;Variables: ; FONCTIONS DE BASE ; call INIT_PC une seule fois en début de programme ; initialise l'USART, 9600bps ;call GET_CAR lit un car sur l'USART sans TIME-OUT, blocage possible(e.g. clavier) ;call WR_CAR_PC le car ASCII ds w est envoyé à l'USART( e.g. affiché à l'écran) ;idem call XEMET ;call RD_CAR_PC la valeur ASCII du car (e.g. tapé au clavier du PC )est ; transmise au PIC via w et,en écho, le car est renvoyé(e.g. pour affichage) ; Time-Out de 3s TO_R_F =1, ;call WR_HEX_PC la valeur sur 16 bits ds HEX_H et _L est convertie ; en decimale puis ASCII et envoyée (e.g. pour affichage) ;call RD_HEX_PC la valeur sur 16 bits du nombre positif(<=65535) délimité par CR ; (e.g. tapé au clavier) est transmise au PIC ; via la variable HEX_H et _L. Si OK,w=0, si pb ; c'està dire soit pas de car entré (seulement CR) ou overflow,w=h'FF' ; Time-Out de 3s ;call WR_VW_PC la valeur 8bits de w est affichée ; AUTRES FONFCTIONS ;call CLR_EEP RAZ de l'EEPROM 256 car, 4ms/car en ecriture ;call WR_w_EEP ecrit w en EEPROM, là où pointe EEADR, respecte les IT, EEADR++ ;call RD_w_EEP lit ds w un car de l'EEPROM là où pointe EEADR, EEADR++ ;call XWAIT_1ms par héritage de biblcd2 (pour LCD) ;call XWAIT_wms ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;