Moin Männers,
ich habe das gute Wetter in den letzten Tagen genutzt, über 5t Erde in eine Mulde geschüppt und 3 Kabel von meiner Hütte ins Haus gezogen und angeschlossen.
Eins dieser Kabel dienen dazu den erzeugten Strom von der PV Anlage die auf dem Dach der Hütte ist in ein Heizstab der Heizung zu pumpen.
Ein anderes liefert von der Heizung das "OK" fürs reinpumpen. Beides getestet, soweit alles funktiontüchtig.
(das dritte ist nur Ethernet, das alte wurde als Zugseil genutzt :D )
Derzeit schalte ich manuell die Heizung ein und eine provisorische LED zeigt mir das OK der Heizung.
Nun soll dafür eine Steurung her.
Mein gedanke (bis jetzt):
-akku Spannung (der PV) messen >= 27 V (24V System, bei 27V ist der Akku sogut wie voll und zumindest bisschen Sonnenenergie gibts auch)
-Rückmeldung der Heizung auf OK abfragen
-Heizung einschalten
-akku Spannung <=22V (bei 20V macht der Wechselrichter dicht)
-Heizung abschalten
-2h warten ( akku kann nicht ehr wieder voll sein)
-es geht von vorne los
-Watchdog soll genutzt werden
Die Frage die ich mir stelle:
-Versorgung der Schaltung? Z Diode, Spannungsregler... Durch das messen der Akku spannung muss die Versorungsspannung schon recht stabil sein, bis auf ein Transistor welches das Schütz schalten soll für die Heizung wird es kaum große verbraucher geben.
-Sollte ein LCD, 7 Segment oder einfach paar Status LEDs eingeplant werden? Was würdet ihr (und warum) tun? Hat alles seinen gewissen Reiz :D
Freue mich auf eure gedanken
Cobra
Fünf Tonnen Erde geschüppt...? Aha, dann machst du jetzt für eine Weile erstmal in "habe Rücken" ! Mal ehrlich: kann ich mir im Moment nicht wirklich vorstellen. Bist du so'n Herkulestyp und zudem Vorturner in Buddy-Bilding-Studios?
Stromversorgungen mache ich seit vielen Jahren nur noch mit solch kleinen IC-Festspannungs-Reglern. Wobei ich jede Form von sich im Betrieb ändernden Lastströmen - wozu schon mehrere LEDs zählen - outsurce, indem ich deren positiven Versorgunsanschluss direkt an die Energiequelle anschließe, also nicht aus dem IC-Kreis heraus. Muss sicher nicht betont werden, aber Spannungsspitzen des Schaltschützes sollte im µC-Kreis nicht mehr ankommen.
Die Anzeige? Ganz einfach ganz einfach halten. Mit einigen wenigen LEDs starten und erst mal den Gesamtbetrieb sicher stellen. Wenn danach das Fell juckt, kann auf LCD-Anzeige aufgewertet werden.
Na dann mal auf weiteren Klimawandel und viel Sonnenschein.
Grüße, picass
Nabend Picass,
Bin alles andere als ein Herculestyp :P
Aber wenn man ein Haus baut und nicht so viel Geld hat muss man anpacken. Will nicht wissen wie viel Beton ich mit der Schubkarre bewegt habe...
Habe vorsichtshalber auf die Rechnung geschaut,es waren 6,25 Tonnen. 2 Abende und ein Samstag. Und ja, danach habe ich es gemerkt ;)
Zurück zum Thema:
Witzigerweise hatte ich ebenfalls beide Überlegungen. IC für Spannungsversorgung sowie erstmal nur mit LEDs paar Status Anzeigen.
Moin Männers!
Ich habe nun mal "auf die schnelle" ein Programmteil geschrieben, im simulator siehts gut aus.
Heute also fix eine Lochrasterplatine zusammen gezimmert und - geht nicht.
Der Analogwandler will einfach nicht.
Ich finde einfach den Grund dafür nicht. Hoffe da auf eure Tipps.
der Pic ist ein 16F690. Leider unterstützt dein kein direktes debuggen. Zumindest sagt das mein mplab.
Es wird der interne Takt benutzt.
für den Analogteil wären denke das die wichtiges Code ausschnitte:
Banksel TRISC
clrf TRISC ;Port C Ausgänge
movlw B'00110000'
movwf ADCON1
banksel WPUB
movwf WPUB
movlw b'00001111' ;RA0-RA2 u RA4 Analog, RC0-RC3 Digital
movwf ANSEL
;Akuuspannung messen
movlw b'00000001' ; A/D wandler einschalten, AN= aktiv, VDD als Vref, messung starten
movwf ADCON0
movlw d'50'
CALL WaitX ;50ms warten
BSF ADCON0,GO ;Start conversion
BTFSC ADCON0,GO ;Is conversion done?
GOTO $-1 ;No, test again
movfw ADRESH ; Akku Spannung messen
movwf Temp0 ;
der Teil mit dem Englischen Kommentar war der letzte einfall (von der Doku), leider auch das ohne erfolg.
In der Simulation kann ich eine Spannung an dem pin AN0 anlegen und diese wird auch gemessen.
Verstehe einfach nicht was hier nun fehlt.
Der Gesamt Code wäre hier:
; Example of using GPR Uninitialized Data
;
GPR_VAR UDATA
Temp0 RES 1 ; User variable linker places
Temp1 RES 1 ; User variable linker places
Temp2 RES 1 ; User variable linker places
PV_State RES 1 ; Status Register von der PC Steuerung
;
; ; Example of using Access Uninitialized Data Section (when available)
; ; The variables for the context saving in the device datasheet may need
; ; memory reserved here.
; INT_VAR UDATA_ACS
; W_TEMP RES 1 ; w register for context saving (ACCESS)
; STATUS_TEMP RES 1 ; status used for context saving
; BSR_TEMP RES 1 ; bank select used for ISR context saving
;
;*******************************************************************************
; TODO PLACE VARIABLE DEFINITIONS GO HERE
;*******************************************************************************
; Reset Vector
;*******************************************************************************
RES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of program
;*******************************************************************************
; TODO Step #4 - Interrupt Service Routines
;
; There are a few different ways to structure interrupt routines in the 8
; bit device families. On PIC18's the high priority and low priority
; interrupts are located at 0x0008 and 0x0018, respectively. On PIC16's and
; lower the interrupt is at 0x0004. Between device families there is subtle
; variation in the both the hardware supporting the ISR (for restoring
; interrupt context) as well as the software used to restore the context
; (without corrupting the STATUS bits).
;
; General formats are shown below in relocatible format.
;
;------------------------------PIC16's and below--------------------------------
;
ISR CODE 0x0004 ; interrupt vector location
;
; <Search the device datasheet for 'context' and copy interrupt
; context saving code here. Older devices need context saving code,
; but newer devices like the 16F#### don't need context saving code.>
;
; RETFIE
;
; TODO INSERT ISR HERE
;*******************************************************************************
; MAIN PROGRAM
;*******************************************************************************
#include GeneralConfigs.inc
; CONFIG
; __config 0x3FCC
__CONFIG _FOSC_INTRCIO & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _IESO_OFF & _FCMEN_OFF
#Define StatusLED PORTC,0
#Define Relais PORTC,1
#Define ErrorLED PORTC,2
#Define AkkuVolt PORTA,0 ;BereitMeldung PV Akku und Heizung bereit zum zuheizen
#Define Temperatur1 PORTA,1
#Define EIN_Taster PORTB,4
#Define AkkuVoltOK PV_State,0 ;Akku ist so gut wie voll und Heizung ist aufnahme bereit
#Define AkkuTempOK PV_State,1
#Define AutoON PV_State,2
extern WaitX
global Temp0,Temp1,Temp2
MAIN_PROG CODE ; let linker place main program
START
;IO Config setzen
bsf OSCCON,SCS ;internen takt benutzten
clrf PORTC
Banksel TRISC
clrf TRISC ;Port C Ausgänge
movlw B'00110000'
movwf ADCON1
movlw b'11110000' ; Pull UP für RB4-RB7 ON
banksel WPUB
movwf WPUB
movlw b'00001111' ;RA0-RA2 u RA4 Analog, RC0-RC3 Digital
movwf ANSEL
clrf ANSELH ;RB4-5 und RC 6-7 Digital IO
BCF STATUS,RP0 ;Bank 0
BCF STATUS,RP1
bcf AkkuVoltOK
StartWait
CLRWDT ;Watchdog zurück setzen
bsf StatusLED ; LED einschalten -> Spannung liegt an
;Akuuspannung messen
movlw b'00000001' ; A/D wandler einschalten, AN= aktiv, VDD als Vref, messung starten
movwf ADCON0
movlw d'50'
CALL WaitX ;50ms warten
BSF ADCON0,GO ;Start conversion
BTFSC ADCON0,GO ;Is conversion done?
GOTO $-1 ;No, test again
movfw ADRESH ; Akku Spannung messen
movwf Temp0 ;
;
; Spannungsteiler wird so eingestellt das bei 32V 5V am Pic ankommen
;es ergeben sich diese Spannungen
;5V/1024 => 0,0048828125 ca 0,005v => ein digit
;32V => 5V
;28V=>5V/32*28=>4,375 - start spannung
;22V=>5/32*22=>3,43 - stopp spannung
;5V=> 1024
;4,37=>1024/5*4,375=> 896 => 11100000/00 (224) 0xE0 -start Wert D'224' nur High in klammer
;3,43=>1024/5*3,43=> 702=> 10101111/10 (175) 0xAF -stopp Wert D'175' nur High in klammer
;einschalten
bsf STATUS,C ;Carry bit setzen
SUBLW d'224' ; Startwert-akku Spannung wenn Akkuspannung > startwertist carry bit false
btfss STATUS,C ;überspringe nachfolgenden wenn gesetzt
bsf AkkuVoltOK
;ausschalten
movfw Temp0
SUBLW d'175' ; Startwert-akku Spannung wenn Akkuspannung > Endwert ist carry bit false
btfsc STATUS,C ;überspringe nachfolgenden wenn gesetzt
bcf AkkuVoltOK
;Schalter Automatik EIN
BCF AutoON
BTFSS EIN_Taster ;//Wenn Schalter belegt bit = False
bsf AutoON
;Freigabe heizen zusammen legen
movfw PV_State
SUBLW B'00000101'
BTFSS STATUS,Z
goto RelaisOFF
goto RelaisON
RelaisON
bsf Relais
goto StartWait
RelaisOFF
bcf Relais
goto StartWait
END
wäre euch sehr dankbar wenn ihr da noch eine Idee habt...
hustene grüße (scheiß Erkältung)
Cobra
Nachtrag: Auch meine Art der Auswertung funktioniert scheinbar nur in der
simulation...
Habe nun die Analog spannung erstmal bei seite geschoben und den Rest überprüfen wollen.
Beim AutoEIN schalter kam aber nichts. Habe dann HW und SW nochmal überprüft.
HW alles OK - SW - mit ein Testprogramm konnte eine LED eingeschaltet werden
bei mein Code wird mit ein SUBLW die bits abgezogen die an sein müssen, wenn ergebnis 0 ist, somit das Z
Flag gesetzt ist wird also dahin gesprungen zum einschalten. genau das passiert aber im "echten" pic einfach nicht :(
Wenn ihr da ebenfalls ideen habt, gern her damit...
Hi cobra
a) mir fällt auf, dass keine Bankumschaltung verwendet wird!
b) AD-channel ist RA0/AN0:RA2/AN2
Diese pins müssen als inputs in TRISA und in ANSEL als analog konfiguriert sein.
c)in ADCON0 würde ich bit7=1 setzen, für Result right justfied.
Vielleicht hilft's
MfG Ottmar
Moin Ottmar,
danke fürs drüberschauen.
zu
a) : Doch, banksel WPUB bringt mich in die Bank 2, da ist dann auch ADCON1 sollte also passen.
b) TRISA ist bei Reset immer gesetzt und somit sind es bereits eingänge.
c) nope, benutzt nur die 8 bits vom Highteil, da ist rechts bündig angenehmer ;)
Hi cobra,
Verwendest Du den sleepmode? Wenn nicht würde ich den Versuch machen in ADCON1 nicht frc sondern z.B. fosc/16 o.ä. zu verwenden.
Moin Ottmar, da stand vorher Mal nix drin also fosc/2, da ich aber den internen oszi nutze hatte ich gedacht das der dann auch auf intern stehen muss.
Werde aber Mal da was anderes versuchen. Aber erst morgen.
Nun erstmal schlafen und schauen wies mir morgen geht.
Habe übrigens schon ein anderen 16f690 genommen. Selbe Ergebnis.
Kann mich nicht erinnern schonmal Probleme mit analog Zeugs in der Form gehabt zu haben.
Auch das die Routine mit der Prüfung auf z nun nicht geht... Seltsam bis frustrierend
seufz,
guten morgen.
Die Gute Nachricht: Bin nun eine Woche krank geschrieben und dank Laptop und TestKoffer kann ich auf dem Sofa oder Bett weiter Forschen.
Habe nun ein 18F14K22 gefunden, dieser ist Pingleich mit dem 16F690. Mein Gedanke war es damit debuggen zu können um besser die Probleme zu finden.
Allerdings schaffe ich es nicht das Projekt auf dem 18F ans laufen zu kriegen.
Habe alle Fehler weg bekommen bis auf diesen:
Error - file './build/default/production/Main.o', section 'Haupt', Symbol '_Haupt_002A' is not word-aligned.
It can not be used as the target of a call or goto instruction.
Errors : 1
Verstehe aber nicht was der mir sagen will. Der Main teil wird nicht mit CALL oder GOTO aufgerufen.
Kennt das jemand? Würde ja 2 " word-aligned " machen, aber finde auch da nicht wo oder wie ich das machen soll. Bei mein anderen 18F steht da auch nichts anderes...
wieder ein Schritt weiter.
Der 18F mag wohl die in der Doku verwendete sprung methode nicht. $-1
Dafür namen gegeben und nun kann ich übersetzen und debuggen.
Dabei ist mir nun was aufgefallen:
in mein Register PV_State kann ich weder löschen, noch schreiben o.O muff.
Ebenfalls laufen meine Zeitschleifen irgenwie garnicht oder sehr langsam, da bin ich noch am schauen.
Hi cobra,
ich komme nochmals auf das banking vom 16f690zurück.
Nach dem Programmstart ist Bank 0 aktiv.
OSSCON liegt aber in Bank 1
dann würde die Osc.config 500kHz ins Leere gehen.
Erst danach schaltest Du mit
BANKSEL TRISC auf Bank 1 um.
vielleicht hilft's
drück Dir die Daumen
Zitat von: ^Cobra in 07.04.2025, 12:17:39 CESTDer 18F mag wohl die in der Doku verwendete sprung methode nicht. $-1
der 18er hat eine andere Adressierung, da besteht ein Befehl aus zwei Byte, GOTO $-2 sollte dann gehen. Der Goto-Befehl besteht sogar aus zwei Worte = 4 Byte.
Der zweite Teil von Goto fängt mit NOP an, gefolgt von der Sprungadresse. Falls man aus versehen auf die zweite Hälfte trifft, passiert also nichts.
Auch die Interrupt-Adresse ist anders statt 0x0004 jetzt 0x0008, es gibt sogar zwei Interrupt einen HI und einen Lo 0x0018
Mahlzeit ihr beiden.
Ich habe nun mein Programm ans laufen gekriegt, so wie es soll. (erstmal)
zum Schluss hatte ich das Problem das nicht in mein Register PC_State das drin stand was sollte. bzw. es
schien so als würde dieses Register einfach nicht beschrieben.
Es stellte sich herraus das dieses verhalten bei allen Variablen war, und somit meine Zeitschleifen ins unendliche verliefen.
Grund:
Statt UDATA musste ich nun UDATA_ACS bei den 18F benutzen.
Beim versuch das bei mein 16F Projekt umzusetzen scheiters aber wieder an der Übersetzung.
Hier konnte ich aber mit einer Blinkende LED die Register der Zeitschleife überprüfen. Die
scheint also zu laufen.
@pic18 Achja, das mit dem $-2 sagt mir dunkel wieder was... da war mal etwas :P
werde morgen Früh mit meinen Testaufbau mal versuchen die Heizstäbe einzu schalten. Werde berichten.
ich drehe hier mit dem Virenschutz auf der Arbeit noch durch
Zitat von: ^Cobra in 07.04.2025, 10:58:08 CESTMein Gedanke war es damit debuggen zu können um besser die Probleme zu finden
debuggen habe ich noch nie gemacht. Ich schließe immer eine LCD-Anzeige an und lasse mir die Werte anzeigen.
Übrigens rechne ich etwas einfacher:
1024inc / 32V= 32inc/V
für 28V gilt
32inc/V *28V= 896inc (896>>2= 224 =0xe0)
für 22V gilt
32inc/V *22V= 704inc (704>>2= 176 =0xb0)
Hi pic18!
Ja eine LCD wäre was feines, aber auch die muss erstmal laufen :P Ist bei mir alles sehr lange her.
Wow, danke für den kürzeren rechenweg :D Darauf kam ich nicht.
Aber: Ich konnte bis morgen nicht warten, alles Nähe des Ladereglers hingesetzt (übringes, die 5V kommen von einer USB Buchse
des Ladereglers, wusste nicht das der sowas hat)
Und rein Zufällig war der Akku auch grade im Status "bereit zum heizen". Also Schalter umgelegt, Relais zieht an, Schütz zieht an, voll Dampf vorraus :D :) Und wo der Akku bei ca. 22, noch was war auch brav abgeschaltet.
Es gab nur 2 Zwischenfälle:
1. ein 18F habe ich scheinbar gegrillt (Kabelsalat unter Spannung entwirren war nicht gut)
2. das Hilfs relais kann nur als öffner dienen da beim Schließer der gesamte Ausgangsteil dann taktet. (Dachte eventuell doch mit ein grßeren Transistor das Schütz direkt zu schalten... mal sehen) Jetzt ist meine Status LED für das Schütz an, wenn das Schütz aus ist...
Morgen werde ich mir das am Tage nochmal anschauen, wenn alles gut läuft kommen Temperatursensoren, Zeit begrenzungen usw nach und nach rein.
Danke euch für die Hilfe.
Cobra
Zitat von: ^Cobra in 07.04.2025, 17:38:27 CESTJa eine LCD wäre was feines, aber auch die muss erstmal laufen
wenn es in Assembler sein muss, so hat Sprut ein Beispiel.
https://www.sprut.de/electronic/pic/programm/lcd.htm
Ich persönlich schreibe so etwas immer in C. Man könnte mal probieren, ob man in einen Assemblerprogramm einen C - Code einfügen kann. Umgekehrt habe ich es schon oft gemacht, das funktioniert. Oft schreibe ich Interrupt - Routinen oder auch Berechnungen in Assembler. Um deinen Spannungswert auszugeben hätte ich sogar eine Assembler Routine. Diese hat vier Bits nach dem Integerwert. Sie ist für den DS18B20 Temperaturfühler geschrieben.
Habe ich noch nie hingekriegt.
Selbst andersrum, also Beispielsweise mein asm Code in c zu benutzen, kriege ich nicht hin. Daher fällt mir der Wechsel so schwer 😂
Der c Compiler nimmt für asm wohl den xc8, welcher ne andere Syntax Hat. Und diese ist für mich schwer nachvollziehbar (zumindest gewesen).
Ja,die Sprut Seiten kenne ich und habe auch für LCD das schonmal genommen, aber das jetzt auch noch freifliegend dran zu basteln ohne das was abreißt o.ä. hms, das liegt Grade alles auf 3/4 8 bei den Solar Akku,Regler und dem Sicherungskasten rum.
ich habe den alten C Compiler in MBLAB-X installiert. Mit xc8 laufen meine alten Programme nicht. Ich kann ja mal ein paar Bilder von meinem Projekt heute Abend schicken.
Mach das.
Werde bei mir auch nochmal anschauen welche Compiler bei mir rumliegen.
Übrigens geht der 16f690 immer noch nicht.
Durch blinke Led kann ich zwar bestätigen das der läuft,auch taktmäßig richtig ist aber der ganze Rest... Tut jetzt nicht Not da der 18f14k22 genau so gut ist aber mich würde es interessieren was bei dem noch klemmt... Mag aber auch sein das der uC Schrott ist.
was geht denn nicht, das Einlesen des Analogwertes? Umfasst die Schleife, welche die LED blinken lässt das ganze Programm oder ist es eine eigene Schleife.
Beim 18er läuft alles? Ist das Prog. noch so wie oben, ich werde es mir mal anschauen, muss aber erst das Datenblatt vom 16er studieren.
Hi pic18!
Die Schleife fürs blinken habe ich vor dem auslesen des analog Wertes reingemacht.
Da beim 18f sich ja gar nichts am Anfang tat wollte ich wissen wie es beim 16f ist. Dieser blinkt aber an der Stelle. Auch wenn ich Kontroll Lampen an weiteren stellen mache, erkenne ich das das Programm soweit erstmal läuft. Aber die analog Spannung nicht eingelesen wird. Das Register ist laut den LEDs immer leer. Übrigens so,wie bei mein defekten 18f. Da war der Effekt übrigens auf bei an1.
Anscheind habe ich also den kompletten wanlder gekillt und nicht wie ich hoffte den Treiber für den Pin an0.
der Code ist weitestgehend gleich geblieben. Wegen dem defekten Relais ist die Ansteuerung verdreht, ansonsten löscht der Schalter das state Register .Mehr ist noch nicht hinzugekommen.
Hole aber mein Laptop Mal gleich vor.
Zitat von: pic18 in 08.04.2025, 10:38:31 CESTich habe den alten C Compiler in MBLAB-X installiert. Mit xc8 laufen meine alten Programme nicht. Ich kann ja mal ein paar Bilder von meinem Projekt heute Abend schicken.
Habe nun mal nachgeschaut:
mpasm (5.87)und (5.54)sowie XC8 (2.45) sind bei mir installiert als Compiler.
War der XC8 der "alte" oder der neue C Compiler?
Zitat von: pic18 in 08.04.2025, 11:29:59 CESTwas geht denn nicht, das Einlesen des Analogwertes? Umfasst die Schleife, welche die LED blinken lässt das ganze Programm oder ist es eine eigene Schleife.
Beim 18er läuft alles? Ist das Prog. noch so wie oben, ich werde es mir mal anschauen, muss aber erst das Datenblatt vom 16er studieren.
Moin Pic18,
ich muss es zwar noch in meine PV Testplatine mal stecken, aber auf mein ProgrammBoard tut es nun wie es soll.
Ich hatte alles kontrolliert, bis auf mein Register PV_State. Dieser hatte willkürliches zeugs drin stehen. (gesehen durch ausgabe auf Portc.)
Und nun kommts: So wie beim P18F habe ich vergessen PV_State auf 0 zu inizialisieren -.-
läuft jetzt alles richtig?
Hier die versprochenen Bilder
Moin Pic18,
ja der 16F läuft nun auch. Danke für die Hilfe.
Dein C18 Compiler taucht in meiner Liste nur bei den 18F auf. Bei den 16F kann ich den also erst garnicht Auswählen.
Könntest du mir mal ein einfach Beispiel machen wo du in z.B. C Main eine Assambler geschriebene Datei ausführst?
also z.B. für ein Lauflicht habe ich in einer Datei sowas stehen:
loop
CALL Wait250
CLRF STATUS
RLF PORTC,f
BTFSS PORTC,7
goto loop
CALL Taste
loop1
CALL Wait250
CLRF STATUS
RRF PORTC,f
BTFSS PORTC,0
goto loop1
CALL Taste
goto loop
Taste
BTFSC PORTB,4
return
goto Taste
In einer anderen Assambler Datei steht für die Warte schleifen
; 1 Sekunde warten
WaitXS
movwf WaitRSec ;in Temp2 steht wie viele Sekunden geartet werden soll
WaitS_loop
CALL Wait250
CALL Wait250
CALL Wait250
CALL Wait250
decfsz WaitRSec, F ; alle s vorbei?
goto WaitS_loop
return
;X ms warten 1-255ms einstellbar, Wert muss vohrer in W geladen sein
WaitX
movwf WaitRms
goto wai
; Warteschleife 250 ms
Wait250
movlw D'250' ; 250 ms Pause
movwf WaitRms
; Warteschleife, Anzahl der Millisekunden steht in loops
wai
movlw Cloop;.110 ; Zeitkonstante für 1ms berechnung 0,001ms/(1/(Fcyc/4)*SchleifenZyklen)
movwf WaitRus
Wai2 nop ;
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
decfsz WaitRus, F ; 1 ms vorbei?
goto Wai2 ; nein, noch nicht
decfsz WaitRms, F ; alle ms vorbei?
goto wai ; nein, noch nicht
RETLW 0 ; das Warten hat ein Ende
;**************************
END ; directive 'end of program'
Wenn ich jetzt ein neues Projekt anlege, Da den C18 Compiler nehme, mir eine C MainFile hinzufüge, ist dieser nichtmal Fehlerfrei.
cMainProjekt.PNG
Wie kriege ich es nun hin das mein C Projekt 1. überhaupt Übersetzbar ist. 2. meine Assambler Files ausgeführt werden können?
Zitat von: ^Cobra in 09.04.2025, 10:42:31 CESTDein C18 Compiler taucht in meiner Liste nur bei den 18F auf. Bei den 16F kann ich den also erst gar nicht Auswählen.
kein sein, dass dieser nur für den 18er ist.
Hier ein Beispiel:
das C- Unterprogr. void ds18b20int (void) wird über timer im Hauptmenu aufgerufen.
in der case - Verzweigung ds18b20ToutInit_LCD wird das Assemblerprogr. float4li(get0,sr_1) aufgerufen. Welches die Temperaturwerte des Fühlers für die LCD Ausgabe aufbereitet und als String_Pointer zurückliefert.
Später wird mit LCD_string(sr_1) der Temperaturwert mit Kommastellen auf die Anzeige gebracht.
Im Assemblerprogr. habe ich mit MOVFF FSR2L, POSTINC1 usw die Parameter die umgewandelt werden sollen übernommen.
sw18b20.zip
Danke für das Beispiel!
Werde ich mir heute anschauen
Hallo pic18,
habe mir dein Beispiel angeschaut.
Habe zwar deine beschriebenen Punkte gefunden, aber leider verstehe ich es dennoch nicht.
1. Ist dein Beispiel mit so viel anderes nichts sagendes vollgestopft, dass ich ehrlich gesagt null durchblick habe
2. Das Projekt ist nicht Übersetzbar, nicht mal ansatzweise da viele Dateien fehlen.
3. Ich habe gesehen das in dem ASM File die Variable extern zur Verfügung gestellt wurde. Kann aber nicht finden wo sie als Global deklariert ist.
Dein C Code Ruft irgendwann float4li(get0,sr_1) auf und fertig.
4. Nach lagem rum basteln nun die Lösung:
=> Mein Projekt ließ sich nicht Übersetzen da in meiner C Vorlage, welche von Microchip daher kommt kurz gesagt Müll drin steht.
Ich habe durch hier und da lesen mal was anderes hingeschrieben:
#pragma code
void main(void) {
}
Das konnte man zumindest übersetzen.
Dann habe ich hier nun bisschen C mäißges rein gebastelt:
void AsmLoop (void);
/** D E C L A R A T I O N S **************************************************/
#pragma code
void main(void)
{
LATB = 0x00;
TRISB = 0xFE;
while(1)
{
LATB = 1;
Delay10KTCYx(100);
LATB = 0;
Delay10KTCYx(100);
AsmLoop();
}//end while
}//end main
Die Config ,Delay Lib und die Pic Inc datei habe ich weiter oben eingebunden:
#include <stdio.h>
#include <stdlib.h>
/** I N C L U D E S **********************************************************/
#include "delays.h" // für die Warteschleife
/** Configuration ********************************************************/
#include <p18F14K22.h>
// CONFIG1H
#pragma config FOSC = IRC // Oscillator Selection bits (Internal RC oscillator)
#pragma config PLLEN = OFF // 4 X PLL Enable bit (PLL is under software control)
#pragma config PCLKEN = ON // Primary Clock Enable bit (Primary clock enabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 19 // Brown Out Reset Voltage bits (VBOR set to 1.9 V nominal)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bit (WDT is controlled by SWDTEN bit of the WDTCON register)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config HFOFST = OFF // HFINTOSC Fast Start-up bit (The system clock is held off until the HFINTOSC is stable.)
#pragma config MCLRE = OFF // MCLR Pin Enable bit (RA3 input pin enabled; MCLR disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config BBSIZ = OFF // Boot Block Size Select bit (1kW boot block size)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block not protected from table reads executed in other blocks)
Nun mein Spannenderteil:
die Funktion AsmLoop(); ist in einer anderen Datei, welche in Assambler geschrieben ist.
global AsmLoop
ASM_Code CODE ; let linker place main program
AsmLoop:
GOTO AsmLoop ; loop forever
END
Und hier springt der auch in der Sim rein und bleibt für ewig dadrin >:D .
Danke dir pic18 für die Hilfe. Auch wenn ich bei dir weder ein Prototyp noch eine extern deklaration finden konnte, so kam ich auf die Idee des Prototyps, und mit dem hat dann funktioniert. Ob ich jetzt auf C umsteige? Wohl kaum... alleine das ich hier 2 .h einbinden musste welche für mich nichts sagend sind... weiß schon nicht mehr wo ich das gelesen,gehört oder geahnt habe... Auch wenn ich mir anschaue was jetzt an Speicher schon verbraucht wurde. Klar, wenn ich mir dein Code anschaue will ich das ganze nicht in Assambler nach bilden müssen, aber meine einfachen Projekte sind bis jetzt nach machbar. Werde aber am Ball bleiben und das ein oder andere in C weiter Testen.
Gruß
Cobra
Zitat von: ^Cobra in Gestern um 14:41:01 CESTDas Projekt ist nicht Übersetzbar, nicht mal ansatzweise da viele Dateien fehlen.
Das ist richtig, da es ein sehr großes Programm ist. Es gibt sehr viele Unterprogramme die auf einander zugreifen. Außerdem habe ich viel über Interrupt gesteuert, da ich so gut wie keine Zeitschleifen benutzt habe, um eine gute Performance zu haben. Ich habe leider im Moment kein einfaches Beispiel zur Hand.
Im Assemblerprogramm gebe ich float4li bekannt
und benutze ein externes Unterprogr. LCD_Out, welches ich in C dekariert habe
global float4li
extern LCD_Out
dem C-Compiler sage ich, dass ich ein externes Programm (float4li) habe, welches 2 Pointer vom Type char hat.
sr_1[10] und get0[10] sind Pointer (Zeiger) vom Typ char mit 10 Zeichen
extern void float4li(char *get, char *erg);
char sr_1[10]; // für ASCII Anzeige ("-012.3456";)
char get0[10]; //scratchpad RAM (temp LSB, temp MSB, TH, TL, Config,rev5678, CRC)
die Parameter (Pointer) übergebe ich mit
float4li(get0,sr_1)
Im Assemblerprogramm lese ich übergebenen Daten aus.
;Stk2PushFromReg FSR2L FSR2 sichern
MOVFF FSR2L, POSTINC1
MOVFF FSR2H, POSTINC1
;Stk2CpyToReg -6,FSR2L zeiger ASCII_string nach FSR2
MOVLW 0xfa
MOVFF PLUSW1, FSR2L
MOVLW 0xfb
MOVFF PLUSW1, FSR2H
;StkCpyToReg -4,FSR0L Wert Get_imput nach FSR0
; movlb merker
; SETF merker,BANKED ;movlw 0xff
; RCALL p_to_fsr0
MOVLW 0xfc
MOVFF PLUSW1,FSR0L
MOVLW 0xfd
MOVFF PLUSW1,FSR0H
MOVFF POSTINC0,POSTINC1 ;get_lo zwischenspeichern
MOVFF POSTDEC0,INDF1; POSTINC1 ;get_hi
Das mag etwas kompliziert sein, aber dadurch kann ich direkt von C die Daten ohne eine Dauerhafte Variable zu generieren übergeben.
Zitat von: ^Cobra in Gestern um 14:41:01 CESTUnd hier springt der auch in der Sim rein und bleibt für ewig da drin
ist klar, du hast hier eine Endlosschleife AsmLoop: goto AsmLoop
Zitat von: ^Cobra in Gestern um 14:41:01 CEST2 .h einbinden musste welche für mich nichts sagend sind
Welche Header Datei meinst Du. Durch einbinden der Header Datei erklärst Du dem Compiler was Du noch alles einfügst. Dies kann Intern sein, oder auch eigenen Programmteile.
Zitat von: ^Cobra in Gestern um 14:41:01 CESTWerde aber am Ball bleiben und das ein oder andere in C weiter Testen
Bei größeren Programmen wird es schwer alles in Assembler zu schreiben. Da benötigst Du eine Hochsprache. Wenn ich nur überlege, irgendwelche Rechenoperationen durchzuführen. Einfache Sachen habe ich früher auch in Assembler geschrieben, da du oft einfache Befehle nehmen kannst. Zum Beispiel ein Bit setzen (BSF..), in C musst Du dann eine Oder -Verknüpfung nehmen und bei löschen eines Bits (BCF..) eine Und -Verknüpfung.
Zitat von: pic18 in Gestern um 22:37:03 CESTZitat von: ^Cobra in Gestern um 14:41:01 CEST2 .h einbinden musste welche für mich nichts sagend sind
Welche Header Datei meinst Du. Durch einbinden der Header Datei erklärst Du dem Compiler was Du noch alles einfügst. Dies kann Intern sein, oder auch eigenen Programmteile.
Ich meinte diese hier:
#include <stdio.h>
#include <stdlib.h>
Danke für deine Erklärung. Verzeih mir noch eine Frage: wo ist die Schnittstelle zwischen dein in c vergebenen pointern und im assamblercode? Die Bezeichnung finde ich zumindest nicht wieder
<stdio.h>
<stdlib.h>
Das sind fertige Bibliotheken vom C-Compiler, erkennst Du am "< >"
wahrscheinlich werden diese bei Deinem kurzen Prog. nicht benötigt.
Die Datei
stdio.h enthält diverse
Stan
dard-
Input-
Output-Funktionen (daher der Name)
https://www.proggen.org/doku.php?id=c:lib:stdio:start
stdlib Standard Library
https://www.proggen.org/doku.php?id=c:lib:stdlib:start
Zitat von: ^Cobra in Gestern um 23:02:39 CESTwo ist die Schnittstelle zwischen dein in c vergebenen pointern und im assamblercode
float4li(get0,sr_1)
damit rufe ich das Assemblerprog. auf und übergebe die zwei Pointer, wobei der zweite die Rück-Antwort ist.
Der C-Compiler schiebt die Adressen in das File Select Register (FSR), dieses lese ich im Assemblerprog. aus.
Man kann dies auch anders machen, in dem ein Assemblerprogr. ohne Parameter aufruft, und die Parameter im Assemblerprog. als extern definiert. Dann muss natürlich auch float4li auch ohne Parameter definiert werden.
void float4li(void)