PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer1 als Gesamtlaufzeit-Zähler möglich?



PsiQ
30.05.2013, 16:29
Mahlzeit!
Kurze Frage. Bei den Pic16Fxxx gibt es ja den Timer0 (0..255+1) und den Timer1 (65535 +1).
Kann ich den Timer 1 somit als Laufzeitspeicher verwenden?

Ich benötige für eine Stoppuhr mit 10mS Schritten eine Zeit die "im Hintergrund" immer weiterläuft,
Bei einem Stoppsignal soll der aktuelle Zeitwert seit "Start" auf dem LCD dargestellt werden.
Beim nächten Stoppsignal wieder die GESAMTzeit seit dem "Start" (nicht die Zeit seit dem letzten Stopp).

Daher die Frage ob ich den Timer1 als Gesamt-Laufzeit-Zähler nutzen kann.
Die benötigte GesamtMess-Zeit liegt dabei unter 1h, eigentlich sogar unter 100 Sekunden,
ich brauche aber eine Auflösung von 10mS Schritten, also 00,01 Sekunden.

Ob der Timer1 dann ab "Startsignal" läuft oder ab "Reset" ist ja egal, da eh nach Ende jeder Messung einmal Reset erfolgt.

Danke!

(PS.: Bin auf diese Idee gekommen weil ich beim Arduione gelesen habe, das dieser einen Laufzeit-seit-Start Timer hat.
Da dieser immer im Hintergrund mitläuft und wohl bis zu 30 Tage messen kann, kann man über diesen den Start/Ersten
und Stop/zweiten Wert vergleichen und damit die Differenz = vergangene Zeit ermitteln)

oberallgeier
30.05.2013, 16:40
Hallo Jürgen


... Bei den Pic16Fxxx gibt es ... und den Timer1 (65535 +1). Kann ich den Timer 1 somit als Laufzeitspeicher verwenden ...Ohne dass ich jemals mit nem Pic Erfahrungen machte, behaupte ich : ja. Bei meinem Atmels habe ich praktisch immer einen interruptgetriebenen Heartbeat (im Prinzip egal welcher Timer), der mit 20kHz eine kurze ISR aufruft. Darin wird eine 16bittige Variable von 19 999 runtergezählt - dann wieder von oben anfangen. Beim Nulldurchgang wird eine weitere 16bittige Variable "Isecundn" hochgezählt. Als unsigned Variable (eine Laufzeit kann nie negativ werden) komme ich also auf über 18 Stunden Laufdauer bis zum Überlauf. WENN Dir das nicht reicht, dann kannst Du natürlich nen Stundencounter (if (Isecundn == 3600)...) einbauen und wochenlang die Zeit messen.

RoboHolIC
30.05.2013, 23:34
@Jürgen
Wenn die Stoppuhrfunktion die Kernaufgabe des Controllers ist, kannst du den Timer 1 als Speicher dafür verwenden. Die Zeitbasis von 10ms schreit aber eigentlich danach, das von oberallgeier beschriebene Verfahren anzuwenden; andernfalls ist man doch sehr beschränkt in der HW-seitigen Konfigurierbarkeit (Prescaler-Einstellungen) des Zähltaktes und der Zeit bis zum Überlauf von Timer1. In Software kaskadiert man zwei, drei, vier, ... Bytes und gut is. Die Ausführungszeit dafür ist bei einem 10ms-Interrupt nicht der Rede wert.

PsiQ
31.05.2013, 19:06
Nachdem ich jetzt nach einem Tag rumgefluche meinen Programmierer wieder hinbekommen habe,
werde ich jetzt endlich meine Platine zusammenbraten.

Also LCD ran, 3 Taster (Start, Stop, Reset), 4096mhz Quarz, und mal ein fertiges Programm von Sprut draufbrennen.

Dann stimmt zwar der Timer/Zähler überhaupt nicht, aber wenn das dann irgendwas tut,
werde ich nach und nach versuchen das von 1Sekunden auf 10mS Schritte passend zu modden..
und wenn das ging dann das
Reset; Start=>LCD Uhr läuft mit , Stop=>Zeit1 auf LCD steht , Stop=Zeit2 auf LCD , Stop=Zeit3 auf LCD steht.
irgendwie hinbiegen. ... ... ...Hoffentlich!

Im Sprut Beispiel wird der Timer 0 verwendet, der nach 255+1 überläuft, um den Zeitgeber mit 32khz quarz in Sekundenschritten zu machen/weiterzuzählen.*
Ich dachte an eine Kombination aus Timer 1 mit Vorteiler:4 und Timer 0 als Überlauf-Mitzähler. Wären dann 65535 x4(Teiler) x 255 Werte die im Hintergrund mitlaufen können.

Haarig wirds dann für mich mehrere Zeiten zu speichern/auszugeben.


*@RoboHolic: Ich denke das ist das was du mit kaskadieren meinst. Sprut zählt die EinerSekunden bis 9, bei 10 erfolgt der reset und der übertrag um 1 auf das nächste bit (ZehnerSekunden),
und dort dann bei 5+1 der übertrag von 60sekunden = 1 Minute .. dann 60min = 1h .. bis 23:59+1 => 00:00:00

Ich habe nur Sorge, dass ich nachher fürs LCD ausgeben/beschreiben und den Rest drumrum nicht genug Zeit habe um die 10mS genau genug zu halten/messen.
Wenn ich das im timer 1 "laufenlassen" könnte und nur kurz den wert auslese und damit von mS auf [ss]:[mS][mS] rechnen kann reicht mir das.
Brauche gar keine Minuten, es würde auch 999Sekunden,[mS][mS] reichen, was ja bei einem 10mS Grundzähler

Eine einfache Division oder sogar eine direkte darstellung möglich macht...
30.025 in Timer 0 wären dann 30.025x10mS = 300.250mS also 300,250 Sekunden.
Darstellbar aufm LCD als 300[Sek]:250[mSek].

(wobei die letzte 1mS Stelle egal ist.)

.. Genug geredet, los gehts an den Lötkolben!

RoboHolIC
31.05.2013, 23:47
Ein 4096MHz-Quarz ist schon mal sehr komfortabel, weil damit das Timer-Preload-Verfahren zur Einstellung der Zykluszeit wegfällt (siehe die Errata sheets zum Timer0-Fehler).
Willst du ebenfalls diesen 32.768kHz-Quarz verwenden? Der Sinn des vor Dir erwähnten Sprut'schen Konstrukts ist mir nicht klar.
Willst du Timer 0 selbst inkrementieren, wenn Timer 1 überläuft? Das macht nicht viel Sinn und der Chip gibt dergleichen auch nicht her. Dazu verwendet man sinnvollerweise die in ausreichender Zahl vorhandenen Speicherbytes des SRAM.
Die Idee, gleich alle Ziffern für die Anzeige passend durch einzelne Zähler(überläufe) zu implementieren ist recht gut; benötigt zwar in der ISR etwas mehr Zeit, spart dafür aber die aufwendige nachträgliche Zerlegung. Das ist das eine. Das andere ist die Differenzbildung in der ziffernorientierten Darstellung, das klingt für mich ohne Hardwareunterstützung für BCD-Arithmetik etwas heikel.

Das mit dem Kaskadieren hatte ich allerdings anders gemeint: Nämlich bei jedem Timerinterrupt das inkrementieren des niederwertigsten Bytes und bei auftreten des carry-Flags inkrementieren des nächst-höherwertigen Zählerbytes und bei auftreten des carry ........ Das ist deine binäre Uhr. Die Differenzbildung über mehrere Bytes (ich vermute mal Assembler) kann man sich aus dem Netz holen oder selbst ausdenken. Es gibt auch Application Notes für die PIC16-Familie, da wird so etwas beschrieben. (In C wäre das ja kein Thema).
Der Vorgang des Zeitnehmens ist schlicht das Anfertigen von Kopien aller Zähler-Bytes.

