Jag har läst upp mig mycket på motorcykelns inbyggda (men för användaren osynliga) växelindikator under våren och nu har jag äntligen fått för mig att realisera ett sådant projekt själv!
Motorcykelns växellåda ger ut en analog spänning mellan 0-5 V beroende på vilken växel man har i. Denna signal skickas sedan vidare till motorcykelns dator för att användas vid diverse uträkningar. Denna signal vill jag låna samtidigt som jag vill lura datorn att man har sjätte växeln i hela tiden, en vanlig modifikation eftersom datorn håller igen effekten på de första tre växlarna.
Min första tanke var att använda en A/D-omvandlare och ett kombinatoriknät för att styra en 7-segmentsdisplay, men det visade sig (såklart) vara omöjligt att realisera. Skolans digitalteknik fick bytas ut mot skolans datorteknik! =) Jag gick igenom Elfas sortiment av mikroprocessorer och då såg jag att det är vanligt med en A/D-omvandlare i processorn. Varför har jag inte fått lära mig det i skolan!
Sagt och gjort, nu sitter jag här med en komplett design av en växelindikator+TRE-mod (växeltricket). Jag har programmerat och tänkt och väntar bara på att tentorna ska ta slut någon gång så samvetet tillåter en att pyssla med detta. Nedan finns den färdiga modellen samt den färdiga koden. Transistorn i mitten är till för att inte påverka MC-datorn när den neutrala växeln är i.
Kod: Markera allt
; final.asm
#include "p16f676.inc"
LIST P=16f676, R=HEX ; Alla värden anges i hex
ERRORLEVEL -302 ; remove message about using proper bank (bug)
; Configuration Options:
; 1) _WDT_OFF Turn off Watchdog Timer
; 2) _INTRC_OSC_NOCLKOUT Use internal 4MHz oscillator, don't output clock signal
; 3) _CP_OFF Turn off code protect
; 4) _MCLRE_OFF Turn off /MCLR reset pin
;
; Because of #2 and #4, we have a total of 12 I/O pins if we need them
__CONFIG _WDT_OFF & _INTRC_OSC_NOCLKOUT & _CP_OFF & _MCLRE_OFF
Start
CLRF PORTC
CLRW ;Nollställ W, inga parametrar
; Set up peripherals
; See the PIC16F676 data sheet for information on
; what these configuration registers all do
; Bank 1 Accesses
BSF STATUS,RP0 ; Läs/Skriv i minnesbank 1
MOVWF TRISC ; Set PORTC to all outputs
MOVLW b'00000001'
MOVWF ANSEL ; turn on only analog input 0
BSF ADCON1,ADCS2 ; set ADCS<2:0> = 101 ->
BCF ADCON1,ADCS1 ; Sample Time Tosc/16
BSF ADCON1,ADCS0 ; from Data Sheet
; Bank 0 Accesses
BCF STATUS,RP0 ; Läs/Skriv i minnesbank 0
MOVLW b'11100011' ; set A/D input channel 0
ANDWF ADCON0, f ; Resultatet sparas i f (= hela byten ADCON0)
BCF ADCON0, ADFM ; set shift left, gör så resultatet av A/D
; hamnar i ADRESH bit 7-0+ADRESL bit 7-6.
; MSB ADRESH bit 7, LSB ADRESL bit 6
BCF ADCON0, VCFG ; set reference voltage = Vdd, dvs +5V=matning
BSF ADCON0, ADON ; turn on A/D converter
Main_Loop
BSF ADCON0, GO ; Fetch a sample
Wait_Loop
BTFSC ADCON0, GO ; wait for A/D conversion to finish
GOTO Wait_Loop ; ADC will clear bit ADCON0, GO when done
;KOLLA OM VI LIGGER UNDER 0.89 V
MOVF ADRESH, W ; get upper 8 bits of sampled data
SUBLW 0x2E ; Dra bort 0.89 V
BTFSS STATUS,C ; Kolla carryn, hoppa över nästa instruktion
; om C=1, dvs om A>0.89V
GOTO set_vaxel_neutral
;KOLLA OM VI LIGGER UNDER 2.0 V
MOVF ADRESH,W ; get upper 8 bits of sampled data
SUBLW 0x68 ; Dra bort 2.0 V
BTFSS STATUS,C ; Kolla carryn, hoppa över nästa instruktion
; om C=1, dvs om A>2.0V
GOTO set_vaxel_ettan
;KOLLA OM VI LIGGER UNDER 2.6 V
MOVF ADRESH,W ; get upper 8 bits of sampled data
SUBLW 0x87 ; Dra bort 2.6 V
BTFSS STATUS,C ; Kolla carryn, hoppa över nästa instruktion
; om C=1, dvs om A>2.6V
GOTO set_vaxel_tvaan
;KOLLA OM VI LIGGER UNDER 3.3 V
MOVF ADRESH,W ; get upper 8 bits of sampled data
SUBLW 0xAA ; Dra bort 3.3 V
BTFSS STATUS,C ; Kolla carryn, hoppa över nästa instruktion
; om C=1, dvs om A>3.3V
GOTO set_vaxel_trean
;KOLLA OM VI LIGGER UNDER 4.0 V
MOVF ADRESH,W ; get upper 8 bits of sampled data
SUBLW 0xCD ; Dra bort 4.0 V
BTFSS STATUS,C ; Kolla carryn, hoppa över nästa instruktion
; om C=1, dvs om A>4.0V
GOTO set_vaxel_fyran
;KOLLA OM VI LIGGER UNDER 4.5 V
MOVF ADRESH,W ; get upper 8 bits of sampled data
SUBLW 0xE7 ; Dra bort 4.5 V
BTFSS STATUS,C ; Kolla carryn, hoppa över nästa instruktion
; om C=1, dvs om A>4.5V
GOTO set_vaxel_femman
GOTO set_vaxel_sexan ; Har vi inte valt växel ännu, finns bara
; sexan kvar att välja på
set_vaxel_neutral
CLRW
GOTO output_vaxel
set_vaxel_ettan
MOVLW 0x01
GOTO output_vaxel
set_vaxel_tvaan
MOVLW 0x02
GOTO output_vaxel
set_vaxel_trean
MOVLW 0x03
GOTO output_vaxel
set_vaxel_fyran
MOVLW 0x04
GOTO output_vaxel
set_vaxel_femman
MOVLW 0x05
GOTO output_vaxel
set_vaxel_sexan
MOVLW 0x06
output_vaxel
MOVWF PORTC
; nop instructions just delay for awhile, I'm not sure if they're needed
; between A/D conversions or not. The number of nops was arbitrary here.
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
goto Main_Loop
END