123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821 |
- list p=18f25k22
- errorlevel -305 ; no default destination messages
- errorlevel -302 ; no bank 0 warnings
- errorlevel -202 ; no 'argument out of range' warnings
- include <p18f25k22.inc>
- ; Device configuration settings
- config FCMEN = OFF
- config IESO = OFF
- config PRICLKEN = ON
- config PLLCFG = OFF
- config FOSC = HSMP
- config BORV = 285
- config BOREN = OFF
- config PWRTEN = ON
- config WDTPS = 2048
- config WDTEN = OFF
- config CCP2MX = PORTB3
- config PBADEN = OFF
- config CCP3MX = PORTC6
- config HFOFST = OFF
- config T3CMX = PORTB5
- config P2BMX = PORTC0
- config MCLRE = INTMCLR
- config XINST = ON
- config DEBUG = OFF
- config LVP = OFF
- config STVREN = ON
- config CP0 = OFF
- config CP1 = OFF
- config CP2 = OFF
- config CP3 = OFF
- config CPD = OFF
- config CPB = OFF
- config WRT0 = OFF
- config WRT1 = OFF
- config WRT2 = OFF
- config WRT3 = OFF
- config WRTC = OFF
- config WRTB = OFF
- config WRTD = OFF
- config EBTR0 = OFF
- config EBTR1 = OFF
- config EBTR2 = OFF
- config EBTR3 = OFF
- config EBTRB = OFF
- ; Holding registers for some values
- CONTMR equ 000
- CPSTATE equ 001
- DLYCOUNT equ 002
- LCD_CHAR equ 003
- LCD_NIB_H equ 004
- LCD_NIB_L equ 005
- DLYREG1 equ 006
- DLYREG2 equ 007
- WTEMP equ 008
- PWM_VALUE equ 009
- ; Some constants
- PILOT_12 equ 0F4
- PILOT_9 equ 0D2
- PILOT_6 equ 0B4
- DIODE equ 016
- PWM_6A equ 19
- PWM_7A equ 1D
- PWM_8A equ 21
- PWM_9A equ 25
- PWM_10A equ 29
- PWM_11A equ 2D
- PWM_12A equ 32
- PWM_13A equ 36
- PWM_14A equ 3A
- PWM_15A equ 3E
- PWM_16A equ 42
- PWM_0A equ 0FA
- ; Some port labels
- LCD_BL equ 0
- LCD_RS equ 3
- LCD_RW equ 4
- LCD_EN equ 5
- ; Return codes for the read_cp functions
- STATE_A equ 0
- STATE_B equ 1
- STATE_C equ 2
- KNOP_LINKS equ 0
- KNOP_MIDDEN equ 1
- KNOP_RECHTS equ 2
- CHARGEPWM equ PWM_7A
- goto start
- start
- ; Initialize Ports TRISA
- ; PORTA, 0 = CP input = analog in 1
- ; PORTA, 1 = PP input = analog in 1
- ; PORTA, 2 = Temperatuursensor = analog in 1
- ; PORTA, 3 = (niet aangesloten) 1
- ; PORTA, 4 = motor driver 1 = digital out 0
- ; PORTA, 5 = motor driver 2 = digital out 0
- ; PORTA, 6 = kristal 1 0
- ; PORTA, 7 = kristal 2 1
- movlb 0F ; Stel bank F in voor alle SFR's
- movlw b'10001111'
- movwf TRISA
- movlw b'00001111'
- movwf ANSELA
-
- ; Analog to Digital conversion setup
- bsf ADCON0, ADON ; Turn on ADC module
- movlw b'00100101' ; Settings for ADC: left justified, 8 cycles, Fosc/16
- movwf ADCON2
- movlw b'00000001'
- movwf ADCON0
-
-
- ; PORTB, 0 = display 1 = digital out
- ; PORTB, 1 = display 2 = digital out
- ; PORTB, 2 = display 3 = digital out
- ; PORTB, 3 = display 4 = digital out
- ; PORTB, 4 = Solid State Relais = digital out
- ; PORTB, 5 = Richtingsschakelaar voor RS485 = digital out
- ; PORTB, 6 = UART 2 TX (moet als input)
- ; PORTB, 7 = UART 2 RX (moet als input)
- clrf ANSELB
- movlw b'11000000'
- movwf TRISB
-
- ; PORTC, 0 = display 5 = digital out (display verlichting)
- ; PORTC, 1 = Lock State = digital input
- ; PORTC, 2 = PWM output poort (moet als input geconfigureerd voor PWM operatie, pag 186)
- ; PORTC, 3 = display 6 = digital out
- ; PORTC, 4 = display 7 = digital out
- ; PORTC, 5 = display 8 = digital out
- ; PORTC, 6 = UART 1 TX, RS485 communicatie TX
- ; PORTC, 7 = UART 2 RX, RS485 communicatie RX
- clrf ANSELC
- movlw b'11000110'
- movwf TRISC
-
- ; Initialize PWM op poort C2
- bcf CCPTMRS0, C1TSEL0 ; Selecteer TMR1 en TMR2 voor PWM
- bcf CCPTMRS0, C1TSEL1
- bsf CCP1CON, CCP1M3 ; Stel in voor PWM op de CCP module
- bsf CCP1CON, CCP1M2
- movlw b'00000110' ; Stel 16x prescaler in port Timer 2
- movwf T2CON
-
- movlw 0F9h ; Stel periode in op 249 = 1 kHz bij 16 MHz
- movwf PR2
-
- movlw PWM_0A ; Stel 100% PWM in bij start
- movwf CCPR1L
-
- bcf PIR2, TMR2IF
- bsf T2CON, TMR2ON ; Start de timer
- bcf PIR1, TMR1IF
- bsf T1CON, TMR1ON ; Start TMR1
- bcf TRISC, 2 ; Enable output driver
-
- ; Stroom Duty Cycle CCPR1L:CCP1CON<5:4> CCPR1L CCP1CON<5:4>
- ; 6 10% 100 25 0
- ; 7 11.7% 117 29 1
- ; 8 13.3% 133 33 1
- ; 9 15% 150 37 2
- ; 10 16.7% 167 41 3
- ; 11 18.3% 183 45 3
- ; 12 20% 200 50 0
- ; 13 21.7% 217 54 1
- ; 14 23.3% 233 58 1
- ; 15 25% 250 62 2
- ; 16 26.7% 267 66 3
- ; Initialize TMR0 to use as a delay timer
- ; Set to 16 bits, instruction cycle clock, use prescaler, use 8x prescaler
- clrf TMR0L
- clrf TMR0H
- clrf T0CON
- bsf T0CON, T0PS1
-
- ; Initialize Serial port 2 (UART)
-
- bcf TXSTA2, SYNC ; Asynchronous
- bsf TXSTA2, BRGH ; High speed
- bcf BAUDCON2, BRG16 ; 8 bit Baud Rate Generator
- movlw 33 ; 19.2 kbaud
- movwf SPBRG2
- bsf TXSTA2, TXEN ; Enable the transmit port
- bsf RCSTA2, SPEN ; Enable the receive port
- bsf RCSTA2, CREN ; Enable continuous receive
-
- ; Initialize LCD
- call delay100
- call lcd_init
-
- movlw PWM_7A
- movwf PWM_VALUE
- call display_7a
- ; Main application
- enter
- bsf PORTA, 4 ; Motor Standby
- bsf PORTA, 5
-
- bcf PORTB, 4 ; Power Off
-
- btfss PORTC, 1 ; Make sure the socket is unlocked
- goto unlock
-
- movlw 5 ; Reset CONTMR
- movwf CONTMR
-
- movlw 0FA ; Turn off PWM
- movwf CCPR1L
-
- idle
- call display_idle
- bcf PORTC, LCD_BL ; Turn off LCD backlight
- call check_serial ; Check for serial communications
- call check_state ; Check if there is a car
- call check_knoppen
- sublw STATE_A
- btfsc STATUS, Z
- goto enter
-
- call delay100 ; Delay 100 ms
- decfsz CONTMR ; 5 times
- goto idle ; Check the stuff in this loop again
-
- movlw 5
- movwf CONTMR
- goto connected ; Then go to Connected
- connected
- call check_knoppen
- bsf PORTC, LCD_BL ; Turn on LCD backlight
-
- call check_state
- sublw STATE_A
- btfsc STATUS, Z
- goto enter
-
- btfsc PORTC, 1 ; Check if the lock is closed
- goto lock
-
- call display_connected
- movff PWM_VALUE, CCPR1L
- call delay_1
-
- ; Check if the diode is OK
- call check_diode ; Check the diode (als goed: W = 1)
- sublw 1 ; (W = 0)
- btfss STATUS, Z ; Proceed if the diode state was 1
- goto enter
- ; Check the S2 state of the vehicle
- call check_state
-
- movwf CPSTATE
- sublw STATE_B
- btfsc STATUS, Z
- goto connected
-
- movf CPSTATE, w
- sublw STATE_C
- btfsc STATUS, Z
- goto charging
-
- goto enter
-
-
- charging
- call display_charging
- movff PWM_VALUE, CCPR1L
- bsf PORTB, 4 ; Power On
- call check_knoppen
- call check_state
- sublw STATE_C
- btfsc STATUS, Z
- goto charging
-
- bcf PORTB, 4 ; Power Off
- goto connected
- check_state
- ; Lees CP uit en return met een waarde in W (0 = los, 1 = connected, 2 = S2 gesloten)
- ; TMR2 loopt mee gedurende de PWM. Als TMR2 < CCPR1L dan zitten we nog in de hoog periode.
- ; De aquisitietijd voor de AD-conversie is 4 cycli. Als we 8 cycli voor het eind van de PWM-hoog periode beginnen met samplen, hebben we tijd genoeg.
- ; We willen niet direct aan het begin van de periode zitten, maar na 5%.
- ; Dus 12 < TMR2 < (CCPR1L - 8)
-
- ; Check if TMR2 > 12d
- movlw d'12'
- cpfsgt TMR2 ; Compare TMR2 to W, proceed if TMR2 > W
- goto check_state
-
- ; Check if TMR2 < (CCPR1L - 16)
- movlw 8 ; 8 -> W
- subwf CCPR1L, W ; (CCPR1L - 8) -> W
- cpfslt TMR2 ; Compare TMR2 to W, proceed if TMR2 < W
- goto check_state
-
- call take_sample
- movf ADRESH, W
-
- ; Check if >12V
- movf ADRESH, w ; Voltage -> W
- sublw PILOT_12 ; PILOT_12 - Voltage: moet < nul zijn, dus STATUS,C = 0
- btfss STATUS, C
- retlw STATE_A
-
- ; Check if >9V
- movf ADRESH, w
- sublw PILOT_9
- btfss STATUS, C
- retlw STATE_B
-
- ; Check if >6V
- movf ADRESH, w
- sublw PILOT_6
- btfss STATUS, C
- retlw STATE_C
-
- ; If it is something else, take state A which is safe.
- retlw STATE_A
- check_diode
- ; Read the CP at the low point, return 1 if OK, 0 if not.
- ; (CCPR1L + 12) < TMR2 < (PR2 - 8)
-
- ; Check if TMR2 > CCPR1L + 12
- movf CCPR1L, W ; CCPR1L -> W
- addlw d'12' ; (CCPR1L + 12) -> W
- cpfsgt TMR2 ; Compare TMR2 to W, proceed if TMR2 > W
- goto check_diode
-
- ; Check if TMR2 < (PR2 - 8)
- movlw 8 ; 8 -> W
- subwf PR2, W ; (PR2 - 8) -> W
- cpfslt TMR2 ; Compare TMR2 to W, proceed if TMR2 < W
- goto check_diode
- call take_sample
-
- movlw DIODE
- cpfsgt ADRESH ; Compare ADRESH to DIODE, return 0 if ADRESH > DIODE
- retlw 1
- retlw 0
- take_sample
- bsf ADCON0, GO ; Start the sample
- wait_sample
- btfsc ADCON0, DONE
- goto wait_sample
- return
- ; Routines for locking and unlocking
- lock
- call display_lock
- bcf PORTA, 4
- bsf PORTA, 5
- call delay100 ; Blocking 100ms delay
- call delay100 ; Blocking 100ms delay
- bsf PORTA, 4 ; Stop the motor
- call delay2000 ; Wait 2 seconds to charge the capacitor back up..
- goto connected
-
- unlock
- movlw 0FA ; Turn off PWM
- movwf CCPR1L
- bcf PORTB, 4 ; Power off
- call display_unlock
-
- bsf PORTA, 4 ; Start the motor
- bcf PORTA, 5
- call delay100 ; Blocking 100ms delay
- call delay100 ; Blocking 100ms delay
- bsf PORTA, 5 ; Stop the motor
-
- call delay2000 ; Wait 2 seconds to charge the capacitor back up.
- goto enter ; Always go to 'enter' after unlocking.
- ; Routines for a 100 ms delay
- delay100
- ; Preset timer 0 value at 15533
- movlw 3C
- movwf TMR0H
- movlw 0AD
- movwf TMR0L
-
- ; Start the timer
- bcf INTCON, TMR0IF ; Clear the interrupt
- bsf T0CON, TMR0ON ; Start the timer
- delay_wait
- btfss INTCON, TMR0IF ; Wait for the timer to overflow
- goto delay_wait
-
- bcf T0CON, TMR0ON ; Stop the timer
- return
- ; Routines for a 2 second delay
- delay2000
- movlw d'20'
- movwf DLYCOUNT
- goto delay_repeat
- delay_repeat
- call delay100
- decfsz DLYCOUNT, f
- goto delay_repeat
- return
- ; Routines to handle serial communication from the Raspberry Pi
- check_serial
- btfsc PIR3, RC2IF ; Check of er iets aan de hand is
- goto read_serial
- return
- read_serial
- btfsc RCSTA2, FERR ; Check of er een frame error is (dan naar reset)
- goto start_reset
-
- btfsc RCSTA2, OERR ; Check of er overrun-errors zijn en wis deze
- call clear_oerr
-
- movf RCREG2, W
- return
- clear_oerr
- bcf RCSTA2, CREN
- bsf RCSTA2, CREN
- return
- start_reset
- call display_reset
- reset
- display_reset
- movlw 1
- call lcd_write
- movlw 80
- call lcd_write
- movlw A'R'
- call lcd_print
- movlw A'E'
- call lcd_print
- movlw A'S'
- call lcd_print
- movlw A'E'
- call lcd_print
- movlw A'T'
- call lcd_print
- return
- ; 1 ms Delay (for display logic)
- delay_1
- movwf WTEMP
- movlw 4
- movwf DLYREG1
- movlw 0F8
- movwf DLYREG2
-
- delay_1_inner
- nop
- decfsz DLYREG2 ; 1 cycle
- goto delay_1_inner ; 2 cycles
- delay_1_loop
- movlw 0F8
- movwf DLYREG2
- decfsz DLYREG1
- goto delay_1_inner
- movf WTEMP, W
- return
- ; Everything having to do with the HD44780 display
- lcd_init
- call delay100
- bcf TRISB, KNOP_LINKS
- bcf TRISB, KNOP_MIDDEN
- bcf TRISB, KNOP_RECHTS
-
- bcf PORTC, LCD_EN
- bcf PORTC, LCD_RW
- bcf PORTC, LCD_RS
-
- movf PORTB, W
- andlw 0F0
- iorlw 3 ; Reset instruction, see page 45 of Hitachi datasheet
- movwf PORTB
- call lcd_go
-
- call delay_1 ; wait 5 ms
- call delay_1
- call delay_1
- call delay_1
- call delay_1
-
- call lcd_go
- call delay_short
- call lcd_go
- call delay_short
-
- movf PORTB, W
- andlw 0F0
- iorlw 2 ; Set up as 4-bit mode (interpreted as 8-bit command so completes in one write)
- movwf PORTB
- call lcd_go
-
- call delay_1 ; 4-bit transmissions starts here
-
- movlw b'00101000' ; Function Set, 4-bit, 2 line display, 5x8 pixel characters
- call lcd_write
-
- movlw b'00001000' ; Display Off, Cursor Off, Blink Off
- call lcd_write
-
- movlw b'00000001' ; Clear Display
- call lcd_write
- movlw b'00000110' ; Entry mode set (increment and not shifted)
- call lcd_write
-
- movlw b'00001100' ; Display On, Blink On
- call lcd_write
- bsf TRISB, KNOP_LINKS
- bsf TRISB, KNOP_MIDDEN
- bsf TRISB, KNOP_RECHTS
- return
- lcd_print
- bsf PORTC, LCD_RS
- call lcd_write
- bcf PORTC, LCD_RS
- return
- lcd_write
- ; Split nibbles
- bcf TRISB, KNOP_LINKS
- bcf TRISB, KNOP_MIDDEN
- bcf TRISB, KNOP_RECHTS
- movwf LCD_CHAR
- andlw 0F
- movwf LCD_NIB_L
- swapf LCD_CHAR, W
- andlw 0F
- movwf LCD_NIB_H
- ; Write high nibble
- movf PORTB, W
- andlw 0F0
- iorwf LCD_NIB_H, W
- movwf PORTB
- call lcd_go
- call delay_1
-
- ; Write low nibble
- movf PORTB, W
- andlw 0F0
- iorwf LCD_NIB_L, W
- movwf PORTB
- call lcd_go
- call delay_1
- call delay_1
- bsf TRISB, KNOP_LINKS
- bsf TRISB, KNOP_MIDDEN
- bsf TRISB, KNOP_RECHTS
- return
- lcd_go
- bsf PORTC, LCD_EN
- nop
- nop
- bcf PORTC, LCD_EN
- return
- delay_short
- decfsz DLYREG1
- goto delay_short
- return
- display_idle
- movlw 80
- call lcd_write
- movlw A' '
- call lcd_print
- movlw A'G'
- call lcd_print
- movlw A'e'
- call lcd_print
- movlw A'r'
- call lcd_print
- movlw A'e'
- call lcd_print
- movlw A'e'
- call lcd_print
- movlw A'd'
- call lcd_print
-
- return
-
- display_connected
- movlw 80
- call lcd_write
-
- movlw A'V'
- call lcd_print
-
- movlw A'r'
- call lcd_print
-
- movlw A'b'
- call lcd_print
-
- movlw A'o'
- call lcd_print
-
- movlw A'n'
- call lcd_print
-
- movlw A'd'
- call lcd_print
-
- movlw A'e'
- call lcd_print
-
- movlw A'n'
- call lcd_print
-
- return
- display_charging
- movlw 80
- call lcd_write
-
- movlw A' '
- call lcd_print
-
- movlw A'L'
- call lcd_print
-
- movlw A'a'
- call lcd_print
-
- movlw A'd'
- call lcd_print
-
- movlw A'e'
- call lcd_print
-
- movlw A'n'
- call lcd_print
-
- movlw A' '
- call lcd_print
-
- movlw A' '
- call lcd_print
-
- return
- display_unlock
- movlw 80
- call lcd_write
-
- movlw A' '
- call lcd_print
-
- movlw A'U'
- call lcd_print
-
- movlw A'n'
- call lcd_print
-
- movlw A'l'
- call lcd_print
-
- movlw A'o'
- call lcd_print
-
- movlw A'c'
- call lcd_print
-
- movlw A'k'
- call lcd_print
-
- movlw A' '
- call lcd_print
-
- return
-
- display_lock
- movlw 80
- call lcd_write
-
- movlw A' '
- call lcd_print
-
- movlw A' '
- call lcd_print
-
- movlw A'L'
- call lcd_print
-
- movlw A'o'
- call lcd_print
-
- movlw A'c'
- call lcd_print
-
- movlw A'k'
- call lcd_print
-
- movlw A' '
- call lcd_print
-
- movlw A' '
- call lcd_print
-
- return
- check_knoppen
- btfss PORTB, KNOP_LINKS
- goto set_7a
- btfss PORTB, KNOP_RECHTS
- goto set_14a
- btfss PORTB, KNOP_MIDDEN
- goto unlock
- return
- set_7a
- movlw PWM_7A
- movwf PWM_VALUE
- call display_7a
- return
- set_14a
- movlw PWM_14A
- movwf PWM_VALUE
- call display_14a
- return
- display_7a
- movlw 0C2
- call lcd_write
- movlw A' '
- call lcd_print
- movlw A'7'
- call lcd_print
- movlw A'A'
- call lcd_print
- return
- display_14a
- movlw 0C2
- call lcd_write
- movlw A'1'
- call lcd_print
- movlw A'4'
- call lcd_print
- movlw A'A'
- call lcd_print
- return
- end
|