Die Ausgabe aufs LCD ist wirklich Aufgabe des Hauptprogramms, allein die Übergabe der Datenhappen an das LC-Modul sollte man entweder der ISR selbst aufbürden oder durch ein von der ISR gesetztes "Neue-Zeitscheibe"-Flag synchronisieren.

Das alles genau zu beschreiben fällt mir allerdings schwer. Es ist schon wichtig, dass du eine klare Vorstellung von solchen zeitgesteuerten Mechanismen zwischen Hauptprogramm und ISR entwickelst. Da scheint auch jeder seine eigene Vorliebe zu entwickeln, wie er das genau umsetzt.

PsiQ
01.06.2013, 15:55
Ich habe den 4096er Quarz bestellt weil Sprut in seinen Beispielen explizit sagt,
dass mit dem 32khz uhrenquarz eine 100mS oder 10mS Uhr nicht möglich ist, da mit seiner vorgehensweise der kleinste passende Teiler eben der 1 Sekunden Schritt ist.
Habe mich da in die 3 Programmbeispiele die er hat versucht etwas einzulesen:
Zitat Sprut bei 32khz LCd Uhr:

Weiterführende Gedanken
Kann man auf dieser Basis auch eine Stoppuhr mit 1/10 und 1/100 Sekunden-Anzeige bauen???
Nein! es gibt keine Möglichkeit, aus einem 32768-Hz-Takt durch Teilung ein 10Hz oder 100Hz-Signal abzuleiten. Folglich müssen Stoppuhren mit ganz anderen Quarzen bestückt sein.


Und bei 4.096 : 4 : 256 wäre man bei => 4000 überläufen pro Sekunde .. wenn ich die dann
durch 4 (Vorteiler) Teile habe ich beim Originalprogramm von Sprut eine um 1000fach höhrere Messzeit, also 1mS statt 1s.

gegenüber
32768 : 4 : 256 => 32 Überläufe pro Sekunde .. die teilt Sprut dann durch 32 (Vorteiler) und hat seinen Überlauf im Sekundentakt.


"Theroetisch", muss ich im Originalprogramm also nur die Pausenzeiten/Loops anpassen um den Faktor 1000x und die LCD Wartezeiten an mein großes LCD anpassen,
dann läuft die Uhr schon mit mS. Ist aber halt noch keine Stoppuhr.

--------------
Sprut speichert die Zahlenwerte direkt in die auszugebenden Zeichen (ES ist ein vorher definiertes Speicher Bit), soweit ich das richtig sehe,
wobei er dann eben gleich die entsprechenden Überläufe zur nächsten Stelle mit macht, z.B: bei 59+1sek = 1min. ( siehe code bei clrfs ES)
So sieht das Unterprogramm dafür aus, das für jeden Sekundenüberlauf/Interrupt abgearbeitet wird.


Int_1
bsf neu

incf ES, f ; 1 Sekunden erhöhen
movlw D'10'
subwf ES, w
btfss STATUS, Z
goto Int_end ; 1 Sekunden <> 10

clrf ES
incf ZS, f ; 10 Sekunden erhöhen
movlw D'6'
subwf ZS, w
btfss STATUS, Z
goto Int_end ; 10 Sekunden <> 6

clrf ZS
incf EM, f ; 1 Minuten erhöhen
movlw D'10'
subwf EM, w
btfss STATUS, Z
goto Int_end ; 1 Minuten <> 10

clrf EM
incf ZM, f ; 10 Minuten erhöhen
movlw D'6'
subwf ZM, w
btfss STATUS, Z
goto Int_end ; 10 Minuten <> 6

clrf ZM
incf EH, f ; 1 Stunden erhöhen
movlw D'10'
subwf EH, w
btfss STATUS, Z
goto Test24 ; 1 Stunden <> 10

clrf EH
incf ZH, f ; 10 Stunden erhöhen
goto Int_end


Da Sprut nur eine Uhr und keine Stoppzeiten benötigt, zeigt er diese Stellen [ZM][EM]:[ZS][ES] direkt auf dem LCD an.

Vom Prinzip her würde es also reichen im Fall von "STOPP" Werte der laufenden Uhr zu kopieren und anzuzeigen.
Beim 2 zeiligen Display wäre es also möglich in der 1. Zeile immer die laufende Uhr zu zeigen
und in der 2. Zeile die im Moment vom letzten "Stopp" rauskopierten Werte.
Ich weiß nur nicht ob das schnell genug geht (unter 10mS) dass ich nicht beim Auslesen von hinten nach vorne
einen Überlauf ins nächsthöhere Bit verpasse und quasi noch paar mS weiterzähle.

Daher der Gedanke "nach" dem 255+1 Timer den 65535er Timer1 zu verwenden (zu beschreiben) und in diesem die verstrichene Gesamtzeit zu zählen,
damit ich nur diesen einzelnen Wert auslesen und anschließend "umrechnen" muss,
und nicht alle 5 Stellen einzeln kopieren.


Ich versuche mal meinen Gedanken weiterzuführen/zu erläutern:
Ich lasse den Timer0 255+1 mit den Teilern 4096/4 :4 laufen.
Ich habe also 1000 überläufe pro sekunde.

Das schreib ich in ein Byte, was jeweils nach 9+1 überläuft.
Ich komme also von 1mS Schritt damit auf 10mS. (Dieser Zwischenwert interssiert mich nicht wirklich beim auslesen,
da mich der 1mS Stand nicht interessiert. Falls genug Luft bleibt kann ich den ja aber immer noch auslesen)

Diesen 9+1mS Überlauf zähle ich dannn in Timer1 mit.
Timer 1 kann dann 65535 x 10mS zählen (=655350mS), also eine Gesamtzeit von 655 Sekunden
- was über 10 Minuten sind und völlig ausreichend.

Im Fall von "Stopp" lese ich dann den Wert von Timer1 zu diesem Zeitpunkt aus,
und kann den gespeicherten Wert dann "ganz in Ruhe" langsam auf dem LCD darstellen,
was dann auch länger dauern darf, da der Timer ja im Hintergund mit seiner Interruptroutine ungestört weiterläuft.

Die vermeintlichen Grundlagen dazu hab ich da gelesen:
http://www.sprut.de/electronic/pic/grund/timer/timer.htm#timer0


Mit ISR, meinst du die "Interrupt gesteuerte Routine", also das zeitkritische Programm was
das LCD-Anzeige/UmrechenHauptprogramm unterbricht und danach wieder zurückspringt, korrekt ?


...
Nunja. Soviel zu dem wie ich mir das theoretisch überlegt habe. Leider fehlen mir noch die Fachbegriffe und Zuordnungen, wie was wo..

Aber erstmal muss ich meine Platine zum Laufen bekommen, die zeigt nämlich nur 2 schwarze Balken aufm LCD und tut sonst nichts.
Ich habe das 10Mhz Programm mit dem 4096er Quarz verwenden wollen zum Testen meiner Platine, das läuft halt dann nur auf 40% Speed.
=> http://www.sprut.de/electronic/pic/programm/lcduhr/lcduhr.html

Leider tut sich nichts. Werde die Schaltung nochmal prüfen, wobei ich einen Fehler beim Compilieren vor dem Brennen vermute, da muss ich mal etwas rumspielen
und werde dann die Fehlercodes posten wenns unter 10 geworden sind ;-)
Mit dem fertigen *.hex und der passend Konfig (high voltage aktiv) beim Brennen hats leider auch nicht geklappt.

PsiQ
02.06.2013, 00:08
Alsooooo. Irgendwie ist da der Wurm drin.

Ich habe jetzt alternativ das simple LCD-Testprogramm von Sprut mal draufgemacht, das läuft original mit 4mhz, die 4096mhz sollten also egal sein.
Da krieg ich aufs ganze LCD (20x4) nur ne graue Fläche, keine Pixel o.ä. sichtbar.

Meine 5V Spannung war anscheinend zu schwach gepuffert, da hatte ich nur 4,6V , jetzt vorne und hinten 100µF an den Regler und die 4,95V sind da.
Den Kontrastpin am LCD habe ich auch son hingedreht mitm Trimmer,
dass ich gut was sehe, dazu das LCD mit 13mA Strom (5V mit 100Ohm Vorwiderstand bei 3,6V LED Spannung)etwas beleuchtet.

