; Filename: toto.asm *
; Date: Jan 2014 *
; File Version: 1.0 *
; *
; Author: Rémi PUTHOMME-ESSAISSI aka gpunk *
; Company: Bad . *
; *
; *
;**********************************************************************
; *
; Files required: $0 + your assembler *
; *
; *
; *
;**********************************************************************
; *
; Notes: Thanks to: *
; Microchip ofcourse *
; BigOnOff for his template/tutorial *
; *
; Copyright : GPL 2.0 & + ;) *
; money & time has been spent on this, so please repect it *
;
;**********************************************************************
list p=16f877 ; list directive to define processor
#include <p16f877.inc> ; processor specific variable definitions
;ERRORLEVEL -302 ;remove message about using proper bank
; __CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC
; __CONFIG _CONFIG2, _WRT_OFF & _BOR21V
__CONFIG
_CP_OFF & _DEBUG_OFF & _WRT_ENABLE_ON & _CPD_OFF
& _LVP_OFF & _BODEN_OFF & _PWRTE_OFF & _WDT_OFF &
_XT_OSC & _BODEN_OFF & _WRT_ENABLE_ON
;*****************************************************************************
; ASSIGNATIONS SYSTEME *
;*****************************************************************************
; REGISTRE OPTION_REG (configuration)
; -----------------------------------
OPTIONVAL EQU B'10000111'
; RBPU b7 RB7 pull ups (inverted)
; INTEDG b6 RB0 int edge side
; T0CS b5 TMR0 source
; T0SE b4 TMR0 edge side
; PSA b3 prescaler assignment TMR0 / WDTMR
; PS2:PS0 b2 , b1, b0 prescaler rate select TMR0 or WDTMR
; REGISTRE INTCON (contrôle interruptions standard)
; -------------------------------------------------
INTCONVAL EQU B'01100000'
; GIE b7 masque autorisation générale interrupt ACTIVATION (prise en charge... )
; ne pas mettre ce bit à 1 ici , attendre fin des initialisations ...
; PEIE b6 interruption perifs ... a/d usart ... ACTIVATION
; T0IE b5 timer0 overflow ... interrupt ACTIVATION
; INTE b4 RB0 int ACTIVATION
; RBIE b3 RBIE RB port change int ACTIVATION
; T0IF b2 timer0 interupt FLAG
; INTF b1 RB0 int FLAG
; RBIF b0 RB port int FLAG
; REGISTRE PIE1 (contrôle interruptions périphériques)
; ----------------------------------------------------
PIE1VAL EQU B'01110001'
; PSPIE b7 : Toujours 0 sur PIC 16F876 ... pas de port parallele, E ... :p
; ADIE b6 : masque interrupt convertisseur A/D ACTIVATION
; RCIE b5 : masque interrupt réception USART ACTIVATION
; TXIE b4 : masque interrupt transmission USART ACTIVATION
; SSPIE b3 : masque interrupt port série synchrone ACTIVATION
; CCP1IE b2 : masque interrupt CCP1 ACTIVATION
; TMR2IE b1 : masque interrupt TMR2 = PR2 ACTIVATION
; TMR1IE b0 : masque interrupt débordement tmr1 ACTIVATION
; REGISTRE PIE2 (contrôle interruptions particulières)
; ----------------------------------------------------
PIE2VAL EQU B'00000001'
; UNUSED b7 : inutilisé, laisser à 0
; RESERVED b6 : réservé, laisser à 0
; UNUSED b5 : inutilisé, laisser à 0
; EEIE b4 : masque interrupt écriture EEPROM ACTIVATION
; BCLIE b3 : masque interrupt collision bus ACTIVATION
; UNUSED b2 : inutilisé, laisser à 0
; UNUSED b1 : inutilisé, laisser à 0
; CCP2IE b0 : masque interrupt CCP2 ACTIVATION
; REGISTRE ADCON1 (ANALOGIQUE/DIGITAL)
; ------------------------------------
;ADCON1VAL EQU B'10000011' ; PORTA en mode digital , ra0 1 2 4 analog, justifé a droite
;ADCON1VAL EQU B'10000010' ; 2/2 ; vref + et - , 2 ADC
;ADCON1VAL EQU B'10001101' ; 2/2 ; vref + et - , 2 ADC
;ADCON1VAL EQU B'10000100' ;
ADCON1VAL EQU B'10000101' ; 2 ana / 1 vref+, sur ra3
CHAN0 EQU b'00000000'
CHAN1 EQU b'00001000'
CHAN2 EQU b'00010000'
CHAN3 EQU b'00011000'
CHAN4 EQU b'00100000'
ADUP EQU b'00000001'
ADGO EQU b'00000100'
ADFR EQU b'10000000' ; internal rc oscillator
; DIRECTION DES PORTS I/O
; -----------------------
DIRPORTA EQU B'00001011' ; RA6,7 non present, tous en entrées, RA3,4/5 en sortie
DIRPORTB EQU B'00000000' ; Direction PORTB : sortie, RB6 et RB7 pour debeugeur ;)
DIRPORTC EQU B'00000010' ; Direction PORTC : sortie
DIRPORTD EQU B'00000000' ; Direction PORTD : sortie
DIRPORTE EQU B'00000000' ; Direction PORTE : sortie
;*****************************************************************************
; Serial port part *
;*****************************************************************************
;----------------------------------------------------------------------------
;Constants
SPBRG_VAL EQU .10 ; for 115200 /// .25 ;set baud rate 9600 for 4Mhz clock
TX_BUF_LEN EQU
.80
;length of transmit circular buffer
RX_BUF_LEN EQU TX_BUF_LEN ;length of receive circular buffer
;----------------------------------------------------------------------------
;Bit Definitions
TxBufFull EQU 0 ;bit indicates Tx buffer is full
TxBufEmpty EQU 1 ;bit indicates Tx buffer is empty
RxBufFull EQU 2 ;bit indicates Rx buffer is full
RxBufEmpty EQU 3 ;bit indicates Rx buffer is empty
ReceivedCR EQU 4 ;bit indicates <CR> character received
;*****************************************************************************
; Timer1 port part *
;*****************************************************************************
;----------------------------------------------------------------------------
; prescaler XX110000 ; 11 = 1/8
; oscen XXXX1000 ; 1 osc enabled
; extsunc XXXXX1XX ; 0 ext sync
; clksrc XXXXXX1X ; 1 externzl clock , 0 internal clock , fosc/4
; tmrena XXXXXXX1 ; 1 enable timer
TMR1FREQU EQU b'00110000'
TMR1OSCEN EQU b'00000000'
TMR1EXSYN EQU b'00000000'
TMR1CKSRC EQU b'00000000'
TMR1ENABL EQU b'00000001'
;*****************************************************************************
; DEFINE *
;*****************************************************************************
#DEFINE LEDPORT PORTA
#DEFINE LED LEDPORT,5 ; LED de sortie
#DEFINE LEDMASK B'00100000' ; Masque pour inversion de la LED (RA4)
#DEFINE CMPTVAL D'1' ; valeur de recharge du compteur
#DEFINE LEDPORT2 PORTA
#DEFINE LED2 LEDPORT2,4 ; LED de sortie
#DEFINE LEDMASK2 B'00010000' ; Masque pour inversion de la LED (RA4)
#DEFINE CMPTVAL2 D'1' ; valeur de recharge du compteur
;*****************************************************************************
; DEFINES for lcd *
;*****************************************************************************
#DEFINE LCDPORT PORTD ; le lcd est sur le port B en 4bit, a ORer avec 00001111
#DEFINE LCDSTAT TRISD ; idem
#DEFINE RS LCDPORT,1 ; register select du lcd:data ou instructions:0 inst, 1 data
#DEFINE RW LCDPORT,2 ; mode : lecture / ecriture : 0 write , 1 read
#DEFINE EN LCDPORT,3 ; active l execution par le LCD lcd en question sur le bus
#DEFINE BZF LCDPORT,7 ; busy flag pour le LCD
#DEFINE BZD LCDSTAT,7 ; "busy port" BZF's direction
#DEFINE IN 1
#DEFINE OUT 0
;*****************************************************************************
; DEFINES for Graphic lcd *
;*****************************************************************************
#DEFINE GLCDPORT PORTB ; le Glcd est sur le port B en 8bit
#DEFINE GLCDSTAT TRISB ; idem
#DEFINE GRS PORTE,2 ; register select du lcd:data ou instructions:0 inst, 1 data
#DEFINE GRW PORTE,1 ; mode : lecture / ecriture : 0 write , 1 read
#DEFINE GEN PORTE,0 ; active l execution par le LCD lcd en question sur le bus
#DEFINE GCS1 PORTA,5 ; graphic pane select 1
#DEFINE GCS2 PORTA,2 ; // 2
#DEFINE GRST PORTA,4 ; Reset the damn ting, would you?
#DEFINE GBZF GLCDPORT,7 ; busy flag pour le LCD
#DEFINE GBZD GLCDSTAT,7 ; "busy port" BZF's direction
;*****************************************************************************
; VARIABLES BANQUE 0 *
;*****************************************************************************
; Zone de 80 bytes
; ----------------
CBLOCK
0x20
; Début de la zone (0x20 à 0x6F)
cmpt :1
; compteur de passage
cmpt2 :1
DIGI1 :1
DIGI2 :1
DIGI3 :1
DIGI4 :1
datal4lb :1
datal4hb :1
dig1 :1
dig2 :1
ADCCHAN :1
ACTCHAN0 :1
ACTCHAN1 :1
ACTCHAN2 :1
ACTCHAN3 :1
ACTCHAN4 :1
ACTCHAN :1
; GLCD stuff
GCONTR :1
octel :1
Doctel :1
DBIT :1
DSHIFT :1
DPAGE :1
gPos :1
gposx :1
gposy :1
; serial stuff
Flags :1
;byte to store indicator flags
TempData :1
;temporary data in main routines
BufferData :1
;temporary data in buffer routines
TxStartPtr :1
;pointer to start of data in TX buffer
TxEndPtr :1
;pointer to end of data in TX buffer
RxStartPtr :1
;pointer to start of data in RX buffer
RxEndPtr :1
;pointer to end of data in RX buffer
;delay routines
b1 :1
b2 :1
b3 :1
d1 :1
d2 :1
e1 :1
x1 :1
x2 :1
ENDC
; Fin de la zone
; more serial stuff
CBLOCK 0xA0
TxBuffer :TX_BUF_LEN
;transmit data buffer
ENDC
CBLOCK 0x120
RxBuffer :RX_BUF_LEN
;receive data buffer
ENDC
;*****************************************************************************
; VARIABLES ZONE COMMUNE *
;*****************************************************************************
; Zone de 16 bytes
; ----------------
CBLOCK
0x70
; Début de la zone (0x70 à 0x7F)
W_TEMP : 1
; Sauvegarde registre W
STATUS_TEMP : 1
; sauvegarde registre STATUS
FSR_TEMP : 1
; sauvegarde FSR (si indirect en interrupt)
PCLATH_TEMP : 1
; sauvegarde PCLATH (si prog>2K)
datal : 1
datah : 1
datal_tmp : 1
datah_tmp : 1
char : 1
char_temp : 1
cmd : 1
tmrl : 1
tmrh : 1
gYpos : 1
gXpos : 1
tmport : 1
ENDC
;*****************************************************************************
; MACRO *
;*****************************************************************************
; Changement de banques
; ----------------------
BANK0 macro
; passer en banque0
bcf STATUS,RP0
endm
BANK1 macro
; passer en banque1
bsf STATUS,RP0
endm
BANK2 macro
; passer en banque2
bcf STATUS,RP0
bsf STATUS,RP1
endm
BANK3 macro
; passer en banque3
bsf STATUS,RP0
bsf STATUS,RP1
endm
NIBHEX macro
addlw 0-D'10'
btfsc STATUS,C
addlw 'A'-'0'-d'10'
addlw '0'+d'10'
endm
PRINTADC macro
movfw datah
; XXXXXXYY
andlw b'00000011' ; remove the zeros bit 3 to 7 000000YY
NIBHEX
movwf char
call LCDsendchar4
swapf datal,W
andlw b'00001111' ; 0000XXXX: remove the zeros
NIBHEX
movwf dig2
movwf char
call LCDsendchar4
movfw datal
andlw b'00001111' ; 0000XXXX: remove the zeros
NIBHEX
movwf char
call LCDsendchar4
endm
GetPOS macro
swapf datal,W
andlw b'00001111'
movwf datal
swapf datah,W
andlw b'00110000'
iorwf datal,W
movwf gPos
endm
HM macro
movlw b'00000010' ; home pos 0,0
movwf cmd
call LCDsendcmd4
endm
WAITCAP macro
NOP
; cant help nature !!! hein
NOP ; this version uses 20Mhz xtal
NOP ; more cycles are needed for the capacitor
NOP ; to dicharge .
NOP ; a next version, will force this .
NOP ; depending on your "speed"
NOP ; less NOOPs will be needed ;)
NOP
NOP
NOP
NOP
; cant help nature !!! hein
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
; cant help nature !!! hein
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
; cant help nature !!! hein
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
; cant help nature !!! hein
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
endm
;
; //////////////////////////////
;**********************************************************************
ORG
0x000
; processor reset vector
clrf PCLATH
; ensure page bits are cleared
goto
init
; go to beginning of program
ORG
0x004
; interrupt vector location
movwf
W_TEMP
;save WREG
movf STATUS,W
;store STATUS in WREG
clrf STATUS
;select file register bank0
movwf
STATUS_TEMP
;save STATUS value
movf PCLATH,W
;store PCLATH in WREG
movwf
PCLATH_TEMP
;save PCLATH value
clrf PCLATH
;select program memory page0
movf FSR,W
;store FSR in WREG
movwf
FSR_TEMP
;save FSR value
BANK0
; passer en banque0
BTFSC INTCON,T0IE
; timer0 int configured?
BTFSC INTCON,T0IF
; timer0 int accured ?
GOTO T0_INT
BSF STATUS,RP0
BTFSC PIE1,TMR1IE
BANK0
BTFSC PIR1,TMR1IF
GOTO T1_INT
bsf STATUS,RP0
BTFSC PIE1,ADIE
BANK0
BTFSC PIR1,ADIF
GOTO AD_INT
bsf STATUS,RP0
BTFSC PIE1,CCP1IE
BANK0
BTFSC PIR1,CCP1IF
GOTO CCP1_INT
bsf STATUS,RP0
BTFSC PIE2,CCP2IE
BANK0
BTFSC PIR2,CCP2IF
GOTO CCP2_INT
; cereal removeer
; reception
BANK0
;select bank0
BTFSC PIR1,RCIF
;test RCIF receive interrupt
BSF STATUS,RP0
;change to bank1 if RCIF set
BTFSC PIE1,RCIE
;test if interrupt enabled if RCIF set
GOTO
GetData
;if RCIF and RCIE set, do receive
; emission
BANK0
;select bank0
BTFSC PIR1,TXIF
;test for TXIF transmit interrupt
BSF STATUS,RP0
;change to bank1 if TXIF set
BTFSC PIE1,TXIE
;test if interrupt enabled if TXIF set
GOTO
PutData
;if TXIF and TCIE set, do transmit
GOTO END_ISR
;------------------------------------
;Get received data and write into receive buffer.
GetData:
BANK0
btfsc RCSTA,OERR
;test overrun error flag
goto
ErrOERR
;handle it if error
btfsc RCSTA,FERR
;test framing error flag
goto
ErrFERR
;handle it if error
btfsc
Flags,RxBufFull
;check if buffer full
goto
ErrRxOver
;handle it if full
movf RCREG,W
;get received data
xorlw
0x0d
;compare with <CR>
btfsc STATUS,Z
;check if the same
bsf
Flags,ReceivedCR
;indicate <CR> character received
xorlw
0x0d
;change back to valid data
call
PutRxBuffer
;and put in buffer
goto END_ISR
;error because OERR overrun error bit is set
;can do special error handling here - this code simply clears and continues
ErrOERR:
bcf RCSTA,CREN
;reset the receiver logic
bsf RCSTA,CREN
;enable reception again
goto END_ISR
;error because FERR framing error bit is set
;can do special error handling here - this code simply clears and continues
ErrFERR:
movf RCREG,W
;discard received data that has error
goto END_ISR
;error because receive buffer is full and new data has been received
;can do special error handling here - this code simply clears and continues
ErrRxOver:
movf RCREG,W
;discard received data
xorlw
0x0d
;but compare with <CR>
btfsc STATUS,Z
;check if the same
bsf
Flags,ReceivedCR
;indicate <CR> character received
goto END_ISR
;------------------------------------
;Read data from the transmit buffer and transmit the data.
PutData:
BANK0
;select bank 0
btfss
Flags,TxBufEmpty
;check if transmit buffer empty
goto
PutDat1
;if not then go get data and transmit
bsf STATUS,RP0
;select bank1
bcf PIE1,TXIE
;disable TX interrupt because all done
goto END_ISR
PutDat1:
call
GetTxBuffer
;get data to transmit
movwf TXREG
;and transmit
goto END_ISR
;----------------------------------------------
;Add a byte (from WREG) to the end of the receive buffer
PutRxBuffer:
BANK0
;select bank 0
btfsc Flags,RxBufFull ;check if buffer full
goto ErrRxBufFull ;and go handle error if full
BANKISEL RxBuffer ;bank bit for indirect addressing
movwf BufferData ;save WREG into BufferData
movf RxEndPtr,W ;get EndPointer
movwf FSR ;and place into FSR
movf BufferData,W ;get BufferData
movwf INDF ;store in buffer
;test if buffer pointer needs to wrap around to beginning of buffer memory
movlw LOW RxBuffer+RX_BUF_LEN-1 ;get last address of buffer
xorwf RxEndPtr,W ;and compare with end pointer
movlw LOW RxBuffer ;load first address of buffer
btfss STATUS,Z ;check if pointer is at last address
incf RxEndPtr,W ;if not then increment pointer
movwf RxEndPtr ;store new end pointer value
;test if buffer is full
subwf RxStartPtr,W ;compare with start pointer
btfsc STATUS,Z ;check if the same
bsf Flags,RxBufFull ;if so then indicate buffer full
bcf Flags,RxBufEmpty ;buffer cannot be empty
return
;error because attempting to store new data and the buffer is full
;can do special error handling here - this code simply ignores the byte
ErrRxBufFull:
return ;no save of data because buffer full
;----------------------------------------------
;Remove and return (in WREG) the byte at the start of the transmit buffer
GetTxBuffer:
BANK0
;select bank 0
btfsc Flags,TxBufEmpty ;check if transmit buffer empty
goto ErrTxBufEmpty ;and go handle error if empty
BANKISEL TxBuffer ;bank bit for indirect addressing
movf TxStartPtr,W ;get StartPointer
movwf FSR ;and place into FSR
;test if buffer pointer needs to wrap around to beginning of buffer memory
movlw LOW TxBuffer+TX_BUF_LEN-1 ;get last address of buffer
xorwf TxStartPtr,W ;and compare with start pointer
movlw LOW TxBuffer ;load first address of buffer
btfss STATUS,Z ;check if pointer is at last address
incf TxStartPtr,W ;if not then increment pointer
movwf TxStartPtr ;store new pointer value
bcf Flags,TxBufFull ;buffer cannot be full
;test if buffer is now empty
xorwf TxEndPtr,W ;compare start to end
btfsc STATUS,Z ;check if the same
bsf Flags,TxBufEmpty ;if same then buffer will be empty
movf INDF,W ;get data from buffer
return
;error because attempting to read data from an empty buffer
;can do special error handling here - this code simply returns zero
ErrTxBufEmpty:
retlw 0 ;tried to read empty buffer
T0_INT
BCF INTCON,T0IF
goto ADUPDATE ; zap LED for now ; décrémenter compteur de passages
decfsz cmpt , f
GOTO ADUPDATE ;END_ISR ; pas 0, on ne fait rien
movlw
LEDMASK
; sélectionner bit à inverser
; xorwf LEDPORT,f ; inverser LED
movlw
CMPTVAL
; pour CMPTVAL nouveaux passages
movwf
cmpt
; dans compteur de passages
;GOTO END_ISR
;T1_INT
ADUPDATE
; Routine when the Timer1 overflows
; get saved last channel, stick it in the pointer the zeros
movfw ACTCHAN
movwf FSR
movfw INDF
movwf ADCCHAN
;zap chan3, change here the number of chans to scan
movfw ADCCHAN
xorlw CHAN2
btfss STATUS,2
call ADClunch
; BCF ADCON0,0 ; stop AD
movfw ADCCHAN
xorlw CHAN4 ; the max channel configured
btfss STATUS,2
goto INC
goto RST
INC
incf FSR,1
goto END_AD
RST
movlw ACTCHAN0
movwf FSR
goto END_AD
END_AD
;;BCF PIR1,TMR1IF ; Clear the Timer1 overflow interrupt flag
; save last channel used.
movfw FSR
movwf ACTCHAN
GOTO
END_ISR
; Ready to leave ISR (for this request)
AD_INT
; Routine when the A/D completes
BCF ADCON0,0
BCF PIR1,
ADIF
; Clear the A/D interrupt flag
call ADCCrunch
; call CCPCrunch
;check and print the H
CHECKH
movfw ADCCHAN
xorlw CHAN0
btfsc STATUS,2
goto PRINTH
goto CHECKV
PRINTH
movlw 0x80+d'2' ; b'10000000' ; goto beginning line 1
movwf cmd
call LCDsendcmd4
PRINTADC
GetPOS
movfw gPos
movwf gposx
goto PRINTDONE
;check and print the V
CHECKV
movfw ADCCHAN
xorlw CHAN1
btfsc STATUS,2
goto PRINTV
goto PRINTDONE
;goto CHECKL
PRINTV
movlw 0x80+d'8' ;b'10000110' ; goto mid line 1
movwf cmd
call LCDsendcmd4
PRINTADC
GetPOS
movfw gPos
movwf gposy
goto PRINTDONE
CHECKL
movfw ADCCHAN
xorlw CHAN2
btfsc STATUS,2
goto PRINTL
goto PRINTDONE
;goto CHECKL
PRINTL
movlw 0x80+d'13' ;b'10000110' ; goto mid line 1
;movlw 0xC0+d'13' ; b'10000000' ; goto beginning line 1
movwf cmd
call LCDsendcmd4
PRINTADC
goto PRINTDONE
PRINTDONE
BSF ADCON0,0 ; turn AD back on
GOTO
END_ISR
; Ready to leave ISR (for this request)
T1_INT
graphpos:
BCF PIR1,TMR1IF
;GSC2
movfw gposx
movwf gXpos
movfw gposy
movwf gYpos
call GLCDsendPixOr
; decfsz cmpt2,F
; GOTO END_ISR ; pas 0, on ne fait rien;
; btfss PORTA,4
; GOTO LEDON
; GOTO LEDOFF
;LEDON
; bsf PORTA,4
; GOTO END_LED
;LEDOFF
; bcf PORTA,4
; GOTO END_LED
;END_LED
; movlw CMPTVAL2 ; pour CMPTVAL nouveaux passages
; movwf cmpt2
; dans compteur de passages
GOTO END_ISR
CCP2_INT
BANK1
BCF PIE2,CCP2IE ; disable this interrupt
BANK0
BCF PIR2,CCP2IF ; Clear the CCP interrupt flag
;stop timer
movfw T1CON
andlw b'11111110' ; whatever is at 1, le reste, mais met bit0 à Zéro
movwf T1CON
movfw CCPR2H
movwf tmrh
movfw CCPR2L
movwf tmrl
;restart timer
clrf TMR1H
clrf TMR1L
movfw T1CON
iorlw b'00000001'
movwf T1CON
BANK1
BSF PIE2,CCP2IE ; reeable this interrupt
BANK0
GOTO
END_ISR
; Ready to leave ISR (for this request)
CCP1_INT
; Routine when PortB has a change
GOTO END_ISR
END_ISR
;
BANK0
;select bank 0
movf
FSR_TEMP,W
;get saved FSR value
movwf FSR
;restore FSR
movf
PCLATH_TEMP,W
;get saved PCLATH value
movwf PCLATH
;restore PCLATH
movf
STATUS_TEMP,W
;get saved STATUS value
movwf STATUS
;restore STATUS
swapf
W_TEMP,F
;prepare WREG to be restored
swapf
W_TEMP,W
;restore WREG without affecting STATUS
retfie
;return from interrupt
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
; remaining code goes here
;*****************************************************************************
; INITIALISATIONS *
;*****************************************************************************
init
; initialisation PORTS (banque 0 et 1)
; ------------------------------------
BANK0 ; sélectionner banque0
clrf PORTA ; Sorties PORTA à 0
clrf PORTB ; sorties PORTB à 0
clrf PORTC ; sorties PORTC à 0
clrf PORTD ; sorties PORTD à 0
clrf PORTE ; sorties PORTE à 0
clrf ADCON0
bsf STATUS,RP0 ; passer en banque1
movlw ADCON1VAL ; PORTA en mode digital/analogique
movwf ADCON1 ; écriture dans contrôle A/D
movlw DIRPORTA ; Direction PORTA
movwf TRISA ; écriture dans registre direction
movlw DIRPORTB ; Direction PORTB
movwf TRISB ; écriture dans registre direction
movlw DIRPORTC ; Direction PORTC
movwf TRISC ; écriture dans registre direction
movlw DIRPORTD ; Direction PORTD
movwf TRISD ; écriture dans registre direction
movlw DIRPORTE ; Direction PORTE
movwf TRISE ; écriture dans registre direction
; Registre d'options (banque 1)
; -----------------------------
movlw OPTIONVAL ; charger masque
movwf OPTION_REG ; initialiser registre option
; registres interruptions (banque 1)
; ----------------------------------
movlw INTCONVAL ; charger valeur registre interruption
movwf INTCON ; initialiser interruptions
movlw PIE1VAL ; Initialiser registre
movwf PIE1 ; interruptions périphériques 1
movlw PIE2VAL ; initialiser registre
movwf PIE2 ; interruptions périphériques 2
; Effacer RAM banque 0
; ---------------------
bcf STATUS,RP0 ; sélectionner banque 0
movlw 0x20 ; initialisation pointeur
movwf FSR ; d'adressage indirect
init1
clrf INDF ; effacer ram
incf FSR,f ; pointer sur suivant
btfss FSR,7 ; tester si fin zone atteinte (>7F)
goto init1 ; non, boucler
; initialiser variable
; --------------------
movlw CMPTVAL ; charger valeur d'initialisation
movwf cmpt ; initialiser compteur de passages
movlw CMPTVAL2 ; charger valeur d'initialisation
movwf cmpt2 ; initialiser compteur de passages
; autoriser interruptions (banque 0)
; ----------------------------------
clrf PIR1 ; effacer flags 1
clrf PIR2 ; effacer flags 2
; init AD
movlw ADUP
movwf ADCON0 ; turn on
movlw ADFR ; get freq
iorwf ADCON0,1 ; set freq
;init timer 1
clrf T1CON
clrf TMR1H
clrf TMR1L
movlw TMR1FREQU
movwf T1CON
movlw TMR1OSCEN
iorwf T1CON,1
movlw TMR1EXSYN
iorwf T1CON,1
movlw TMR1CKSRC
iorwf T1CON,1
movlw TMR1ENABL
iorwf T1CON,1
; init CCP2CON ... test capture...
movlw b'00000110'
movwf CCP2CON
; init CCP1CON ... test pwm ...
movlw b'00001100'
movwf CCP1CON
movlw d'254' ; frequency
movwf PR2
movlw d'0' ; duty cycle
movwf CCPR1L
movlw b'00000100'
movwf T2CON
; init pointer
movlw CHAN0
movwf ACTCHAN0
movlw ACTCHAN0
movwf FSR
incf FSR,1
movlw CHAN1
movwf ACTCHAN1
movlw ACTCHAN1
movwf FSR
incf FSR,1
movlw CHAN2
movwf ACTCHAN2
movlw ACTCHAN2
movwf FSR
incf FSR,1
movlw CHAN3
movwf ACTCHAN3
movlw ACTCHAN3
movwf FSR
incf FSR,1
movlw CHAN4
movwf ACTCHAN4
movlw ACTCHAN4
movwf FSR
decf FSR,1
decf FSR,1
decf FSR,1
decf FSR,1
decf FSR,1
;
;macros pour le LCD
lcdPlop macro
bsf EN
bcf EN
endm
lcdCmd macro
bcf RS
endm
lcdDat macro
bsf RS
endm
lcdRmode macro
bsf RW
endm
lcdWmode macro
bcf RW
endm
; initialisation du LCD
call Delay1m
call Delay1m
call Delay1m
call Delay1m
call Delay1m
call Delay1m
; setup lcd
;
; movlw b'00111100' ; FONCTION SET
movfw LCDPORT
andlw b'00001111' ; mask to preserve RB 0 1 2 3
iorlw b'00100000' ; FONCTION SET
movwf LCDPORT
lcdPlop
call Delay1m
call Delay1m
call Delay1m
call Delay1m
call Delay1m
movfw LCDPORT
andlw b'00001111' ; mask to preserve RB 0 1 2 3
iorlw b'00100000' ; FONCTION SET
movwf LCDPORT
lcdPlop
call Delay1m
call Delay1m
call Delay1m
call Delay1m
call Delay1m
movfw LCDPORT
andlw b'00001111' ; mask to preserve RB 0 1 2 3
iorlw b'11000000' ; FONCTION SET
movwf LCDPORT
lcdPlop
call Delay1m
call Delay1m
call Delay1m
call Delay1m
call Delay1m
movfw LCDPORT
andlw b'00001111' ; mask to preserve RB 0 1 2 3
iorlw b'00000000' ; FONCTION SET
movwf LCDPORT
lcdPlop
call Delay1m
call Delay1m
call Delay1m
call Delay1m
call Delay1m
movfw LCDPORT
andlw b'00001111' ; mask to preserve RB 0 1 2 3
;iorlw b'11110000' ; FONCTION SET, cursor+blink
iorlw b'11000000' ; FONCTION SET, no cur+blnk
movwf LCDPORT
lcdPlop
call Delay1m
call Delay1m
call Delay1m
call Delay1m
call Delay1m
movfw LCDPORT
andlw b'00001111' ; mask to preserve RB 0 1 2 3
iorlw b'00000000' ; FONCTION SET
movwf LCDPORT
lcdPlop
call Delay1m
call Delay1m
call Delay1m
call Delay1m
call Delay1m
movfw LCDPORT
andlw b'00001111' ; mask to preserve RB 0 1 2 3
iorlw b'01100000' ; FONCTION SET
movwf LCDPORT
lcdPlop
call Delay1m
call Delay1m
call Delay1m
call Delay1m
call Delay1m
;init lcd END
; graphic lcd ...
; macros...
GSC1 macro
BsF GCS1
BcF GCS2
; NOP
endm
GSC2 macro
BcF GCS1
BsF GCS2
; NOP
endm
GSC0 macro
BsF GCS1
BsF GCS2
; NOP
endm
GSC3 macro
BcF GCS1
BcF GCS2
; NOP
endm
GWRTDAT macro
BSF GRS ; data incomming!
BCF GRW ; to be written
; NOP
endm
GWRTINS macro
BCF GRS ; instruction incomming!
BCF GRW ; to written to GLCD
; NOP
endm
GRRDDAT macro
BSF GRS ; data incoming !
BSF GRW ; to be read from the GLCD
; NOP
endm
GRRDINS macro
BCF GRS
BSF GRW
; NOP
endm
GPLOP macro
BSF GEN
NOP
NOP
NOP
BCF GEN
NOP
NOP
NOP
endm
GWAITerde macro
GSC0
GRRDINS
bsf STATUS,RP0
bsf
GBZD
; put on read mode en BF port, TRISB7 as IN to read it
BANK0
bsf GEN
btfsc
GBZF
; LCD not busy ? read bit PORTB7
goto $-1
bcf GEN
bsf STATUS,RP0
bcf
GBZD
; write mode en BF port, clear bit TRISB7 of the LCD
BANK0
NOP
;BCF GRW
endm
GWAIT macro
; bsf STATUS,RP0
; movlw b'11111111'
; movwf TRISE
; BANK0
;
; movfw PORTE
; movwf GCONTR
;
; GRRDINS
;
; ; bsf STATUS,RP0
;; bsf GBZD
;; BANK0
; bsf GEN
; btfsc GBZF
; goto $-1
; bcf GEN
;; bsf STATUS,RP0
;; bcf GBZD
;; BANK0
;
; bsf STATUS,RP0
; movlw b'00000000'
; movwf TRISE
; BANK0
;
; movfw GCONTR
; movwf PORTE
call Delay10µ
call Delay10µ
call Delay10µ
; call Delay1m
; call Delay1m
; call Delay1m
; call Delay1m
endm
;reset the glcd
BCF GRST ; pull down the reset pin,
call Delay1m
BSF GRST ; pull it back up,
call Delay1m
; turn it on ;
;BCF GEN ;
GSC1
GPLOP
; call Delay1m
GSC2
GPLOP
; call Delay1m
GWRTINS
;call Delay1m
GSC1 ; chip 1 setup
GPLOP
call Delay1m
movlw b'00111111' ; DISP ON command
movwf GLCDPORT ;
GPLOP
;set page : x address
movlw b'10111000'
movwf GLCDPORT ;
GPLOP
; set adress : y address
movlw b'01000000'
movwf GLCDPORT ;
GPLOP
; set start line : z address
GWAIT
movlw b'11000000'
movwf GLCDPORT ;
GPLOP
GSC2 ; chip 2 setup
call Delay1m
movlw b'00111111' ; DISP ON command
movwf GLCDPORT ;
GPLOP
;set page : x address
movlw b'10111000'
movwf GLCDPORT ;
GPLOP
; set adress : y address
movlw b'01000000'
movwf GLCDPORT ;
GPLOP
; set start line : z address
movlw b'11010000'
movwf GLCDPORT ;
GPLOP
; Clear screen .....
; for (page(x) =0, page(x) +, page(x)< 8)
; {
; for (segment(y)=0, segment(y)+, segment(y)< 64)
; { clear OcTel }
; }
;
ClearGscreen
SETPAGE EQU b'10111000' ; Les liges / X ??
SETSEGM EQU b'01000000' ; Les colonnes Y
GSC1
movlw d'8'
movwf gXpos
movlw d'64'
movwf gYpos
_1cls0loop
GWAIT
GWRTINS
movlw SETPAGE
iorwf gXpos,W
movwf GLCDPORT
GPLOP
movlw SETSEGM
movwf GLCDPORT
GPLOP
_1cls1loop
GWAIT
GWRTDAT
movlw b'00000000' ; 0x01 ; rempli de zeros
movwf GLCDPORT
GPLOP
decfsz gYpos,F
goto _1cls1loop
decfsz gXpos,F
goto _1cls0loop
GSC2
movlw d'8'
movwf gXpos
movlw d'64'
movwf gYpos
_2cls0loop
GWAIT
GWRTINS
movlw SETPAGE
iorwf gXpos,W
movwf GLCDPORT
GPLOP
movlw SETSEGM
movwf GLCDPORT
GPLOP
_2cls1loop
GWAIT
GWRTDAT
movlw b'00000000' ; 0x01 ; rempli de zeros
movwf GLCDPORT
GPLOP
decfsz gYpos,F
goto _2cls1loop
decfsz gXpos,F
goto _2cls0loop
Welcome
; welcome screen
GSC1
GWRTINS
movlw SETPAGE+0x05
movwf GLCDPORT ;
GPLOP
GWAIT
movlw SETSEGM+0x55
movwf GLCDPORT
GPLOP
;test
GWAIT
GWRTDAT ; write data
GWAIT
movlw b'01111111' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00001001' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00011001' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00101001' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01000110' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00111000' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01010100' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01010100' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01001000' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00000000' ; testing :p
movwf GLCDPORT ;
GPLOP
GSC2
GWRTINS
;set page : x address
movlw SETPAGE+0x06
movwf GLCDPORT ;
GPLOP
GWAIT
movlw SETSEGM+0x55
movwf GLCDPORT
GPLOP
GWAIT
GWRTDAT
movlw b'01111111' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00001001' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00011001' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00101001' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01000110' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00111000' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01010100' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01010110' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00001001' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00000000' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01111100' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00001000' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00000100' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01111000' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00000100' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01111000' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'00000000' ; testing :p
movwf GLCDPORT ;
GPLOP
GWAIT
movlw b'01111101' ; testing :p
movwf GLCDPORT ;
GPLOP
goto startg
GLCDsendoctel:
movfw octel
GRRDINS
bsf GEN
BANK1
bsf GBZD ; put on read mode en BF port, TRISB7 as IN to read it
BANK0
btfsc GBZF ; LCD not busy ? read bit PORTB7
goto $-1
bsf STATUS,RP0
bcf GBZD ; write mode en BF port, clear bit TRISB7 of the LCD
BANK0
GWRTDAT
movwf GLCDPORT
bcf GEN
GPLOP
return
GLCDsendPixel:
movlw b'00000001' ; the pixel to put, need to find its position "parmis" les 8 bit de l'octel
movwf DBIT ; 8 positions a calculer depuis XXXXXPPP, PPP 3 bits --> 8 positions
; Find "bit"
movfw gYpos
andlw b'00000111'
addlw d'1'
movwf DSHIFT ; to make the pixel , shift of of '10000000'
; Find Page, divide by 8, trash after Virgule
rrf gYpos,F
rrf gYpos,F
rrf gYpos,W
andlw b'00011111'
movwf DPAGE
BCF STATUS,C
shifting
decfsz DSHIFT,F
goto shiftIt
goto makePixel
shiftIt
rlf DBIT,F
movfw DBIT
goto shifting
makePixel
GWRTINS
movfw DPAGE
iorlw SETPAGE
movwf GLCDPORT
GPLOP
GWAIT
;GWRTINS
movfw gXpos
iorlw SETSEGM
movwf GLCDPORT
GPLOP
GWAIT
GWRTDAT
movfw DBIT
movwf octel
call GLCDsendoctel
GPLOP
return
GLCDsendPixOr:
movlw b'00000001'
; the pixel to put, need to find its position "parmis" les 8 bit de l'octel
movwf
DBIT
; 8 positions a calculer depuis XXXXXPPP, PPP 3 bits --> 8 positions
; assign "bit"'s position
movfw gYpos
andlw b'00000111'
addlw d'1'
movwf DSHIFT ; to make the pixel , shift of of '10000000'
; Find Page, divide by 8, trash after Virgule
rrf gYpos,F
rrf gYpos,F
rrf gYpos,W
andlw b'00011111'
movwf DPAGE
BCF STATUS,C
shiftingOr
decfsz DSHIFT,F
goto shiftItOr
goto makePixelOr
shiftItOr
rlf DBIT,F
movfw DBIT
goto shiftingOr
makePixelOr
GWRTINS
movfw DPAGE
iorlw SETPAGE
movwf GLCDPORT
GPLOP
GWAIT
;GWRTINS
movfw gXpos
iorlw SETSEGM
movwf GLCDPORT
GPLOP
GWAIT
;get the octel already in place
bsf STATUS,RP0
movlw b'11111111'
movwf GLCDSTAT
BANK0
GRRDDAT
GPLOP
GWAIT
GWAIT
movfw GLCDPORT
movwf Doctel
bsf STATUS,RP0
movlw b'00000000'
movwf GLCDSTAT
BANK0
GWAIT
; write the pixel
;go back to my xPos, reading it, incremented it,the zeros man
GWRTINS
movfw gXpos
iorlw SETSEGM
movwf GLCDPORT
GPLOP
GWAIT
GWRTDAT
movfw DBIT
iorwf Doctel,0
movwf octel
call GLCDsendoctel
GPLOP
return
startg
GSC1
movlw b'11001100'
movwf octel
call GLCDsendoctel
movlw b'11001100'
movwf octel
call GLCDsendoctel
movlw b'11001100'
movwf octel
call GLCDsendoctel
movlw b'00110011'
movwf octel
call GLCDsendoctel
movlw b'00110011'
movwf octel
call GLCDsendoctel
movlw b'11001100'
movwf octel
call GLCDsendoctel
movlw b'11001100'
movwf octel
call GLCDsendoctel
movlw b'00110011'
movwf octel
call GLCDsendoctel
movlw b'00110011'
movwf octel
call GLCDsendoctel
GSC1
movlw b'11001100'
movwf octel
call GLCDsendoctel
movlw b'11001100'
movwf octel
call GLCDsendoctel
movlw b'00110011'
movwf octel
call GLCDsendoctel
movlw b'00110011'
movwf octel
call GLCDsendoctel
movlw b'11001100'
movwf octel
call GLCDsendoctel
movlw b'11001100'
movwf octel
call GLCDsendoctel
movlw b'00110011'
movwf octel
call GLCDsendoctel
movlw b'00110011'
movwf octel
call GLCDsendoctel
GSC1
movlw d'1'
movwf gXpos
movlw d'5'
movwf gYpos
call GLCDsendPixOr
movlw d'5'
movwf gXpos
movlw d'10'
movwf gYpos
call GLCDsendPixOr
movlw d'20'
movwf gXpos
movlw d'45'
movwf gYpos
call GLCDsendPixOr
gline
movlw d'64'+.1
movwf tmport
gloop
decfsz tmport,F
goto gprint
goto gdone
gprint
movfw tmport
movwf gYpos
movwf gXpos
call GLCDsendPixOr
goto gloop
gdone
GSC2
movlw d'56'
movwf gXpos
movlw d'44'
movwf gYpos
call GLCDsendPixOr
gline2
movlw d'64'+.1
movwf tmport
gloop2
decfsz tmport,F
goto gprint2
goto gdone2
gprint2
movfw tmport
movwf gYpos
movwf gXpos
call GLCDsendPixOr
goto gloop2
gdone2
movlw d'20'
movwf gYpos
movlw d'18'
movwf gXpos
call GLCDsendPixOr
movlw d'11'
movwf gYpos
movlw d'11'
movwf gXpos
call GLCDsendPixOr
movlw d'0'
movwf gYpos
movlw d'25'
movwf gXpos
call GLCDsendPixOr
movlw d'0'
movwf gYpos
movlw d'35'
movwf gXpos
call GLCDsendPixOr
goto start ; programme principal
;*****************************************************************************
; PROGRAMME PRINCIPAL *
;*****************************************************************************
;
; macro applicatives ...
CLS macro
movlw b'00000001' ; clear screen
movwf cmd
call LCDsendcmd4
endm
; fin macro applicatives
start
CLS
; clear screen
movlw 0x80+d'00' ; b'10000000' ; goto beginning line 1
movwf cmd
call LCDsendcmd4
movlw A'V'; b'01001000' ; put H unit ...
movwf char
call LCDsendchar4
movlw A':'; b'01001000' ; put H unit ...
movwf char
call LCDsendchar4
movlw 0x80+d'06' ;b'10000110' ; goto mid line 1
movwf cmd
call LCDsendcmd4
movlw A'I' ;b'01010110' ; put V unit ...
movwf char
call LCDsendchar4
movlw A':' ;b'01010110' ; put V unit ...
movwf char
call LCDsendchar4
movlw 0x80+d'12' ;b'10000110' ; goto mid line 1
movwf cmd
call LCDsendcmd4
movlw A'C' ;b'01010110' ; put V unit ...
movwf char
call LCDsendchar4
;movlw A':' ;b'01010110' ; put V unit ...
;movwf char
;call LCDsendchar4
movlw 0xC0+d'10'; b'10001100' ; goto to 3/3 of line 1
movwf cmd
call LCDsendcmd4
movlw A'T' ;b'01001000' ; put H unit ...
movwf char
call LCDsendchar4
movlw A':' ;b'01001000' ; put H unit ...
movwf char
call LCDsendchar4
movlw 0xC0+d'0'; b'10001100' ; goto to 3/3 of line 1
movwf cmd
call LCDsendcmd4
movlw A'S' ;b'01001000' ; put H unit ...
movwf char
call LCDsendchar4
call SetupSerial ;set up serial port and buffers
; test GLCD :p
; write doctel
movlw 0x80+d'13' ;b'10000110' ; goto mid line 1
movwf cmd
call LCDsendcmd4
swapf Doctel,0
andlw b'00001111'
NIBHEX
movwf char
call LCDsendchar4
movfw Doctel
andlw b'00001111'
NIBHEX
movwf char
call LCDsendchar4
BANK0
bsf INTCON,GIE ; activer les interruptions
toto
BANK0
btfsc Flags,ReceivedCR ;check if <CR> character received
call
CopyRxToTx
;if so then move received data
; call GetRxBuffer
;;
;
bcf INTCON,GIE ; desactiver les interruptions
movlw 0xC0+d'1' ;b'10001101' ; goto to 3/3 of line 1
movwf cmd
call LCDsendcmd4
;
BANKISEL RxBuffer ;bank bit for indirect addressing
movf RxStartPtr,W ;get StartPointer
movwf FSR ;and place into FSR
movlw LOW RxBuffer+RX_BUF_LEN-1 ;get last address of buffer
xorwf RxStartPtr,W ; and compare with start pointer
movlw LOW RxBuffer ;load first address of buffer
movf INDF,W ;get data from buffer
movwf char
call LCDsendchar4
incf FSR,F
movf INDF,W ;get data from buffer
movwf char
call LCDsendchar4
incf FSR,F
movf INDF,W ;get data from buffer
movwf char
call LCDsendchar4
incf FSR,F
movf INDF,W ;get data from buffer
movwf char
call LCDsendchar4
incf FSR,F
movf INDF,W ;get data from buffer
movwf char
call LCDsendchar4
incf FSR,F
movf INDF,W ;get data from buffer
movwf char
call LCDsendchar4
incf FSR,F
movf INDF,W ;get data from buffer
movwf char
call LCDsendchar4
incf FSR,F
movf INDF,W ;get data from buffer
movwf char
call LCDsendchar4
;movlw TempData
;movlw b'01001000' ; put H unit ...
;timer the zeros ...
PRINTCCP:
movlw 0xC0+d'12' ;; goto to 3/3 of line 1
movwf cmd
call LCDsendcmd4
swapf tmrh,W
andlw b'00001111'
NIBHEX
movwf char
call LCDsendchar4
movfw tmrh
andlw b'00001111'
NIBHEX
movwf char
call LCDsendchar4
swapf tmrl,W
andlw b'00001111'
NIBHEX
movwf char
call LCDsendchar4
movfw tmrl
andlw b'00001111'
NIBHEX
movwf char
call LCDsendchar4
bsf INTCON,GIE ; reactiver les interruptions ( sinon interferance avec ecriture LCD
goto
toto
; boucle principale ...si besoin de boucle ...
; cereal routines
;----------------------------------------------------------------------------
;Set up serial port and buffers.
SetupSerial:
bsf STATUS,RP0
;select bank 1
movlw b'11000000' ;set tris bits for TX and RX
iorwf TRISC,F
movlw SPBRG_VAL ;set baud rate
movwf SPBRG
movlw
0x24
;enable transmission and high baud rate
movwf TXSTA
BANK0
;select bank0
movlw 0x90 ;enable serial port and reception
movwf RCSTA
clrf
Flags
;clear all flag bits
call InitTxBuffer ;initialize transmit buffer
call InitRxBuffer ;initialize receive buffer
return
;----------------------------------------------
;Add a byte (from WREG) to the end of the transmit buffer
PutTxBuffer:
bsf STATUS,RP0
;select bank 1
bcf PIE1,TXIE ;disable transmit interrupt
BANK0
;select bank 0
btfsc Flags,TxBufFull ;check if buffer full
goto ErrTxBufFull ;and go handle error if full
BANKISEL TxBuffer ;bank bit for indirect addressing
movwf BufferData ;save WREG data into BufferData
movf TxEndPtr,W ;get EndPointer
movwf FSR ;and place into FSR
movf BufferData,W ;get BufferData
movwf INDF ;and store in buffer
;test if buffer pointer needs to wrap around to beginning of buffer memory
movlw LOW TxBuffer+TX_BUF_LEN-1 ;get last address of buffer
xorwf TxEndPtr,W ;and compare with end pointer
movlw LOW TxBuffer ;load first address of buffer
btfss STATUS,Z ;check if pointer is at last address
incf TxEndPtr,W ;if not then increment pointer
movwf TxEndPtr ;store new end pointer value
;test if buffer is full
subwf TxStartPtr,W ;compare with start pointer
btfsc STATUS,Z ;check if the same
bsf Flags,TxBufFull ;if so then indicate buffer full
bcf Flags,TxBufEmpty ;buffer cannot be empty
bsf STATUS,RP0
;select bank 1
bsf PIE1,TXIE ;enable transmit interrupt
BANK0
;select bank 0
return
;error because attempting to store new data and the buffer is full
;can do special error handling here - this code simply ignores the byte
ErrTxBufFull:
bsf STATUS,RP0
;select bank 1
bsf PIE1,TXIE ;enable transmit interrupt
BANK0
;select bank 0
return
;no save of data because buffer full
;----------------------------------------------
;Remove and return (in WREG) the byte at the start of the receive buffer
GetRxBuffer:
BANK0
;select bank 0
btfsc Flags,RxBufEmpty ;check if receive buffer empty
goto ErrRxBufEmpty ;and go handle error if empty
bsf STATUS,RP0
;select bank 1
bcf PIE1,RCIE ;disable receive interrupt
BANK0
;select bank 0
BANKISEL RxBuffer ;bank bit for indirect addressing
movf RxStartPtr,W ;get StartPointer
movwf FSR ;and place into FSR
;test if buffer pointer needs to wrap around to beginning of buffer memory
movlw LOW RxBuffer+RX_BUF_LEN-1 ;get last address of buffer
xorwf RxStartPtr,W ; and compare with start pointer
movlw LOW RxBuffer ;load first address of buffer
btfss STATUS,Z ;check if pointer is at last address
incf RxStartPtr,W ;if not then increment pointer
movwf RxStartPtr ;store new pointer value
bcf Flags,RxBufFull ;buffer cannot be full
;test if buffer is now empty
xorwf RxEndPtr,W ;compare start to end
btfsc STATUS,Z ;check if the same
bsf Flags,RxBufEmpty ;if same then buffer will be empty
movf INDF,W ;get data from buffer
bsf STATUS,RP0
;select bank 1
bsf PIE1,RCIE ;enable receive interrupt
BANK0
;select bank 0
return
;error because attempting to read data from an empty buffer
;can do special error handling here - this code simply returns zero
ErrRxBufEmpty:
bsf STATUS,RP0
;select bank 1
bsf PIE1,RCIE ;enable receive interrupt
BANK0
;select bank 0
retlw 0
;tried to read empty buffer
;----------------------------------------------------------------------------
;Move data from receive buffer to transmit buffer to echo the line back
CopyRxToTx:
BANK0
;select bank 0
bcf Flags,ReceivedCR ;clear <CR> received indicator
Copy1:
btfsc Flags,RxBufEmpty ;check if Rx buffer is empty
return
;if so then return
call GetRxBuffer ;get data from receive buffer
movwf TempData ;save data
call PutTxBuffer ;put data in transmit buffer
movf TempData,W ;restore data
xorlw 0x0d ;compare with <CR>
btfss STATUS,Z ;check if the same
goto Copy1 ;if not the same then move another byte
return
;----------------------------------------------------------------------------
;Circular buffer routines.
;----------------------------------------------------------------------------
;Initialize transmit buffer
InitTxBuffer:
BANK0
movlw LOW TxBuffer ;take address of transmit buffer
movwf TxStartPtr ;and place in transmit start pointer
movwf TxEndPtr ;and place in transmit end pointer
bcf Flags,TxBufFull ;indicate Tx buffer is not full
bsf Flags,TxBufEmpty ;indicate Tx buffer is empty
return
;----------------------------------------------
;Initialize receive buffer
InitRxBuffer:
BANK0
movlw LOW RxBuffer ;take address of receive buffer
movwf RxStartPtr ;and place in receive start pointer
movwf RxEndPtr ;and place in receive end pointer
bcf Flags,RxBufFull ;indicate Rx buffer is not full
bsf Flags,RxBufEmpty ;indicate Rx buffer is empty
return
ADClunch:
movlw b'11000111'
andwf ADCON0 ,1
; clean up previous ADCON0 state from CHAN / keep FR
; ON state
movfw ADCCHAN
; get CHAN to Convert
iorwf ADCON0 ,1
; stick it in ADCON0
movlw ADGO
WAITCAP
; wait for the capacitor to discharge ...
; capacitor discharger after 9 cycles (µs) (@4Mhz) put ten to be safe
iorwf ADCON0 ,1
; start conversion
return
ADCCrunch:
; movfw ADCCHAN
; xorlw CHAN1
; btfsc STATUS,2
; return
bsf STATUS,RP0
movfw ADRESL
movwf datal
movwf datal_tmp
; movwf CCPR1L
BANK0
movfw
ADRESH
; XXXXXXDD
movwf datah
movwf datah_tmp
; movwf CCPR1H
movfw datal
movwf dig2
rlf dig2,1
rlf dig2,1
rlf dig2,1
rlf dig2,0
; XXDDYYYY
andlw b'00110000' ; remove the zeros
iorlw b'00001100' ; and keep the state of ccp1con ...
movwf CCP1CON
rrf datal,1
rrf datal,0
andlw b'00111111' ; remove the zeros top2
movwf datal
rlf datah,1
rlf datah,1
rlf datah,1
rlf datah,1
rlf datah,1
rlf datah,0
andlw b'11000000' ; remove the zeros 6 bottoms for datal
iorwf datal,0
movwf CCPR1L
movfw datal_tmp
movwf datal
movfw datah_tmp
movwf datah
return
; fin adccrunch
LCDsendcmd4:
movlw b'00001111'
andwf LCDPORT,1
movfw cmd ; the char to save
lcdCmd ; cmd mode , clear bit RS / PORTB1
lcdRmode ; for reading status , set bit RW / PORTB2
bsf STATUS,RP0
bsf BZD ; put on read mode en BF port, TRISB7 as IN to read it
BANK0
bsf EN ; magic , set bit PORTB3
btfsc BZF ; LCD not busy ? read bit PORTB7
goto $-1
bcf EN ; test if that helps
bsf STATUS,RP0
bcf BZD ; write mode en BF port, clear bit TRISB7 of the LCD
BANK0
lcdWmode ; clear bit PORTB2
lcdCmd ; set bit PORTB1
movfw cmd
andlw b'11110000' ; remove bit 0 1 2 3 from the char to write
iorlw b'00000000'
; mask for data+write mode
movwf
LCDPORT
; out to the LCD;:
lcdPlop
; execute
swapf cmd,W
andlw b'11110000' ; remove bit 0 1 2 3 from the char to write
iorlw b'00000000'
; mask for data+write mode
movwf LCDPORT
lcdPlop
; execute
return
; command sending
LCDsendchar4:
movlw b'00001111'
andwf LCDPORT,1
movfw char
; the char to save
lcdCmd
; cmd mode , clear bit RS / PORTB1
lcdRmode
; for reading status , set bit RW / PORTB2
bsf STATUS,RP0
bsf
BZD
; put on read mode en BF port, TRISB7 as IN to read it
BANK0
bsf
EN
; magic , set bit PORTB3
btfsc
BZF
; LCD not busy ? read bit PORTB7
goto $-1
bcf
EN
; test if that helps
bsf STATUS,RP0
bcf
BZD
; write mode en BF port, clear bit TRISB7 of the LCD
BANK0
lcdWmode
; clear bit PORTB2
lcdDat
; set bit PORTB1
movfw char
andlw b'11110000' ; remove bit 0 1 2 3 from the char to write
iorlw b'00000010' ; mask for data+write mode
movwf
LCDPORT
; out to the LCD;:
lcdPlop
; execute
swapf char,W
andlw b'11110000' ; remove bit 0 1 2 3 from the char to write
iorlw b'00000010' ; mask for data+write mode
movwf LCDPORT
lcdPlop
; execute
return
; caracter sending
;
; routine de temporisations
;
; Delay = 1 seconds
; Clock frequency = 20 MHz
; Actual delay = 1 seconds = 5000000 cycles
; Error = 0 %
; cblock;
; b1
; b2
; b3
; endc
Delay:
;4999993 cycles
movlw 0x2C
movwf b1
movlw 0xE7
movwf b2
movlw 0x0B
movwf b3
Delay_0:
decfsz b1, f
goto $+2
decfsz b2, f
goto $+2
decfsz b3, f
goto Delay_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
; 1 milliseconde avec q 20Mhz
; Delay = 0.001 seconds
; Clock frequency = 20 MHz
; Actual delay = 0.001 seconds = 5000 cycles
; Error = 0 %
; cblock
; d1
; d2
; endc
Delay1m:
;4993 cycles
movlw 0xE6
movwf d1
movlw 0x04
movwf d2
Delay1m_0:
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay1m_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
; 100 micros
; Delay = 0.0001 seconds
; Clock frequency = 20 MHz
; Actual delay = 0.0001 seconds = 500 cycles
; Error = 0 %
; cblock
; e1
; endc
Delay100µ:
;496 cycles
movlw 0xA5
movwf e1
Delay100µ_0:
decfsz e1, f
goto Delay100µ_0
;4 cycles (including call)
return
Delay50µ:
;496 cycles
movlw 0x53
movwf e1
Delay50µ_0:
decfsz e1, f
goto Delay50µ_0
;4 cycles (including call)
return
Delay25µ:
;496 cycles
movlw 0x29
movwf e1
Delay25µ_0:
decfsz e1, f
goto Delay25µ_0
;4 cycles (including call)
return
Delay10µ:
;496 cycles
movlw 0x0B
movwf e1
Delay10µ_0:
decfsz e1, f
goto Delay10µ_0
;4 cycles (including call)
return
; Delay = 0.025 seconds
; Clock frequency = 20 MHz
; Actual delay = 0.025 seconds = 125000 cycles
; Error = 0 %
; cblock
; x1
; x2
; endc
Delay25m:
;124993 cycles
movlw 0xA6
movwf x1
movlw 0x62
movwf x2
Delay25m_0:
decfsz x1, f
goto $+2
decfsz x2, f
goto Delay25m_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
END ; directive fin de programme