![]() |
|
|
#1 |
|
Erfahrener Benutzer
Registriert seit: 23.03.2017
Ort: Worms
Beiträge: 140
|
Hallo Gemeinde,
ich habe mir auch eine Ganganzeige drangebastelt. Dafür füttere ich einen PIC Mikrocontroller 18F2455 mit dem Gangsensor und außerdem noch mit der Batteriespannung und einem NTC für die Öltemperatur, der an Stelle der Ölablassschraube sitzt. Im einfachsten Fall hängt nur eine LED am Alarmausgang, die leuchtet, wenn Öl nicht im Bereich von 60 h 100 Cel liegt und die blinkt, wenn Batterie weniger als 12V oder mehr als 14,9V hat. Per I2C hängt eine LED Anzeige dran, auf der in den ersten 30s. nach Start Spannung angezeigt wird, danach der Gang. Falls eines der obigen Limits verletzt wird, springt die Anzeige auf den entsprechenden Wert. Per RS232 werden die Werte aus dem PIC rausgeschoben und per Bluetooth Modul zur Verfügung gestellt. Kann man über eine passend programmierte APP dann auf dem Handy darstellen. Falls es jemanden interessiert, kann er/sie mich gerne über PM anschreiben, kann aber ein paar Tage dauern, bis ich antworte. Gruß, Wolfgang P.S. Bilder bekomme ich auf dem Handy nicht hinzugefügt, schick ich später hinterher. Geändert von wekltf (07.10.2023 um 22:48:38 Uhr) |
|
|
|
|
|
#2 |
|
Erfahrener Benutzer
Registriert seit: 23.03.2017
Ort: Worms
Beiträge: 140
|
Hier noch Bilder:
- Platine habe ich in ein kleines Kunststoffkästchen gesetzt, was noch ins Heck passt. - programmiert wurde in assembler mit der microchip IDE - wenn Spannung okay ist und Temperatur ist okay (oder NTC gar nicht angeschlossen), dann wird Gang angezeigt - wenn Spannung außerhalb des zulässigen Bereiches ist, so wird Voltzahl angezeigt. Anzeige ist mit einem TM1637 Modul gemacht, kostet nur ein paar Cent - auf dem Handy lässt sich der Bluetooth Data Stream z.b. mit Hilfe einer per "MIT APP inventor" erstellten APP gut anzeigen (Öltemperatur ist am unteren Limit, da ein NTC nicht angeschlossen war. Das Programm erkennt das und sendet die Temperatur dann gar nicht erst zur LED Anzeige). Gruß, Wolfgang |
|
|
|
|
|
#3 |
|
Erfahrener Benutzer
Registriert seit: 13.11.2005
Ort: Perchtoldsdorf
Alter: 64
Beiträge: 5.321
Kilometer: 1.1mio
|
Ganganzeig mit PIC hatte ich auch schon gebaut und auch die Spannung gemessen. Es stellte sich aber heraus, das die Spannung des Bordsystems beim Starten und bei längerer Zeit auf Standgas oft die 12V erheblich unterschreitet und deswegen die Alarmanzeige immer gekommen ist. Die Schwellspannung aber soweit runterzusetzen macht auch keinen Sinn.
Wie ist das bei dir? Hast du da eine Pufferzeit beim Starten eingebaut, bis die Messwerte ausgewertet werden? |
|
|
|
|
|
#4 |
|
Erfahrener Benutzer
Registriert seit: 23.03.2017
Ort: Worms
Beiträge: 140
|
Ja, Spannungsmessung ist etwas tricky. Zunächst war es so, dass Messung bei laufendem Motor recht stark zuckte und dann immer mal wieder auch unter die 12 kam und dann alarmiert wurde. Kondensator am Pineingang hinter Spannungsteiler half nicht viel. Ich habe es jetzt so gemacht, dass ich immer den Mittelwert der letzten 4 Messungen anzeige, dann bleibt das einigermaßen stabil und über 12. Außerdem habe ich ein Poti am Spannungsteiler und das so vertrimmt, dass ich ca. 0,2V mehr anzeige, als real. Da ich Spannung am Rücklicht abgreife, kompensiert das etwas den Spannungsabfall.
Beim Starten und selbst davor, wenn Licht an ist, bin ich auch bei unter 12, aber das ist okay, wenn das dann angezeigt wird. Siehe oben, mache ich ja ohnehin die ersten 30s nachdem die Spannung anliegt. Ausprobiert hatte ich auch eine Spannungsmessleitung direkt an den Pluspol der Batterie, dann muss aber ein Relaiskontakt dazwischen, weil sonst selbst bei Widerständen im Kiloohmbereich die Batterie über den Winter leergenuckelt werden kann. Die Temperaturmessung mit dem NTC hat im Vergleich dazu gar kein Problem. Gruß, Wolfgang |
|
|
|
|
|
#5 |
|
Erfahrener Benutzer
Registriert seit: 13.11.2005
Ort: Perchtoldsdorf
Alter: 64
Beiträge: 5.321
Kilometer: 1.1mio
|
Alles klar! Spannung hatte ich am gleich nach dem Zündschloss abgegriffen, um möglichst wenig Spannungabfall zu haben (wundert mich, das es bis da hinten nur 0,2V sind - bei den "Sparleitungen").
Gutes Projekt! |
|
|
|
|
|
#6 |
|
Erfahrener Benutzer
Registriert seit: 23.03.2017
Ort: Worms
Beiträge: 140
|
Hi Gemeinde,
inzwischen habe ich das ein paar Monate in Betrieb und zwischenzeitlich einiges an Erfahrungen gesammelt. Wenn also jemand etwas Ähnliches probieren möchte, hier ein paar Tipps: Ich hab ein PIC zerschossen, weil ich die Gangsensoren direkt an die PIC Eingänge gelegt habe (plus internem Pull-up). Da reichen induzierte Spannungsspitzen offenbar, um das IC zu zerstören. Danach habe ich einen Serienwiderstand von 22k davorgeschaltet. Führt aber dazu, dass die Anzeige manchmal "flattert", weil die Kontakte für so geringe Ströme nicht gedacht sind. Jetzt habe ich einen 1k Widerstand am Eingang und davor den Gangkontakt mit einem 4,7k Widerstand als Pull-up zu 5V. Das geht! Ein PIC 18F2455 erschien mir ein bisschen als Overkill für diese einfache Anwendung. Geht auch mit einem 16F677, 8 MHz und I2C als Bitbanging Interface. Schaltung ist jetzt auch kleiner und passt in so einen Mini Verteilerkasten unter die linke Seitenverkleidung. Batteriespannung zum Messen muss man direkt an der Batterie, bzw. am Magnetschalter zur Messung abgreifen, alles Andere ist letzten Endes zu ungenau. Relais dazwischen nicht vergessen, siehe oben. Die Spannungsversorgung hatte ich am hinteren Bremsschalter abgenommen, leider bricht die manchmal beim Bremsen so zusammen, dass der Mikrocontroller einen Reset bekommt. Also doch lieber die Spannung von vorne holen. Da ich den NTC an einem anderen Mopped installiert habe, habe ich einen Temperaturschalter am Zylinder montiert und die Programmierung entsprechend geändert. Jetzt zeigt die erste Stelle der LED ein " L" an, so lange die Temperatur unter 55 Celsius liegt. Bei den aktuellen Außentemperaturen von 30 Grad schaltet der Kontakt schon nach 5 Minuten Fahrt, man könnte also durchaus auch auf Kontakte mit höheren Schaltwerten gehen. Ich weiß, dass das nur für Wenige von Interesse ist, wäre aber ärgerlich, wenn die dann auch die komplette Trial and Error Schleife durchlaufen müssen. Gruß, Wolfgang |
|
|
|
|
|
#7 |
|
Erfahrener Benutzer
Registriert seit: 13.11.2005
Ort: Perchtoldsdorf
Alter: 64
Beiträge: 5.321
Kilometer: 1.1mio
|
Fein, das du es hinbekommen hast - ja, ist eine gute Info für alle, die sowas angehen wollen......
|
|
|
|
|
|
#8 |
|
Erfahrener Benutzer
Registriert seit: 23.03.2017
Ort: Worms
Beiträge: 140
|
hier noch ein paar Bilder:
- Temperaturschalter - Einbau - linkes Seitenteil Gruß! |
|
|
|
|
|
#9 |
|
Erfahrener Benutzer
Registriert seit: 13.11.2005
Ort: Perchtoldsdorf
Alter: 64
Beiträge: 5.321
Kilometer: 1.1mio
|
Da hinten misst du natürlich nicht die echte Öltemperatur - die wird etwas höher liegen + 10-20°C). Aber als Indikator völlig ausreichend.
|
|
|
|
|
|
#10 |
|
Erfahrener Benutzer
Registriert seit: 23.03.2017
Ort: Worms
Beiträge: 140
|
Finales Update:
Hab noch ein ganz klein wenig an der Software rumgefrickelt, hier der finale Stand, damit es ggf. jemand bei Interesse nachmachen kann: ;************************************************* ***************************** ; * ; Refer to the MPASM User's Guide for additional information on the * ; features of the assembler. * ; * ; Refer to the PIC16F677 Data Sheet for additional * ; information on the architecture and instruction set. * ; * ;************************************************* ***************************** ; * ; Filename: I2C677.asm * ; Date: 06.08.2024 * ; File Version: 2.0 * ; * ; Author: Wolfgang * ; * ;************************************************* ***************************** ; * ; Files required: P16F677.INC * ; * ;************************************************* ***************************** LIST P=PIC16F677 ;directive to define processor #include <P16F677.INC> ;processor specific variable definitions ;************************************************* ***************************** ;Motorbike comp to show gear, battery and temperature for GS500 ;Configuration bits ; CONFIG ; 0x2007h __CONFIG _INTOSCIO & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOREN_ON ; Program variables PVVARS UDATA 0x40 ;variables in access RAM (3+10 bytes) udata_acs for PIC18 WREG_TEMP RES 1 ;variable used for context saving STATUS_TEMP RES 1 ;variable used for context saving PCLATH_TEMP RES 1 ;variable used for context saving PVVARS1 UDATA 0x44 mcounter RES 1 ;counter, incremented each blink period (0,26s), not reset modestat RES 1 ;status, bit0=oil alarm, bit1=batt alarm, ;bit3=show seq initiated, bit4=show seq active, ;bit5=overtime, bit7=start Hunds RES 1 ;variables for hex to decimal conversion Tens RES 1 Ones RES 1 binin RES 1 count RES 1 buf RES 1 oldvolt RES 1 ;for averaging avgvolt RES 1 ;result of average TIMER_VAR UDATA 0x50 ; could be banked timeri RES 1 ; variable for inner loop timero RES 1 ; timer one ms timerx RES 1 ; timer x ms ; The TM1637 uses an I2C 'like' signalling method with two caveats: ; 1. It does not use an I2C address so you can't have any other device on the bus. ; 2. I2C sends data MSB first, the TM1637 expects data LSB first. ; Since this code uses the hardware MSSP module in the PIC, the data to be sent ; must be reversed before loading into the PICs MSSP buffer register. #define WriteDispAddrAuto 0x02 ;//0100 0000 = 40h #define WriteDispAddrFix 0x22 ;//0100 0100 = 44h #define AddressZero 0x03 ;//1100 0000 = C0h ; See TM1637 datasheet page 5 ; Display control table Data Byte Reversed #define DisplayOn1 0x11 ;10001000 00010001 #define DisplayOn2 0x91 ;10001001 10010001 #define DisplayOn4 0x51 ;10001010 01010001 #define DisplayOn10 0xD1 ;10001011 11010001 #define DisplayOn11 0x31 ;10001100 00110001 #define DisplayOn12 0xB1 ;10001101 10110001 #define DisplayOn13 0x71 ;10001110 01110001 #define DisplayOn14 0xF1 ;10001111 11110001 #define DisplayOff 0x01 ;10000000 00000001 #define battery PORTA,0 ;battery voltage #define oilswitch PORTC,2 ;temp switch instead of NTC #define alarmpin PORTx,x ;alarm LED #define gear1 PORTB,7 ;low=gear 1 #define gear2 PORTB,6 ; #define gear3 PORTB,5 ; #define gear4 PORTB,4 ; #define gear5 PORTC,4 ; #define gear6 PORTC,5 ; #define i2csda PORTC,0 ;software i2c; (PORTC,1 reserved) #define i2cscl PORTA,1 ;(wired to PORTA,4; PORTA,4 must be input!) #define neutral PORTA,3 ;input for neutral switch #define lifebit PORTC,3 ;life-bit, is toggled periodically (no MCLR) #define relay PORTA,5 ;drives a relay ; table in RAM with values to be displayed on LED LEDTAB_VAR UDATA 0x58 ; values to be sent to LED via I2C LEDTAB Voltl RES 3 Oill RES 3 Gearl RES 1 Resvl RES 1 ;table for 7-Segment Display org 0x0300 Tab7Seg: andlw 0x0F ;range 0-15 addwf PCL,f retlw 0xFC ;0 retlw 0x60 ;1 retlw 0xDA ;2 retlw 0xF2 ;3 retlw 0x66 ;4 retlw 0xB6 ;5 retlw 0xBE ;6 retlw 0xE0 ;7 retlw 0xFE ;8 retlw 0xF6 ;9 retlw 0x0 ;blank retlw 0x1C ;L retlw 0xFC ;O retlw 0x7C ;U retlw 0x2 ;- retlw 0x2 ;- ;colon is the 8th segment on grid2/display2 from left (TM1637) ;i.e. LSB must be set because of the reversed order ( 1 = 0x60 1: = 0x61) ; battery: 25,5V = 5V at Uin = 255 dec. ADC out ; batt --9.064k--+--2,2K-- 0V ; I I = input Pin PIC ;************************************************* ***************************** ;Reset vector ; This code will start executing when a reset occurs. ORG 0x0 goto Main ;go to start of main code ;************************************************* ***************************** ; interrupt vector ; This code will start executing when an interrupt occurs ORG 0x0004 goto interrupt ;goto interrupt main code ;************************************************* ***************************** ; Start of main program ; The main program code is placed here. Main: ; *** main code goes here *** ; internal oscillator setup banksel OSCCON movlw 0x71 ; IRCF = 111 (8 MHz) movwf OSCCON ; port initialization movlw b'11011101' ; set PORTA 1,5 to output, rest is input movwf TRISA ; TRISA/B/C are in same bank as OSCCON movlw b'11111111' ; set PORTB to input movwf TRISB movlw b'11110111' ; PORTC 3 output, lifebit movwf TRISC ; rest of PORTC is input banksel WPUB movlw b'11111111' movwf WPUB ; weak pull-ups on PORTB (4-7) ; watchdog init clrwdt banksel OPTION_REG movlw b'00000000' ; pull-ups enabled movwf OPTION_REG ; prescaler assigned to timer banksel WDTCON movlw b'00010110' ; prescaler WDT 1:65536 movwf WDTCON ; WDT period appr. 470ms clrwdt ; A/D initialization banksel ADCON1 movlw b'01010000' ; 16Tosc conversion clock movwf ADCON1 banksel ANSEL movlw b'00000001' movwf ANSEL ; set RA0 to analog input clrf ANSELH ; all other ports digital I/O banksel ADCON0 movlw b'00000001' ; ADC enabled, left justified, VDD ref. movwf ADCON0 nop ; timer and interrupt initialization ; timer 1 used, general and peripheral interrupt must be enabled ; timer 1: 8 MHz / 4 / 8 = 250 kHz -> 0.004 ms clock for 16bit timer ; overflow every 262 ms -> interrupt movlw b'00110001' ; FOSC/4, 1:8 prescaler, Timer 1 on banksel T1CON movwf T1CON movlw b'11000000' ; interrupt GIE and PEIE enabled movwf INTCON banksel PIE1 movlw b'00000001' ; enable TMR1IE movwf PIE1 bcf STATUS,RP0 bcf STATUS,RP1 ; select bank 0, i.e. PORTA/B/C ; initialisation PIC done ; init variables clrf mcounter clrf modestat bsf relay ; power relay to check battery voltage ; Memory init for LED values PINIT: clrw ; clear w movwf Voltl ; fill 7 adresses with "0" movwf Voltl+1 movwf Voltl+2 movwf Voltl+3 movwf Voltl+4 movwf Voltl+5 movwf Voltl+6 call i2c_present call init_LED movlw .250 call xms ; wait 750ms after init clrwdt movlw .250 call xms clrwdt movlw .250 call xms clrwdt goto mainstart ; initialisation PIC done ; loop for sending data to RS232 / I2C mainstart: nop movlw .100 call xms ; wait 100ms (loop update time) clrwdt alarmLED: bcf modestat,0 ;reset oil alarm btfsc oilswitch ;test temperature switch bsf modestat,0 ;set oil alarm movf modestat,w ;test for alarm andlw b'00000011' ;only check alarm bits 0,1 btfss STATUS,Z goto alarm1 ;bcf alarmpin ;status=0, no alarm, go on goto checkgear alarm1: andlw b'00000010' ;test battery alarm btfsc STATUS,Z goto alarm3 btfsc lifebit ;battery alarm! nop ;bsf alarmpin btfss lifebit nop ;bcf alarmpin goto checkgear ;blink alarm alarm3: btfsc modestat,0 ;bsf alarmpin ;bit0, oil alarm checkgear: nop clrf Gearl ;check gear incf Gearl,f btfss gear1 goto setgear ;yes gear 1, so stop incf Gearl,f btfss gear2 goto setgear incf Gearl,f btfss gear3 goto setgear incf Gearl,f btfss gear4 goto setgear incf Gearl,f btfss gear5 goto setgear incf Gearl,f btfss gear6 goto setgear clrf Gearl btfss neutral goto setgear ;yes neutral movlw 0xFF ;ungültig movwf Gearl ;writing status to Gearl finished setgear: nop LEDseq: call writeLED ;display on LED endloop: goto mainstart ;code for LED is here ;write gear if no alarm ;write battery value for 1/2 minute after boot ;write Oil Temperature if oil alarm ;write battery if battery alarm writeLED: nop btfss mcounter,7 ;means: appr. 32s elapsed goto writeLED1 bsf modestat,7 writeLED1: btfss modestat,7 ;if less than 32s after boot goto showbatt ;jump to showbatt LEDalmtest: movf modestat,w andlw 0x03 ;mask for alarm bits 0 and 1 btfsc STATUS,Z goto showgear ;if no alarm goto showgear btfsc modestat,1 ;test for battery alarm goto showbatt showgear: call i2c_on movlw AddressZero call i2c_tx movlw 0x0 testoilsw: btfsc oilswitch ;display "L" if oil temp low movlw 0x1C call i2c_tx ;write 7 Segment to LED clrw ; blanks call i2c_tx ;write 7 Segment to LED clrw call i2c_tx ;write 7 Segment to LED lastdigit: movlw 0x2 btfsc Gearl,7 ;test for invalid goto lastdigitend movlw HIGH Tab7Seg movwf PCLATH ;put adress of pointer to PCL movf Gearl,w ;value*2 to w call Tab7Seg ;this causes the jump into table lastdigitend: call i2c_tx ;display gear call i2c_off goto LEDon showbatt: nop call i2c_on movlw AddressZero call i2c_tx movlw HIGH Tab7Seg movwf PCLATH ;put adress of pointer to PCL movf Voltl,w ;value to w call Tab7Seg ;this causes the jump into table call i2c_tx ;write 7 Segment to LED movlw HIGH Tab7Seg movwf PCLATH ;put adress of pointer to PCL movf Voltl+1,w ;value to w call Tab7Seg ;this causes the jump into table addlw .1 ;show colon call i2c_tx ;write 7 Segment to LED movlw HIGH Tab7Seg movwf PCLATH ;put adress of pointer to PCL movf Voltl+2,w ;value to w call Tab7Seg ;this causes the jump into table call i2c_tx ;write 7 Segment to LED movlw 0x0 ;last digit blank call i2c_tx call i2c_off resetseq: btfsc mcounter,7 ;if sequence was active and time expired bcf modestat,4 ;reset sequence active bit goto LEDon LEDon: call i2c_on ;turn display on movlw DisplayOn14 call i2c_tx call i2c_off return ; is called by interrupt ; each 0.262 s ; following conditions of mcounter0 apply: ; 0 = start ADC, ch.0 1 = read ADC, ch.0 interrupt: banksel ADCON0 ; also PORTC, ADRESH and PIR1 (bank 0) movwf WREG_TEMP ;save w swapf STATUS,w movwf STATUS_TEMP ;save STATUS register movf PCLATH,w movwf PCLATH_TEMP ;save PCLATH register movlw b'00001000' ;mask bit 3 xorwf PORTC,f ; toggle lifebit btfsc mcounter,0 goto readadc ;bit 0 of mcounter set, so read ADC startadc: bsf ADCON0,GO ;set GO-bit of ADC goto iend readadc: movf ADRESH,w ;read ADC addwf oldvolt,f rrf oldvolt,w movwf avgvolt movf ADRESH,w movwf oldvolt movf avgvolt,w bsf modestat,1 ;set battery alarm sublw .120 btfsc STATUS,C goto batt1 ;batt < 12V, go on with alarm movf avgvolt,w sublw .148 btfsc STATUS,C ;batt > 14.8V, go on with alarm bcf modestat,1 ;else reset battery alarm batt1: movf ADRESH,w call binary_to_bcd ;convert to 0.0V - 25.5V movf Hunds,w movwf Voltl movf Tens,w movwf Voltl+1 movf Ones,w movwf Voltl+2 ; clear interrupt flag and return from interrupt iend: incf mcounter,f bcf PIR1,TMR1IF movf PCLATH_TEMP,w movwf PCLATH ;restore PCLATH register swapf STATUS_TEMP,w movwf STATUS ;restore working register swapf WREG_TEMP,f swapf WREG_TEMP,w retfie binary_to_bcd: ; convert 8 bit number to 3 decimal digits movwf binin clrf Hunds swapf binin, W ; swap the nibbles addwf binin, W ; so we can add the upper to the lower andlw B'00001111' ; and lose the upper nibble (W is in BCD from now on) btfsc STATUS, DC ; if we carried a one (upper + lower > 16) addlw 0x16 ; add 16 (the place value) (1s + 16 * 10s) btfsc STATUS, DC ; if we carried a one (upper + lower > 16) addlw 0x06 addlw 0x06 btfss STATUS, DC addlw -0x06 btfsc binin, 4 ; 16's place addlw 0x16 - 1 + 0x06 ; add 16 - 1 btfss STATUS, DC addlw -0x06 btfsc binin, 5 ; 32nd's place addlw 0x30 ; add 32 - 2 btfsc binin, 6 ; 64th's place addlw 0x60 ; add 64 - 4 btfsc binin, 7 ; 128th's place addlw 0x20 ; add 128 - 8 % 100 addlw 0x60 ; check for digit overflows rlf Hunds, F ; pop carry in hundreds' LSB btfss Hunds, 0 addlw -0x60 movwf Tens btfsc binin,7 ; remember adding 28 - 8 for 128? incf Hunds, F ; add the missing 100 if bit 7 is set andlw 0x0F movwf Ones swapf Tens,f movlw 0x0F andwf Tens,f return ; I2C subroutines ; I2C Takt ist 100kHz, d.h. Taktlänge ist 10us, 1 Puls hat 5us ; 5us entsprechen bei 20Mhz 100 Takten, d.h. 25 Cyclen/Befehle ; 5us entsprechen bei 8Mhz 40 Takten, d.h. 10 Cyclen/Befehle i2c_present: nop ; return with 0 if slave present, otherwise 1 call onems ; don't check retlw 0x0 ; assume everything is okay i2c_on: ; SDA changes to low, when SCL is high banksel TRISC bsf TRISC,0 ; bring SDA high (=PORTC 0 to input) bcf STATUS,RP0 bcf STATUS,RP1 ; select bank 0, i.e. PORTA/B/C i2c_o1: call fiveus call fiveus ; wait one I2C cycle btfss i2csda ; port is input, level should be high goto i2c_o1 ; no, so wait bsf i2cscl ; set SCL high call fiveus ; wait, just to make sure call fiveus ; SDA and SCL are now high ; now begin with ON condition banksel TRISC bcf TRISC,0 ; set PORTC 0 to output (i2csda) bcf STATUS,RP0 bcf STATUS,RP1 ; select bank 0, i.e. PORTA/B/C bcf i2csda ; PORTC0/SDA is now output and low call fiveus call fiveus bcf i2cscl ; SDA and SCL are low call fiveus ; wait a bit call fiveus return ; subroutine ein Byte aus W senden i2c_tx: nop ; -> zum I2C-Slave übertragen call WrI2cW ; 8 Bit aus W nach I2C banksel TRISC ; set PORTC 0 to input (i2csda) bsf TRISC,0 ; d.h. SDA high bcf STATUS,RP0 bcf STATUS,RP1 ; select bank 0, i.e. PORTA/B/C call fiveus bsf i2cscl ; SCL high i2c_t2: ;btfsc i2csda ; ACK schon empfangen? ;goto i2c_t2 ; nein, noch nicht nop ; ja, Daten sind im Slave call fiveus ; prüfe nicht ACK, warte einfach etwas bcf i2cscl ; SCL low again, transmission completed call fiveus call fiveus return ;************************************************* **** ; I2C-Periode ist 10 µs ; schiebt das Byte aus W in den I2C ; MSB zuerst WrI2cW: ; Takt unten, Daten unten ; Datenbyte in w movwf buf movlw .8 movwf count ; 8 Bits banksel TRISC ; needs 2 instructions bcf TRISC,0 ; set PORTC 0 output (i2csda) bcf STATUS,RP0 bcf STATUS,RP1 ; select bank 0, i.e. PORTA/B/C WrI2cW1: bcf i2csda ; set SDA low (Datenleitung) rlf buf,f btfsc STATUS,C ; 0? bsf i2csda ; set SDA high ; SDA ist set to the right data level nop ; SDA setting time bsf i2cscl ; SCL high (Data bit now valid) call fiveus ; SCL high halten für 1/2 Periode bcf i2cscl ; SCL output = low nop ; one more cycle so that appr. 5 us since last SCL change decfsz count,f ; 8 Bits raus? goto WrI2cW1 ; nein return ; ja ; I2C-Bus wieder freigeben (SDA wird high, wenn SCL bereits high ist) i2c_off: bcf i2cscl ; make sure, SCL is low call fiveus call fiveus ; wait banksel TRISC bcf TRISC,0 ; SDA is output bcf STATUS,RP0 bcf STATUS,RP1 ; select bank 0, i.e. PORTA/B/C bcf i2csda ; make SDA low (PORTC,0) call fiveus ; wait while SCL and SDA are low call fiveus bsf i2cscl ; SCL high (PORTA) call fiveus ; wait a I2C cycle call fiveus banksel TRISC ; set now SDA high bsf TRISC,0 ; set PORTB 0 to input (i2csda) bcf STATUS,RP0 bcf STATUS,RP1 ; select bank 0, i.e. PORTA/B/C, SDA should be high now call fiveus call fiveus return ; reset I2C bus i2c_res: banksel TRISC ; release SDA bsf TRISC,0 ; set PORTC 0 to input (i2csda) bcf STATUS,RP0 bcf STATUS,RP1 ; select bank 0, i.e. PORTA/B/C, SDA should be high now movlw .9 movwf count ; 9 repeats i2c_r1: bcf i2cscl ; SCL low call fiveus ; SCL low halten für 1/2 Periode nop bsf i2cscl ; SCL high call fiveus decfsz count,f ; 9 mal? goto i2c_r1 ; nein call i2c_off return ; Init LED Display ; Send data to TM6137 module using Standard Ports ; See TM1637 datasheet Page 4 ; Write SRAM data in address auto increment 1 mode. init_LED: call i2c_res call onems call i2c_on movlw WriteDispAddrAuto call i2c_tx call i2c_off call onems call i2c_on movlw AddressZero call i2c_tx movlw 0xFF ;all segments call i2c_tx ;write 7 Segment to LED movlw 0xFF call i2c_tx ;write 7 Segment to LED movlw 0xFF call i2c_tx ;write 7 Segment to LED movlw 0xFF call i2c_tx call i2c_off call LEDon return ; wait 5 microseconds (100 cycles at 20 MHZ = 25 instructions of 4 cycles each) ; (80 cycles at 16 MHz = 20 instructions) fiveus: ; loop with 16/20 instructions plus 5 more for call up ;movlw .5 ; for 20MHz ;movlw .4 ; for 16 MHz movlw .2 ; for 8 MHz movwf timero loop5us: nop decfsz timero,f ; 4 instructions loop goto loop5us return ; wait one millisecond (5000 instr. at 20 MHz) onems: movlw .100 banksel timero movwf timero loopms1: ;movlw .16 ;loop f0r 10 us = 50 instructions ;movlw .13 movlw .6 movwf timeri loopms2: decfsz timeri,f ; loop = 3 instr. goto loopms2 decfsz timero,f goto loopms1 return ; wait "w" ms xms: banksel timerx movwf timerx loopxms: movlw .100 ;loop for onems embedded to save calls movwf timero xloopms1: ;movlw .16 ;loop f0r 10 us = 50 instr. ;movlw .13 movlw .6 movwf timeri xloopms2: decfsz timeri,f ; loop = 3 instr. goto xloopms2 decfsz timero,f goto xloopms1 decfsz timerx,f goto loopxms return ;************************************************* ***************************** ;End of program END |
|
|
|
![]() |
| Lesezeichen |
|
|
Ähnliche Themen
|
||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Ganganzeige | towe | Elektrik, Elektronik und Beleuchtung | 33 | 01.12.2019 21:33:49 |
| externe Ganganzeige | Predator112 | Elektrik, Elektronik und Beleuchtung | 5 | 15.05.2017 09:57:41 |
| Ganganzeige | Lowsider | Elektrik, Elektronik und Beleuchtung | 14 | 07.04.2014 21:52:12 |
| Ganganzeige | Verkleidungen, Anbauteile und Zubehör | 20 | 22.08.2007 20:36:43 | |