Nun zum komischen Teil.
Ich hatte ja zu anfangs schon diese 2 schwarzen Balken.
Wenn ich HS Oszillator eingestellt hatte kam erstmal nix, jetzt mit XT "Crsytal" kam was.
Laut Sprut ist bei um 4Mhz aber egal ob XT oder HS. (ausser Strom)

Jetzt mit XT, "low volt disabled",
Kommt manchmal nach
"Spannung weg, Spannung Ran" reset

Ein blinkender Cursor.. der saut dann einmal nach rechts, dann kommt ein "?" was stehenbleibt.
Was ich auch schon hatte war ein rasendes "?" über die beiden aktiven Zeilen ... :confused:

MCLR bzw reset pin ist aktiv, ich sehe aber keine Auswirkung am LCD.
Muss mir irgendwie noch ne blinkende LED an einen freien port setzen, als Programm-läuft-Rückmeldung.

Kann es sein, dass mein Quarz nicht ins Schwingen kommt?
Ich hab da die gleichen kerkos dran wie ich für die 10Mhz quarze vor Jahren mitgekauft hatte
-Kann ich (und wie) die Schaltung mit dem internen Schwinger testen,
oder raucht dann was ab wenn der externe quarz auch noch dran ist?
... Sonst muss ich da halt mit EntLötlitze ran.

Ich werde jetzt noch versuchen das asm selber zu compilieren,
da kamen bisher über 83 Fehler daher habe ich das fertige hex genommen und nur die Konfiguration geändert.

Achja: Ich benutze einen PiC16F628A , der wohl auch tut, im Brenner erkannt wird und auch die Demoprogramme
von Vellemann astrein macht. Das geschribene Hex habe ich auch nachm schreiben überprüft udn es gab keine Fehler/Abweichungen...

ToDo/Memo an mich selbst für morgen:
1. ASM compilieren, ohne Fehlermeldung hinbekommen
2. ASM modifizieren, die Wartezeiten und loops um 50% verringern, anpassung von 10mhz auf 4mhz,
und weil ein anderer Display controller drin steckt nach der Abfrage "Display Ready Pin" noch ne 10mS Pause einbauen.

RoboHolIC
02.06.2013, 00:32
Ich sehe, dass du Assembler machst und Sprut zitierst. Arbeitest du mit High Voltage Programming? (Sprut propagiert und begründet das ja deutlich).
Hast du das LowVoltage Programming Enable Bit in den CONFIGs disabled? Es gibt kein HV-Prog.-Enable, das geht immer. Nur der Pin RB3 kann dann noch stören. Ist der per Widerstand auf GND gezogen? Das kann viel Ärger ersparen.

Das 16-Bit-Register des Timer1 nützt dir kaum was. Auslesen und Verarbeiten kannst du ihn nur byteweise; die Inkrementierung auf 16-Bit-Ebene in Software??? - das wüsste ich grad nicht, wie das gehen soll.

ISR steht für "Interrupt Service Routine", ansonsten aber richtig.

Hast du eine Diagnose-LED am Controller dran? Dann mach dich vielleicht erstmal dran, bezüglich Chipprogrammierung auf festen Boden zu kommen. Danach vielleicht einen 1ms- oder 10ms-Interrupt einrichten. Eine blinkende LED. Eine Delayfunktion in der ISR für das Hauptprogramm. Die Datenübergabe an das Display ...

Bei Fosz = 4,096MHz bzw. Fcycl = 1MHz und 1ms-Interrupt hast du im Extremfall fast 1000 Befehle für die ISR zur Verfügung. Da passt sooo viel rein: (natürlich würde dann das Hauptprogramm nicht mehr "laufen", nur noch "kriechen", aber das ist ein anderes Thema)
Taster- bzw. Lichtschranken-Signalentprellung, die Uhrenkaskade, Kopieren der Bytes bei erkanntem Zeitnahme-Trigger, die LCD-Bedienung, und und und... die meisten Sachen sind ja mit wenigen Befehlen abgehandelt.

Vielleicht magst du ja schon vorher die Fehlercodes zeigen, damit du schneller < 10 kommst?

PsiQ
02.06.2013, 19:22
Assembler, Sprut, Programmieren:
Also brennen tu ich den IC in meinem Velleman 8048.
Da habe ich bei der config auch den haken für low volt rausgenommen.
und jetzt mal noch mit XT oder HS setting getestet.
Der Vergleich zwischen Hexfile und im IC hat auch keinen Fehler ergeben,
das Programmieren vom hex klappt also zumindest.

Danach heissts rausfummeln und den IC umstecken auf die LCD / Stoppuhr Platine.
Den RB3 kann ich da aber nicht auf GND legen, da darüber original die LCD ansteuerung erfolgt,
das Programmieren klappt ja aber auch.
=> Der PIC funktioniert auch, da er mit dem Demo2 auf dem Velleman auch funktioniert. Ist ne demo mit lauflichtern, blinkelicht und wechselblinker, mit tasten zum anwählen.

------------------------------------------------------

Ich vermute grade noch einen Fehler im Quarz/Einschwingen, da ich manchmal ein blinkende cursor und ein "?" bekomme was über den LCD sausst,
und manchmal nichts ausser schwarzen Balken. Bei 3 mal aus-ein-schalten läuft einmal was übers LCD nach paar sekunden.

Ich hab mir jetzt nen sockel fürs quarz gebaut, wie fürn ic aber nur 3 pins. Der in der mitte ist offen. Da habe ich testweise abwechselnd einen 10mhz und den 4.096er quarz rein.
aussen sind noch die kerkos die ich aus der krabbelkiste bei den 10mhz quarzen habe, die tausche ich jetzt gegen welche wo ich sicher weiß, dass die 33pF haben.

Ich hab jetzt noch nen quarzoszillator mit 16mhz gefunden, mit dem ich das ding zwangsbeatmen könnte.

Ach genau. Und vor dem Umbau am Quarz habe ich an VDD-VSS auf der Unterseite nen 100nF Folienkondensator rangemacht.
Den hat sprut in der schaltung vergessen / vergessen zu erwähnen, jetzt kommt immerhin manchmal das fragezeichen.

Am Spannungsregler sind nun davor/dahinter jeweils [100µF]+[470nF], am IC direkt nochmal 100nF.

Ich tausche jetzt die quarzkondensatoren und löte das nochmal neu und exakt symmetrisch.

- - - Aktualisiert - - -

Also ich habe jetzt die 33pF Kondensatoren dran die ich mal mit nem 16mhz quarz bestellt hatte.
Sprut hat im Beispiel 30pF.
Mit dem 10Mhz quarz kein wirkliches Ergebnis ausser schwarze Balken,
mit dem 4.096er bekomme ich am LCD das hier: (von links oben, erste reihe, dann 2. reihe, rasende fragezeichen,
dann schwarze balken. Keine Reaktion auf MCLR pin nach GND. Schaltung wie bei Sprutbeispiel.

http://s22.postimg.org/86u27bx7l/lcd_anzeige.jpg (http://postimage.org/)

- - - Aktualisiert - - -

Soo. Also das Assemblerdingens lief jetzt fehlerfrei durch. die 80+ Fehler waren darin begründet, dass die p16f628a.inc nicht in selben ordner lag.
Damit hat der assembler jetzt ohne fehlermeldung das *.asm von sprut in ein hex gemacht.

im *.asm habe ich davor entsprechend den p=16f628a und inc=16f628a korrigiert.

Kein Fehler beim compilieren, kein Fehler beim Brennen, und Vergleich code mit Chipcode ergab auch keinen Fehler.
also wieder rüber gesteckt, und immer noch nichts. bzw immernoch das ? und cursorblinken wenn ich paarmal resette mit ein/aus.

Ich hab mir jetzt mal die LCD init von sprut angeschaut, und im datenblatt von meinem gekuckt.
dabei ist mir beim init eine Abweichung aufgefallen.
der aufbau ist doch (sprut code)
ganz rechts RB0
ganz links RB7

sprut initialisiert den 4-bit mit

movlw B'00101000' ; 5 function set, 4-bit 2-zeilig, 5x7

Er macht also RB3 und RB5 high... wenn ich das im datenblatt bei mir richtig sehe, müsste das aber für meins
00001000 sein, oder ? (Datenblatt siehe Bild)
was mich verwirrt ist dass da zwei zeilen stehen, also
darunter nochmal
10000000
kommen müsste, oder ist das egal?
- Bei function set stehen 2 Zeilen, aber nur eine Auswirkung..

(Ich hab mal noch die anderen teile rot / grün markiert die wohl passen.)

Beim Display off schreibt Sprut
00001000
aber bei meinem müsste das wohl
00000000 sein, und für on
11110000
oder ?

(RB7 = D7 ; RB6 = D6; RB5 = D5; RB4 = D4; RB3 = R/W; RB2 = RS; RB1 = MCRL-Taster; RB0= Enable LCD )

Edit: Cursor home stimmt entgegen bild / grünem haken wohl auch nicht.

http://s23.postimg.org/l1ts5cvl7/LCD_init.jpg (http://postimg.org/image/65v8xrk6f/full/)

PsiQ
03.06.2013, 18:24
So. Also. Etwas funktioniert, endlich!
Und zwar:
-Das Sprut LCD Miniprogramm was Hallo sagt
-Die Sprut 10Mhz LCD Uhr, aber halt arschlahm weil 4MHZ Quarz.

Und wo läufts:
- Auf dem Velleman 8048!

Mir hat das rumgesuche an meiner Schaltung gereicht. Also habe ich ein 16x2 LCD was ich an einer anderen Schaltung hatte
(wo ich nur hardware gebaut habe, keine Software gemacht, also keine ahnung vom IC-Inhalt) abgemacht und an das velleman 8048 ran.
Habe dazu noch zwei Löchlein in die Platine gebohrt um alle RB0 - RB7 Pins anzapfen zu können, da musste ich nämlich noch zwei Leitungen an RB6 und RB7 dazulegen.

Habe jetzt quasi das Velleman auf das Sprut Standardlayout geändert, Das LCD nach Sprutstandard ran, und das 16x2 (Displaytech 162)
funktioniert jetzt tatsächlich. Den Reset Button habe ich auch an RB1 ergänzt. Das Beispiel "LCD Uhr 10Mhz" läuft jetzt also schonmal, mit LCD, mit Reset.
Ich lasse jetzt erstmal das 4Mhz Quarz im Velleman, ob nun 4.096 oder 4.000 ist ja fürs Programm erstmal egal.

Werde mich jetzt also dran machen, aus dem "32khz Uhr" und dem "10Mhz Uhr" Beispielen eine Uhr für 4.096Mhz mit 10mS Schritten zu machen.

Velleman verwendet am 4Mhz Quarz 18P Kondensatoren, das ist natrülich weit von den 30pF weg die ich hatte.
Allerdings sitzt der Quarz auch ziemlich weit weg vom IC, da der für alle 4 Sockel zuständig ist.

Bildsche: (Der Reset Taster fehlt da noch)
http://s9.postimg.org/y69vjsv7z/lcd_16x2.jpg (http://postimage.org/)

- Mann bin ich froh darüber, ausserdem muss ich so den PIC nicht mehr ständig aus dem Sockel reißen..

RoboHolIC
03.06.2013, 23:03
Hi, PsiQ.

Glückwunsch zum Durchbruch!

Ich hab jetzt allerdings nicht alles gedanklich nachvollzogen.
Die zwei Zeilen je Befehl rühren daher, dass in 4Bit-Mode ebenfalls 8 Bit übertragen werden müssen für einen kompletten Befehl, nur eben in zwei 4Bit-Häppchen zerteilt, die nacheinander in das LC-Modul reingetickert werden müssen. Vielleicht klärt das schon die Fragen. Vielleicht sind Spruts Kommentare nicht ganz deckungsgleich mit der letztendlichen Funktionalität.
Kläre mal den Controllertyp den Displays ab und besorge dir genau dieses Datenblatt. Das ist -unabhängig vom individuellen Displayprodukt- die Referenz für diese Fragen. ( Spezieller wird es aber, wenn es um die Adressierung der Anzeigepositionen geht: Die ist tatsächlich modellabhängig, da hilft auch kein DB eines ähnlichen Displays !) Nach deinem Erfolg durch Displaywechsel kann man wohl nur konstatieren, dass das erste Display nicht ganz HD44780 (oder wie der heißt)-kompatibel ist. Ich hatte schon mal den Fall, dass am LCD-Board "lediglich" die Anschlüsse von +5V und GND sowie die Pin-Numerierung gegenüber dem Standard vertauscht waren ... :( ...ein nettes Verwirrspiel. Prüfe vielleicht auch das beim ursprünglichen Display.


ob nun 4.096 oder 4.000 ist ja fürs Programm erstmal egal aber am Schluss nicht vergessen, gell!

Leicht OT:
Noch ein Vorschlag zum leichteren IC-Wechsel, sofern zukünftig mal wieder erforderlich:
(die Idee stammt nicht von mir!)
Den Chip in einen Sockel mit Präzisionskontakten einsetzen und dann stets in diesem Verbund zwischen den Standardssockeln hin und her wechseln. Im Havariefall kann dann der Transportsockel erneuert werden und der Chip wird geschont.

Jetzt endgültig OT:
Der Königsweg ist aber ein In-Circuit-Programmiersystem (ICSP); da kann der Chip in der Zielhardware verbleiben und dort programmiert werden. Je nach Geschmack wird das evtl. noch von der Variante mit Bootloader getoppt, die ich aber noch nicht ausprobiert habe. ICSP möchte ich nicht mehr missen. /OT

PsiQ
04.06.2013, 13:24
IC-Sockel / ICSP:
Auf dem Bild sieht mans leider nicht so genau,
aber die PIC hab ich genau in sonem Sockel stecken um se zu schützen,
sonst sind die nach paar mal hin und herstecken ihre Beinchen durch Bruch los.
Hab keinen Nullkraftsockel da, und das mit dem ICSP machts Layout nochmal komplexer. (Das Velleman hat aber auch n ICSP Port)
Da ich jetzt aber aufm Programmierboard entwickeln kann ist das ja erstmal egal.
--Einen PIC hab ich mit Überspannung gekillt, weil der erste verlötete Regler bei Last dann nicht mehr richtig garbeitet hat
und plötzlich mal 10V anlagen. 2x Pic16F628A hab ich nun noch :-)

Und wenn die Software läuft, muss ich halt die Hardware einmal lauffähig hinbekommen, die kann ich ja nun gegenchecken.

Thema LCD:
Ich hatte dieses 16x2 auch kurz an "meiner" Platine dran, wo es auch nicht mehr als eine schwarze Zeile produziert hat.
Beim 4x20 habe ich jetzt (glaubich) bei der Initialisierung ein paar Unterschiede gesehen, aber das kommt dann erst später.

Ich vermute ein Problem mit dem Quarz/Takt, da die Schaltung sonst an für sich ja recht simpel ist.
Ich muss mal schauen ob mein altes tragbares Oszi (ca 1988 ) soviel Mhz messen/anzeigen kann.
Auf dem Sondenstecker steht zwar "40Mhz / 10:1", aber obs die Elektronik auch kann muss sich zeigen.

Programm:
Ich habe gestern noch stundenlang im Programm gefuhrwerkt und das um EMS ZMS und HMS ergänzt( 1 mS, 10mS, 100mS,)
sowie die Wait Routinen und die Vorteiler von 32khz auf die 4Mhz angepasst.
Leider war am Ende dann zwar ein fehlerfreies Compilieren möglich,
aber die Uhr machte keinen Mucks mehr auf dem Display, nur noch 00:00:00.

Irgendwann starrt man nur noch auf den Schirm und wenn man ne Minute was anderes macht,
hat man keine Ahnung mehr was man eigentlich grade da gemacht hat :confused:...


PS.: Danke für die Betreuung !

RoboHolIC
04.06.2013, 18:23
Hi, Jürgen.


PS.: Danke für die Betreuung !

Bitte entschuldige die Überbetreuung. Ich hatte deinen Beiträge-Zähler nicht im Blick.
Bei Vellemann-Benutzern springt immer mein "ich-will-doch-nur-dein-Bestes"-Syndrom an. Ich glaub, ich hab da ein Vorurteil:-b

Gruß
Christian.

PsiQ
06.06.2013, 02:55
Also das war von mir ernst gemeint mit dem "Danke für die Betreuung", da war 0,0% Ironie dabei :-)

Das Velleman macht ja nun was ich will, auch wenns n Mist war
und immernoch ist mit dem RS232 gelumpe dabei.

Ich kaue jetzt heute (also seit gestern da nun 02:30 ist) schonwieder seit 6 Stunden am Assembler Code rum,
und habe jetzt Schrittweise das 10Mhz Beispiel auf meine 4.096Mhz umgemodelt (wohl eher massakriert).
Es läuft etwas zu langsam, weil der Quarz ja nur 4.000Mhz hat (hoffentlich mit .000 ohne Abweichung ;-) )

Ich hab es auch hinbekommen, dass ich den Timer laufen lasse und im "Stopp" Moment
die ZeitWerte alle kopiere.

Beispiel: Im Programm schreibt der laufende Timer seinen Wert in EM, also in die EinerMinute,
und stellt diesen EM dann auf dem LCD dar in Zeile 1.

Im Moment von "Stopp" schnappe ich mir den Wert, und kopiere ihn von "EM" nach "work",
und von da dann weiter nach "A_EM".
"A_EM" ist "Anzeige_Einer_Minuten".

Die Hauptuhr läuft fröhlich über den Interrupt weiter,
A_EM steht auf dem zuletzt kopierten Wert beim Tastendruck

Das funktioniert auch, ich habe den Wert einfach nach einem "_" als Leerstelle auf dem LCD dahinter(hinter dem Haupttimer) anzeigen können.

Allerdings verstehe ich nicht wie ich im assemblercode in die 2. Zeile des LCD springen kann um dort weiterzuschreiben.

In Spruts LCD Beispielen schreibt er auf seinem 16x2 LCD immer nur in Zeile 1 von ganz vorne.

Ich sehe zwar noch das "Cursor Home", also wohl "Zeile 1, erste Stelle",
finde (verstehe) aber im Datenblatt nicht wie ich den Cursor dann in
"Zeile 2, 1.Stelle" schicke um dort weiterzuschreiben.

-- Einfach 5 Leerstellen schreiben um damit in Zeile 2 zu landen hat leider nicht funktioniert :rolleyes: --

Zur Veranschaulichung: so siehts grade aus:
00:00:00:00_ _ _ _ _ => Haupttimer, HH:MM:SS:[ms][ms]
_ _ _ _ _ _ _ _ _ _ _ => hier soll "letzte Stoppzeit" rein


Ansonsten bin ich grade recht erfreut wie "einfach" ich das bis auf die Anzeige heute mit
etwas "copy paste" und nachgrübeln hinbekommen habe.

Fehlt nur noch das in die 2. Zeile schreiben..
Und da dort vermutlich das mit dem 16x1 LCD zu 16x2 LCD mit drin steckt,
klappts evtl sogar mit dem 20x4 hinterher.

Ich schreib grad übrigens immer noch alles in Notepad um,
war beim Fehlersuchen vom Compiler etwas blöd weil Notepad
keine Zeilen-nummerierung anzeigt ;-) .
Muss mal schauen ob das "Notepad+" nicht konnte.


Zusammenfassung:
Wie springe ich zu "Zeile 2, 1 Stelle"
Erweiterung:
Wie Springe ich zu "Zeile 3" und "Zeile 4" beim großen LCD...

Das Datenblatt zu meinem 16x2 ist da bei reichelt.de bei "Datenblätter & Downloads" zu finden:
http://www.reichelt.de/Hintergrund-gruen/LCD-162C-LED/3//index.html?ACTION=3&GROUPID=3005&ARTICLE=31653&SHOW=1&START=0&OFFSET=500&

"Cursor Home" nutzt mir ja nichts,
aber steht das evtl im Datenblatt auf S.8 (unten) bei "Display Data Ram Address Map" -?-
Oder ist das hinter "Display shift" versteckt ? .. Oder wo sonst?


-- Danke soweit mal! --




@-it nach Mittagessen heute:
Also im Datenblatt finde ich auf Seite "P.8 of 17"
unten die Display Data Ram Adress Map, da steht was von First Line / Second Line
wobei letztere bei 40H liegt. => Das wäre DD RAM adress

Im Datenblatt steht ausserdem noch auf "S.5 of 17" eine Tabelle mit Steuerkommandos,
bei "Set CG RAM ADDRESS"
steht dabei "CG RAM ADDRESS (corresponds to cursor adress)"

wenn nun "cursor adress" = Cursorposition ist muss das da wohl rein.
Ich verstehe bzw sehe aber in Spruts Erläuterung immer noch nicht wo genau nun die Position eingestellt wird und vermute,
er schreibt einfach immer ausgehend von der "Cursor Home" Position.
- Ist zwar prinzipiell etwas blöde, aber ich werde nachher mal (ev mitm loop) einfach 16+14 Zeichen schreiben,
ob ich dann irgendwann mit dem nächsten Zeichen bei Zeile 2 / Position 1 lande.
Initialisiert wird das LCD jedenfalls als 2 zeilig.


-----------
@-IT nun ists 18:00:
Ich habe jetzt mal die Zeichen primitiv+brutal weitergeschrieben,
also die erste Zeile voll mit 16, dann nochmal ca 20 die man nicht sieht...
Habs paarmal real getestet und danach die Spam-Stellenzahl +/- korrigiert.
Nun lande ich mit "Zeit 2" und "Zeit 3" wie gewünscht in der 2. Zeile,
wobei ein LCD 20x2 besser wäre als das 16x2,
da gehen mir nämlich die Stellen für 2 Zeiten aus.

Sieht aufm LCD nun so aus:
00h:00m:00s,00ms
0:00,00#0:00:00,00

Wobei ich das in der 2.Zeile wohl noch nach
0:00,00##0:00,00
vereinheitlichen werde.

Den Zehn Minuten + Stundentimer kann man ja von der großen Uhr in Zeile 1 ablesen,
und mit etwas Gehirn merkt man dann ja wenns über 9:59,99 waren
und wieder 0:01,xx dasteht ;-)

Jetzt muss ich mich darum kümmern, dass beim Betätigen von "Stopp", der Wert nur einmal von
"zuletzt gemessene Zeit" (rechts unten)
nach
"vorherige Zeit" (links unten)
kopiert wird, und nicht dauernd mitläuft.

Dafür weiß ich nun, dass der Unterschied bei schnellem rumgehoppel auf dem Schalter mal +10mS Differenz sein kann, meist steht aber bei beiden Zeiten sogar 1:1 das gleiche drin.

Jetzt muss ich mir "nur" noch eine if goto else schleife einfallen lassen,
die beim Drücken von "Stopp" nur einmal durchlaufen wird, und dann
da das kopieren der letzten beiden Zeiten reinpacken.

Dann den Port A aktivieren (hab ich schon, nur nix dran),
und dort die "Start" "Stopp" "Reset" Tasten einbinden und entprellen,
wobei ich das entprellen und das "nur einmal kopieren bei Stopp"
wohl dort kombinieren könnte.
Da werde ich wohl mit Zwischenspeicherbits
Start equ xx
Stopp equ xx
Reset equ xx
arbeiten und die Tastenwerte High / Low da reinschreiben,
und mit decfsz evtl zurück oder weiter springen..

edit:
A)
Sind nach den 16 Zeilen in zeile eins nochmal 24 Zeichen,
also insgesamt wirklich 40 in Zeile 1,
dann kommt das nächste in Zeile 2 / Pos1 raus bei 41.

B)
Habe mir nun Notepad++ runtergeladen,
das machts bisschen bunter und zeigt mir die Zeilen-Nummer an.

So, jetzt erstmal n Kaffee.. Ich fühle ich nähere mich dem Ende!

RoboHolIC
06.06.2013, 19:54
Also das war von mir ernst gemeint mit dem "Danke für die Betreuung", da war 0,0% Ironie dabei :-)
Nein, nein, ich hab da keine Ironie rausgelesen; und die "Überbetreuung" hab ich mir ja selbst zugeschrieben.


Ich hab es auch hinbekommen, dass ich den Timer laufen lasse und im "Stopp" Moment
die ZeitWerte alle kopiere. . .
Es besteht ja das Risiko, dass während der Ablesung mehrerer Bytes ein Zählerinkrement dazwischenkommen kann, wo dann ein Überlauf eine inkonsistente Ablesung bewirkt. Da sollte man ein Auge drauf haben. Das andere beschriebene Umkopieren hab ich nicht verstanden.

Mein Vorschlag: Wenn ein STOP (oder auch LAP) erkannt wurde, den nächsten Count im LeastSignificant-Byte abpassen (pollen!) und dann flugs alle Bytes kopieren.
Ein Delay macht sich immer gut. Nach dem Zeitnehmen kann man im Hauptprogramm dann eine Sperrzeit einbauen. 0,3 s beispielsweise wird man nach dem Zeitnehmen gar nicht wahrnehmen und lösen den Konflikt.


Allerdings verstehe ich nicht wie ich im assemblercode in die 2. Zeile des LCD springen kann...
In Spruts LCD Beispielen schreibt er auf seinem 16x2 LCD immer nur in Zeile 1 von ganz vorne...
Ich sehe zwar noch das "Cursor Home", also wohl "Zeile 1, erste Stelle",
finde (verstehe) aber im Datenblatt nicht wie ich den Cursor dann in "Zeile 2, 1.Stelle" schicke um dort weiterzuschreiben.
Das hatte ich oben schon mal angedeutet. Aus meinem Gedächtnis: Die HD44780 (oder wie der heißt)-kompatiblen LC-Controller können bis zu 80 Zeichen darstellen, d.h., 16x2-LCDs zeigen immer nur eine Teilmenge des Zeichenspeichers an. Je nach Schaltungsdesign werden also verschieden Speicherbereich sichtbar gemacht. Das können mal die ersten 32 Speicherstellen am Stück sein oder eben 0..15 und dann erst wieder 40..55 (jeweils dezimal). Versuch einfach mal für die zweite Zeile den Cursor auf Vielfache von 16 oder 20 zu positionieren. Das dürften eigentlich die möglichen Werte sein. Dann weiter sequentiell schreiben.
Grundsätzlich kann man ja alle 80 Zellen beschreiben und durch links/rechts-scrollen des Anzeigefensters sichtbar machen.


Ich schreib grad übrigens immer noch alles in Notepad um,
war beim Fehlersuchen vom Compiler etwas blöd weil Notepad
keine Zeilen-nummerierung anzeigt ;-) .
Muss mal schauen ob das "Notepad+" nicht konnte.
Aversion gegen IDEs?
Ich finde MPLAB(X) OK. Ja, riesig, aber was soll's, so lange der Rechner nicht ins Stocken kommt... Der Zugewinn an Komfort überwiegt für mich. Hab am Anfang (damals beruflich, vom Kollegen vorgeschlagen) mit Batch und Editor gearbeitet. Hab ich eher als mühsam empfunden.



Zusammenfassung:
Wie springe ich zu "Zeile 2, 1. Stelle"
Erweiterung:
Wie Springe ich zu "Zeile 3" und "Zeile 4" beim großen LCD...
2. Zeile 1. Zeichen vermutlich 40dez.
bei 16x4 dürften die Zeilenanfänge relativ sicher 0/20/40/60dez sein.


"Cursor Home" nutzt mir ja nichts,
aber steht das evtl im Datenblatt auf S.8 (unten) bei "Display Data Ram Address Map" -?-
Ja, genau da steht es schwarz auf weiß.

So, jetzt hat sich einiges mit den Nachträgen überschnitten, scheint sich aber gegenseitig zu bestätigen.


Ich fühle ich nähere mich dem Ende! Welchem Ende ? Doch nicht so kurz vor dem Ziel ! :p

Gruß
Christian.

PsiQ
12.06.2013, 00:29
Also irgendwie ist die Benachrichtigungsfunktion kaputt, hab deine Antwort garnicht mitbekommen...
Aber hab auch so quasi alles hinbekommen :-)

Hab erstmal 2 Tage vom Programmieren Abstand gehalten, nur mit Stift+Zettel,
und Hardware gelötet.
Habe die Ports von meinem Z77 Pro4 genau nach Anleitung mit Hilfe der Wikipedia Pinbelegung abgeglichen und eine Buchsenleiste passend ans RS232 Kabel gelötet,
und jetzt funktioniert der alte Velleman 8048 auch an meinem großen PC und ich muss nicht mehr mühsam am Fernseher(PC) aufspielen...

Das Programm macht alles was ich will, aber ich habe gerde Probleme mit einem SpeicherFlag zuwenig.
Es tut (hat getan) alles was muss, aber der Bonus = Ampelfunktion ärgert mich grade.

Also was es nun kann:
Reset/MCLR => Zeiten Nullen
LCD sieht dann so aus:


00h:00m:00s,00ms
0:00,00//0:00,00


StartFlag RA1 ist HIGH nach RESET
Ich springe dann solange beim Auftreten des Interrupts wieder aus dem Timer0 Interrupt raus (goto Int_end) , solange ich die Zeit nicht starten will, also kein Startsignal kam.
Wenn Startsignal kommt, setzte ich StartFlag RA1 = LOW, und springe nicht mehr im Interrupt zum Ende sondern zähle die Zeit hoch, wie original bei Sprut.

Damit läuft die Zeit in "Zeile 1".

Wenn nun "Stopp" kommt, schreibe ich die Zeit von "1.Zeile"
nach "2.Zeile rechts"
und verschiebe vorher "2.Zeile rechts" nach "2.Zeile links".
Ich habe also aufm LCD


[ aktuelle laufende Zeit ]
[vorherige Zeit]/[neueste Zeit]

Das passt soweit alles... äääh. wie beschreibe ich mein Problem:

Mir fehlt eine Speicher-Flag,
das ich mit bsf / bcf benutzen kann
... ... ...

Die Zeit wird bei Stopp HIGH=>LOW nur einmal übertragen,
und erst nach einem LOW=>HIGH und dann wieder HIGH=>LOW erneut überschreiben.
Habe da auch gleich den Taster mit 100ms entprellt und das Dauerkopieren beim Tastehalten beseitigt.
(Das jemand mit 100ms differenz 2x durchs ziel rennt=Stoppt ist unsinn)
--- Dafür brauche ich ein StoppFlag => RA4 (PORTA,4)


Fürs Startflag um die Zeit nicht hochzuzählen
bis "Start" kommt brauche ich das StartFlag = RA1 (PORTA,1)

Und dann will ich noch einen Ampelausgang = grün per Taster aktivieren,
den ich dann in RA3 (PORTA,3) speichere + als Ausgang zum LED-Cluster-Treiber benutze.


SpeicherFlags Übersicht:
Start = RA1
Ampel = RA3
Stopp = RA4

dazu brauche ich noch paar Eingänge:
Stopp => RB1
Start-Taster => RA0
Ampel An => RA2

Wenn man sich die Ports anschaut, passt das theoretisch genau:

PORT A:

RA0 - Startsignal Taster
RA1 - StartFlag
RA2 - Taster Ampel Ein
RA3 - Ampel Ausgang (zum Clustertreiber)
RA4 - StoppFlag
RA5 - MCLR (verwende ich als bequemes Reset ohne Codeaufwand)
RA6 - belegt vom Quarz
RA7 - belegt vom Quarz

PORT B:
RB0 - LCD Enable
RB1 - Taster Stopp
RB2 - LCD RS
RB3 - LCD R/W
RB4 - LCD D4
RB5 - LCD D5
RB6 - LCD D6
RB7 - LCD D7

So. Also theoretisch passts.
ABER! Ich kann RA4 nicht als Flag verwenden!

Ohne Ampelfunktion (RA2+RA3 somit frei) kann ich mein StoppFlag auf RA3 legen.
Dann funktioniert alles. Dürfte auch mit RA2 genauso klappen.

Wenn ich aber die Ampelfunktion nutzenl,
und entweder das AmpelAn Flag in RA4 speichern will,
oder das StoppFlag, klappt das nicht.

bsf / bcf PORTA,4
geht ohne Fehlermeldung oder Programmabsturz o.ä.
Aber es hat keine Auswirkung! Ich konnte auch keine Pegeländerung am PIN direkt am IC messen.

Ich habe probeweise (sehr ätzendes gesuche) im Code RA3 mit RA4 vertauscht, also AmeplFlag / StoppFlag vertauscht.
Einmal geht die Ampel nicht, einmal geht das StoppFlag nicht.

Der Code passt also, aber RA4 scheint sich nicht beschreiben/auslesen (bsf, bcf) zu lassen wie RA3, oder alle anderen RA Pins.
Ich habe am Velleman 8048 keine Verbindung oder Widerstand nach GND oder +5V messen können,
also kein Pullup oder Pulldown Widerstand, auch nicht direkt auf Masse oder +5V gelegt.
Ich sehe leider auf der 2 Layer Platine nicht, ob der Pin irgendwo hingeht, habe aber auch keine sonstige Verbindung zu in der Nähe befindlichen Widerstände / Pins gefunden,
der hängt also evtl komplett in der Luft.

- Nun 2 Fragen:
1. Liegt an RA4 irgendwas spezielles an was ich deaktivieren muss oder umstellen oder was den blockiert?
Den Comparator habe ich aus, die anderen Pins RA0 bis RA3 funktionieren ja auch.

2. Wenn ich RA4 einfach ignoriere (wie ohne Ampelfunktion)
Was für eine andere Flag-Speicherzelle kann ich nutzen, und wie definiere ich die ? Gibt es da noch eine/mehrere die nicht mit dem PortB oder PortA
als "hardware" real verbunden sind und nur "virtuell" vorhanden ?
Sprut schreibt leider nichts zu den vorhandenen Flags ausser dass es da welche in STATUS gibt, das Zero Flag und das Carry Bit.

Und im Programm definiert er noch ein Flag folgendermaßen:

#define neu Flags,0

Also kann er später mit
bsf neu oder bcf neu
das Flag Setzen/Löschen

---WAS PASSIERT--- jetzt wenn ich da einfach schreibe
#define StoppFlag Flags,7

oder

#define StoppFlag Flags,4

Was für "Flags" und wieviele gibts in dem Register "Flags",
und sind davon welche schon vergeben / fest vergeben ??
Wo sitzt da das Carry Bit oder das Zero Bit ??

Wie bastel ich mir ein Flag ?
Nur mit

"StoppFlag equ 0x49"
hats nicht funktioniert
weil bei
bsf was doppeltes erwartet wird im Sinne von

bsf Teil1,NummerTeil2
also wie
bsf PORTA,4

Hmm. hab grad beim Tippen nebenher über Google was gefunden..
( http://www.mikrocontroller.net/topic/4738 )
-- Eventuell muss ich da "equ" einfach doppelt verwenden:

Stopp equ 0x49
Flag equ 0x4A


und dann sollte das später so aussehen:



bsf Stopp,Flag ; Flag wird HIGH

oder

bcf Stopp,Flag ; Flag wird LOW

oder

btfsc Stopp,Flag ; (if) Stopp,Flag = High
return ; (then) return
shutdown ; (else) shutdown


Hmmmm. werde das mal testen, wenns klappt ist mir egal was RA4
macht oder nicht macht oder ob Velleman da auf der Platine was verbockt hat.


Hmmm hmmm hmmm.. Werde das versuchen jetzt noch "schnell" hinzubekommen,
damit ich s morgen nicht vergessen habe wo ich was ändern muss.

-- Brauche also erstmal noch keine Antwort bis ich klappt/ klappt nicht schreibe ;-)

RoboHolIC
12.06.2013, 01:32
Huihui, viel Text und viel Info. Leider bin ich nicht so fix um das alles in vertretbarer Zeit nachzuvollziehen.
Zu drei Dingen kann ich allerdings was sagen.

1.) Der Pin RA4 ist -so weit ich weiß- bei allen PIC16Fxxx ein Open Collector-Ausgang. Daran kann nur eine Spannung gemessen werden, wenn auch ein Widerstand, z.B. 10kOhm, nach +5V angeschlossen ist. Der Open Collector (ein schlichter Transistor, dessen Kollektor unbeschaltet nach aussen geführt ist) für sich alleine kann nämlich nur Strom nach GND fließen lassen oder eben nicht.
(Zweck des RA4 dürfte die Anbindung des Controllers an Wired-Or-Leitungen sein, die einen etwas höheren High-Pegel als nur +5V führen. Sehr viel mehr geht da aber auch nicht, ich erinnere mich, Maximalwerte im nur einstelligen Voltbereich gelesen zu haben.)

2.) Geht es bei den Flagvariablen um das Anzeigen von Informationen (z.B. Debugging) oder um reine Arbeitsflags? Im letzteren Falle sind Portpins Verschwendung, du kannst Flags bis zum Abwinken im RAM selbst definieren.
Es wird mittels "flag equ 0x20 ; nur ein Zahlenbeispiel" eine beliebige RAM-Speicherzelle für acht Flags mit dem Verwaltungsnamen 'flag' belegt.
Die einzelnen Flagbits werden mittels "einflag equ flag.1 ; erstes Flagbit", "nocheinflag equ flag.2 ; zweites Flagbit" usw. usf. sinnvoll benannt und können im Code per "bsf einflag" oder "btfss nocheinflag" referenziert werden. Das ist zugleich maximal effiziente Speicherausnutzung, es stehen alle acht Bits je RAM-Byte als Flags zur Verfügung. Das ganze macht relativ viele Source-Zeilen, verbraucht aber keinen einzigen Programmspeicherplatz, weil es sich nur um Verwaltungsinformationen für den Assembler handelt.
In gleicher Weise können auch die Portleitungen des Controllers mit sprechenden Namen versehen werden.

3.) Die ALU der PIC16-Familie kennt nur Carry- und Zero-Flag als Output der Befehlsabarbeitung; beide stehen im STATUS-Byte. Alle anderen dokumentierten Flags dienen der Steuerung der Controllerhardware oder sind Ergebnisse von Ereignissen in der Umwelt oder der Controller-Peripheriemodule UART, Timer etc.

Noch ein Letztes: Hast du im Code irgendwo die Analog-/-Digital-Eigenschaft des Port A verändert? Das würde sich eventuell mit der digitalen Nutzung beißen: Analogpins werden digital als Low gelesen, egal was wirklich am Pin los ist.

PsiQ
12.06.2013, 02:41
So, fertig! => Funktioniert alles :-)

Habe jetzt mein Ampel-10-Zeilen-Unterprogramm gelöscht, und ganz simpel ersetzt durch

(Im Main Loop)
btfsc PORTA,2 ; Wenn Taster an RA2 gedrückt
bsf PORTA,3 ; schalte Ampel An (RA3 HIGH)

Und in der Start und der Stopp Subroutine fange ich an mit
bcf PORTA,3 ; Ampel ausschalten


Zu1.:
Irgendwo hab ich im Datenblatt was gelesen zu dem RA4 und der Spannung (Referenz, Messung??), aber dachte wenn ich den "digital Einschalte" wie den Rest ist das erledigt.
-- Nunja, jetzt kann er machen was er will, weil ich ja jetzt eine freie Flag definieren kann :-)
Das dürfte wirklich die Erklärung für das Problem sein, der kann sich garnicht aktiv High oder LOW setzen.

Zu 2.: Flags als Anzeigen:
Ich brauche/möchte das Ampel Flag und das Startflag
anzeigen auf einer LED.

- Über die LED am Startflag sieht man, dass Reset erfolgt ist und alles bereit ist.
- Über die Ampel LED schalte ich eben auch diese Ampel an.

Das Stoppflag brauche ich nur Softwareintern um das ständige Überschreiben der alten Zeiten bei Stopp zu verhindern,
das habe ich nun nur noch virtuell.
=> Da habe ich am Ende nochmal richtig was gelernt, irgendwie war mir zwar bewusst ich kann etliche Variablen definieren,
habe das bei "Flags definieren" aber nach anfänglichem rumtesten+Fehlschlag als nicht möglich angenommen

Hatte mir schon überlegt die Variante mit Tastatur+LCD an PortB anzuschauen, das geht ja auch noch für Eingänge,
aber das passt nun schönerweise mit den Ein+Ausgängen genau wie ichs brauche.

Zu 3.:
Ok, also hat das "STATUS" gar nichts mit den restlichen virtuellen Flags zu tun.
Da mangelt es etwas an Ausführlichkeit bei Sprut bei der Beschreibung und im Quelltext.

Zum letzten:
Nein, nun klappt auch alles. (ohne RA4 zu nutzen) Ich habe alles deaktiviert was ging (CCP),
und entsprechend beim init die Ports auf Input / Output gestellt wie ichs gerne hätte.
Und nichts extra "aktiviert".

Abschluss:
Habe mein Velleman 8048 weiter gepimpt, und nun auch an RA0 bis RA3 LEDs parallel zu den originalen Tastern, die ich per Jumperbrücke zuschalten kann.
- War nötig weil ich beobachten wollte ob/wie mein Programm die Flags setzt.
Original werden die Ports per 10k Widerstand nach Masse gezogen, die Taster schalten gegen +5V / HIGH.

Das 20x4 LCD habe ich noch nicht zum Laufen bekommen, habe am LCD und den LCD Pins Stiftleisten / Buchsen verlötet,
so dass ichs einfach aufm Velleman um/einstecken kann. - Da muss ich beim initialisieren wohl nochmal reinschauen.

Bis Freitag kommen hoffentlich von Amazon noch 3 Stück 20x4 in blau, für nur 8 euro das Stück inklusive Versand,
mit HD44780 Controller, dann habe ich noch andere 20x4 zum Testen.

Werde die Tage jetzt mal die Lochrasterplatine neu bauen/kontrollieren wenn ich Zeit + Lust habe, und schauen dass die läuft.
Und mal mitm 4.096er Quarz n paar Stunden Uhrenvergleich machen.

Frage am Rande: Gibt es irgendwo billige Fertigplatinen mit PICs a la Arduino?
Habe den Pinguiono gefunden und andere Open-Source Projekte, aber kein einfache, fertige und bezahlbare Platine wie es von Atmel
soviele gibt. Sowas um 25Euro mit Spannungsregler, IC, Quarz und rausgeführten Anschlusspins.
- Nicht dass ich's nicht kann, aber ich will keine Platinen mehr Ätzen/Bestücken und Fehler suchen, wenns nicht sein muss.

... Hab grad keine Lust das ganze Theater nochmal fürn Arduino micro zu machen ...

PsiQ
20.06.2013, 17:58
Habe heute meine LCDs 20x4 in blau erhalten. Habs auf amzon bestellt da recht günstig/Versandkostenfrei, sind aber lange Lieferzeiten angegeben.
Offiziell hätte es noch bis 8.Juli dauern dürfen, nun sind se aber heute gekommen. werden wohl auch über ebay verkauft.
(amazon/ emall supply / 20x4 lcd modul, blau/weiss 7,99)
Auf dem Display steht noch
QC2004A (sure electronics)
Darüber findet man ein sehr kurzes Dateblatt, was in mir erstmal Sorgen fürs Initialisieren verursacht hat.
Laut Angabe im Datenblatt wird aber ein HD44780 verwendet (kein Ersatz).
Also schnell die Pins geprüft, passen zum Standard, den Kontrastpin nach gnd gebrückt...
einfach angesteckt an meine Platine ... und ... funktioniert sofort + astrein!
Im Originalprogramm habe ich 2x16 Zeichen ausgegeben,
und dazwischen sinnlose Lückenfüller.

Auf dem 4 Zeilen LCD werden nun alle Zeichen die in den Puffer passen angezeigt,
Zeile 1+3 entspricht der oberen Zeile beim 16x2 (Summe 40 Zeichen)
Zeile 2+4 der 2. Zeile beim 16x2. (Nochmal 40 Zeichen)

http://s13.postimg.org/5jof147s7/lcd_neu.jpg (http://postimage.org/)

PsiQ
25.06.2013, 17:44
Ich habe mir jetzt mal den Pinguino geordert ( http://www.watterott.com/de/PIC32-PINGUINIO ) auf den ich dank dem hinweis im anderen Thead gekommen bin.

Gleichzeitig überlege ich gerade ob ich bis der kommt mit dem Arduino den ich nun hier liegen habe das machen soll ... ... .. hmm.

Mein Assembler Code ist ja nun für den PIC16F628A geschrieben...
Wenn ich da die entsprechenden I/O Pins und den Quarz(Frequenz) anpasse,
ist der Code dann auch auf dem PIC32MX440F256H lauffähig?

Wenn ja:
Ich würde dann den Pausentimer (wait kram) von den 4.096 auf den 8Mhz Quarz anpassen,
und dann das Programm noch um eine Stelle vor [1ms] mit passendem krummen Vorteiler einfügen.
Muss noch schauen obs immernoch Frequenz= Quarztakt:4 ist oder der dann im 1:1 Takt läuft..
Dann die 4 Taster und LCD Pins Portmäßig hinbiegen, und die 3 Ausgangs-LEDs...
und paar andere Sachen die ich grade vergesse ... ;-)

- ich will irgendwie ungern auf Hochsprache wechseln wo ichs nun so effizient und klein geschafft habe.

RoboHolIC
26.06.2013, 01:58
Mein Assembler Code ist ja nun für den PIC16F628A geschrieben...
ist der Code dann auch auf dem PIC32MX440F256H lauffähig?

Ich bin noch ganz am Anfang mit den 16/32-Bittern von Microchip, aber soweit ich das sehe, sind die so gravierend unterschiedlich in Struktur und Befehlssatz zu den PIC16-ern, dass eine simple Portierung nicht gehen wird.

PsiQ
06.07.2013, 19:32
Joah, scheint so.

Irgendwie scheint mir der Arduino als Fertigplatine auch Einsteigerfreundlicher als der Pinguino den ich nun hier habe..
(Vermutlich weil länger da = mehr Gedanken dazu im Netz)
Ich hab ja nun quasi keine Ahnung von C und der Semantik, aber beim Arduino krieg ichs wohl immerhin schonmal hin,
dass er was aufs LCD ausspuckt. ("Rein theoretisch", habs Beispiel angeschaut, aber den Lötkolben noch nicht geschwungen)

Ich fürchte nur, dann geht die ganze Überlegung mit Timer/Interruptkram für die Genauigkeit erstmal flöten,
weil ich gar keinen wissentlichen Zugriff mehr auf die Basis unter irgendwelchen Bibliotheken habe.
Es scheint sogar ne Bibliothek zu geben, die den Fehler/Abweichungen
aus der Standard Timer Bibliothek verbessert :confused: - Wie dämlich ist das denn.

Und meine kleinen Code 2-zeiler If-then-Else
sind plötzlich 10mal größer und langsamer. :(