Hallo,
ich habe ein Problem mit einem LCD. Es ist ein zweizeiliges mit jeweils
8 Stellen pro Zeile mit Hitachi hd44780 Controller. Ich betreibe dies im
4 Bit breitem Modus an PortB und PortC eines PIC 16F886. Zusätzlich habe
ich an PortA zwei Kontroll-LED’s. Als Vorlagen dienten ein Skript von
Sprut und ein anderes Skript zur Stringausgabe von phanderson.com. Ich
hatte viele Probleme mit den Ports, weshalb ich die Werte zunächst in
Shadow Registern speichere um sie dann erst gesammelt in den jeweiligen
Port zu laden. Dies geschieht mit den Funktionen write_porta,
write_portb und write_portc.
Damit ich nicht jedes Mal beim Setzen von Bits in Port B die LCDE
Leitung neu setze, ist diese einzeln an PortC. Die Beschaltung sollte
soweit stimmen, da ich mit einer bestimmten Variante meines Codes (der
hier geposteten) das Display soweit ansteuern kann und es string0 in
einer Zeile meiner Wahl ausgibt. Füge ich jedoch neue Programmzeilen
hinzu (zum Beispiel das im Moment auskommentierte Programm;
beliebiges_programm) oder möchte ich einen anderen als String 0
ausgeben, so funktioniert mein Skript nicht mehr.
Woran liegt das?
Ich könnte vermuten, dass es mit der Programmspeicherorganisation
zusammenhängt. Ein Teil des phanderson Skriptes war auf der zweiten
Seite des Programmspeichers abgelegt. Ich habe diese drei Zeilen aber
deaktiviert, da es mit diesen Zeilen überhaupt nicht lief.
Bei Bedarf kann ich noch die Schaltung nachreichen.
1
listp=16f886;listdirectivetodefineprocessor
2
#include<p16f886.inc> ; processor specific variable definitions
Wenn keiner dein Programm debuggen will...
Kauf dir einen Pickit3 oder China-Clone. Mit dem In-Circuit Debugger
wird MC-Programmierung so einfach wie PC-Programmierung.
(Im 16f886 Datenblatt steht nur was von ICD, der günstige Pickit
funktioniert auch).
R. S. schrieb:> Als Vorlagen dienten ein Skript von> Sprut
...damit hatte ich meine ersten "Gehversuche", funktioniert für den
Anfang
prima!
> und ein anderes Skript zur Stringausgabe von phanderson.com.
...warum nicht selber geschrieben,so lernt man am besten
> Zusätzlich habe> ich an PortA zwei Kontroll-LED’s
...prima,für was nutzt Du diese?
> Ich hatte viele Probleme mit den Ports, weshalb ich die Werte zunächst> in Shadow Registern speichere
...hmm,kann man machen,aber ein Sinn sehe ich nicht wirklich? wo lagen
die Probleme?
> Dies geschieht mit den Funktionen write_porta,> write_portb und write_portc.> Damit ich nicht jedes Mal beim Setzen von Bits in Port B die LCDE> Leitung neu setze, ist diese einzeln an PortC.
....3 ports zur ansteuerung eines Display ;-)..ja das kenne ich auch
noch,
ist für den Anfang super einfach, aber versuch mal Spruts Beispiel auf
ein Port umzuschreiben.
> Die Beschaltung sollte> soweit stimmen, da ich mit einer bestimmten Variante meines Codes (der> hier geposteten) das Display soweit ansteuern kann und es string0 in> einer Zeile meiner Wahl ausgibt. Füge ich jedoch neue Programmzeilen> hinzu (zum Beispiel das im Moment auskommentierte Programm;> beliebiges_programm) oder möchte ich einen anderen als String 0> ausgeben, so funktioniert mein Skript nicht mehr.> Woran liegt das?
...wie macht es sich bemerkbar?
Hängt Dein Programm irgendwo fest,oder läuft Dein Controller Amok?
Hier bieten sich deine LEDs als Indikator an, wenn man sie entsprechend
in den betreffenden Programmteilen einbaut.
Vielleicht schreibt Deine Routine den zweiten String nur ausserhalb des
sichtbaren Bereiches in den Ram des Displays?...hab jetzt nicht
nachgeschaut ob du den Kursor vor dem neuchschreiben auf Anfang gesetzt
hast....
> Ich könnte vermuten, dass es mit der Programmspeicherorganisation> zusammenhängt. Ein Teil des phanderson Skriptes war auf der zweiten> Seite des Programmspeichers abgelegt. Ich habe diese drei Zeilen aber> deaktiviert, da es mit diesen Zeilen überhaupt nicht lief.
...wie gesagt, investiere die Zeit, mach Dir Gedanken und versuche sowas
selber zu schreiben, der Lerneffekt ist unglaublich und wird Dir in
Zukunft
bei neuen Problemstellungen doppelt und dreifach Zeit zurück geben ;-)
R. S. schrieb:> Füge ich jedoch neue Programmzeilen> hinzu (zum Beispiel das im Moment auskommentierte Programm;> beliebiges_programm) oder möchte ich einen anderen als String 0> ausgeben, so funktioniert mein Skript nicht mehr.
Vermutlich überschreitet dann Dein Programm die 256 Word Größe.
Im Unterschied zu vielen anderen MCs ist beim PIC der Flash und der SRAM
in 256 Byte Stücke segmentiert. Ein Zugriff ist daher nur in der
ausgewählten Page bzw. Bank möglich.
Will man einen Jump oder Call in eine andere Page machen, muß man
deshalb vor jedem Call das PCLATH berechnen.
Die DT-Anweisung ist eigentlich ein RETLW und benötigt auch einen CALL,
d.h. vor jedem Byte lesen muß PCLATH berechnet werden.
R. S. schrieb:> Ich> hatte viele Probleme mit den Ports, weshalb ich die Werte zunächst in> Shadow Registern speichere um sie dann erst gesammelt in den jeweiligen> Port zu laden.
Ja, die älteren PICs ohne Latch spielen einem lustige Streiche ohne
Schattenregister.
Man sollte modernere nehmen, die ein Ausgangslatch haben. Da kann man
dann gefahrlos einzelne Bits setzen oder löschen ohne die anderen zu
beeinflussen.
Peter
Peter Dannegger schrieb:> Ja, die älteren PICs ohne Latch spielen einem lustige Streiche ohne> Schattenregister.> Man sollte modernere nehmen, die ein Ausgangslatch haben. Da kann man> dann gefahrlos einzelne Bits setzen oder löschen ohne die anderen zu> beeinflussen.
..cool,der Peter hat die passende Antwort immer zur Hand, jetzt dämmerts
bei mir auch wieder.
Ist schon eine Ewigkeit her, als ich mit den kleineren Pics meine ersten
Programmierversuche machte.
Die Speicheraufteilung in Pages und die damit verbundenen
Bankumschaltungen bis hin zu der Latch-geschichte...auweia!
Man ist mittlerweile sehr verwöhnt ;-)
Hallo,
zunächst erstmal vielen Dank für eure Zeit!
pompete schrieb:> ...warum nicht selber geschrieben,so lernt man am besten
Hatte selber schon ein paar Sachen geschrieben. Einzelne Buchstaben
konnte ich problemlos ausgeben. Nur bei ganzen Wörtern wurde der
Quelltext elendig lang, weshalb ich diese Vorlage nahm.
pompete schrieb:> ...prima,für was nutzt Du diese?
Die habe ich immer genutzt um zu sehen wo sich mein Programm aufhängt.
pompete schrieb:> ...hmm,kann man machen,aber ein Sinn sehe ich nicht wirklich? wo lagen> die Probleme?
Das Problem bestand darin, dass sobald ich Bits an den Ports geändert
habe sich alle anderen mit änderten. Scheint auch ein gängiges Prolem zu
sein, die Lösung hatte ich irgendwo im Netz gefunden
pompete schrieb:> ....3 ports zur ansteuerung eines Display ;-)..ja das kenne ich auch> noch,> ist für den Anfang super einfach, aber versuch mal Spruts Beispiel auf> ein Port umzuschreiben.
Eigentlich 2 Ports - den dritten werde ich für was anderes gebrauchen,
wenn ich die LED nicht mehr benötige. Weniger als 2 Ports gingen wegen
des oben genannten Problems leider nicht.
pompete schrieb:> ...wie macht es sich bemerkbar?> Hängt Dein Programm irgendwo fest,oder läuft Dein Controller Amok?> Hier bieten sich deine LEDs als Indikator an, wenn man sie entsprechend> in den betreffenden Programmteilen einbaut.
Probleme sind die folgenden:
-Aktiviere ich das nutzlose Zwischenprogramm, so wird nix mehr am
Display ausgegebn
-Will ich einen anderen als String 0 ausgeben, so wird "Strin"
ausgegeben und das Display gelöscht, wieder "Strin" ausgegeben usw.
-
pompete schrieb:> Vielleicht schreibt Deine Routine den zweiten String nur ausserhalb des> sichtbaren Bereiches in den Ram des Displays?...hab jetzt nicht> nachgeschaut ob du den Kursor vor dem neuchschreiben auf Anfang gesetzt> hast....
Guter Tipp aber die LCD Adressen stimmen soweit, da ich String 0 ja an
einer beliebigen Stelle ausgeben lassen kann.
> ...wie gesagt, investiere die Zeit, mach Dir Gedanken und versuche sowas> selber zu schreiben, der Lerneffekt ist unglaublich und wird Dir in> Zukunft> bei neuen Problemstellungen doppelt und dreifach Zeit zurück geben ;-)
Da hast du Zweifelsfrei recht, ich bin nach ca. 40 Arbeitsstunden aber
mit meinem Latein am Ende....
Peter Dannegger schrieb:> Vermutlich überschreitet dann Dein Programm die 256 Word Größe.> Im Unterschied zu vielen anderen MCs ist beim PIC der Flash und der SRAM> in 256 Byte Stücke segmentiert. Ein Zugriff ist daher nur in der> ausgewählten Page bzw. Bank möglich.>> Will man einen Jump oder Call in eine andere Page machen, muß man> deshalb vor jedem Call das PCLATH berechnen.> Die DT-Anweisung ist eigentlich ein RETLW und benötigt auch einen CALL,> d.h. vor jedem Byte lesen muß PCLATH berechnet werden.
Das mit dem PCLATH habe ich ganz grob verstanden, aber soweit ich das
überblicke ist mein Programm nicht so groß. Wenn ich mir die HEX Datei
mit USBurn anzeigen lasse befinden sich nur im ersten Block blau
markierte Stellen.
Peter Dannegger schrieb:> Ja, die älteren PICs ohne Latch spielen einem lustige Streiche ohne> Schattenregister.> Man sollte modernere nehmen, die ein Ausgangslatch haben. Da kann man> dann gefahrlos einzelne Bits setzen oder löschen ohne die anderen zu> beeinflussen.
Welche PICs besitzen diese Funktion? Ab 18F ?
Übrigens habe ich nun auch Probleme einen 16f628a zu beschreiben. Ich
vermute, dass es mit meinem Brenner8 zusammenhängt. Ich werde mir nun
das PICKIT3 zulegen. Ich habe das PICKIT3 bei verschiedenen Anbietern
mit Bildern gesehen. Ab und zu waren "Adapterplatinen" dabei, welche an
den roten PICKIT angeschlossen werden und wo sich der zu beschreibende
PIC in einen Nullkraftsockel einstecken lässt. Ist das der
Standardlieferumfang?
Ich hätte gerne diese Platinen, damit ich direkt starten kann wenn das
PICKIT da ist. Wenn ich das richtig überblicke ist bei manchen Paketen
eine Testplatine mit einem Pic18f dabei. welchen Zweck hat diese?
Bei Conrad ist es grade für 63€ im Angebot. Nur weiß ich nicht ob die
passenden Adapter dabei sind
Peter Dannegger schrieb:> Ja, die älteren PICs ohne Latch spielen einem lustige Streiche ohne> Schattenregister.> Man sollte modernere nehmen, die ein Ausgangslatch haben. Da kann man> dann gefahrlos einzelne Bits setzen oder löschen ohne die anderen zu> beeinflussen.
So ist das nicht ganz richtig. Es gibt Probleme, wenn der Portpin nicht
dem Zustand des Ausgangstreibers entspricht. Bei einem Read-Modify-Write
Befehl wird dabei der falsche Portwert eingelesen und dann
zurückgeschrieben. Ein solcher Zustand kann eintreten, wenn ein Bit im
vorigen Maschinentakt geändert wurde. Wenn man zwei Bitset oder Bitclear
Befehle auf dem gleichen Port hintereinder ausführt, kann das auftreten.
Ein Nop dazwischen hilft.
Änliches passiert, wenn man große Kapazitäten an einem Portpin hat.
Solange der nicht aufgeladen ist, wird auch der falsche Wert beim
Read-Modify-Write ausgelesen und zurückgeschrieben.
Wenn man weiß, was man tut, ist das alles kein Problem.
MfG Klaus
R. S. schrieb:> Ab und zu waren "Adapterplatinen" dabei, welche an> den roten PICKIT angeschlossen werden und wo sich der zu beschreibende> PIC in einen Nullkraftsockel einstecken lässt.
Das hilft dir nicht beim Debuggen und da dein Code nicht funktioniert,
brauchst du dringend einen Debugger.
MfG Klaus
R. S. schrieb:> Bei Bedarf kann ich noch die Schaltung nachreichen.>> list p=16f886 ; list directive to define processor> #include <p16f886.inc> ; processor specific variable definitions> ...
Erstmal wäre es ganz praktisch, Quellcode dieser Länge als Dateianhang
anzuhängen.
Klaus schrieb:> Ein Nop dazwischen hilft.>> Änliches passiert, wenn man große Kapazitäten an einem Portpin hat.> Solange der nicht aufgeladen ist, wird auch der falsche Wert beim> Read-Modify-Write ausgelesen und zurückgeschrieben.>
Hallo Klaus,
das mit dem nop habe ich auch probiert hatte nicht geholfen, obwohl ich
keine große Kapazität am Ausagang hatte - nämlich nur ein Transistor
(BC337)
Naja mit der Shadowregisterlösung bin ich soweit zufrieden.
Aber wie habe ich das mit dem Debugger zu verstehen?
Das PICKIT3 ist doch Debugger und Programmer zugleich oder?
Zumindest dachte ich das....
Ich dachte der rote PICKIT Kasten hat einen Ausgang mit x-Pins die dann
noch an den PIC gebracht werden müssen - hierzu dienen die Adapter.
Ist das Falsch?
Was du suchst als PicKit3 + Platinen ist das
"DV164131" (= PICkit 3 Debug Express).
Zusätzlich kann man kaufen die "DM164120-3" (28-Pin) und/oder "DM
164120-4" (18-Pin).
Man kriegt 3 Platinen: eine bestückte + 2 leere.
Das ist das PicKit3 jeweils direkt anschließbar.
Der moderne 18-Pin uC ist der PIC16F1827.
Weitere Beiträge hier
Beitrag "Re: PIC Programmiereinstieg"
Autor: Erich (Gast)
Datum: 13.09.2012 11:40
und hier
Beitrag "Re: PIC Programmiereinstieg"
GOOGE: "DV164131" microchip
Gruss
R. S. schrieb:> Wenn ich mir die HEX Datei> mit USBurn anzeigen lasse befinden sich nur im ersten Block blau> markierte Stellen.
Sicher, daß ein Block im Programmer auch einer Page im Code entspricht?
Schau einfach ins Assemblerlisting, ob da eine Adresse > 00FF auftaucht.
Die Strings sind schonmal 44 Words.
Wenn Du den Code angehangen hättest, könnte man leicht sehen, wieviel
Zeilen das sind.
Peter
R. S. schrieb:> Das PICKIT3 ist doch Debugger und Programmer zugleich oder?> Zumindest dachte ich das....
Das Pickit ist die Verbindung zwischen deinem Prozessor und Mplab. Mplab
ist die Toolchain von microchip in der alles drin ist was man zum
programmieren und debuggen so bracht. Assembler,Compiler,Debugger
Simulator etc pp. Frei zum downloaden und kostenlos.
Damit kannst du dein Programm debuggen. Es dauert aber eine gewisse Zeit
bis man durch dieses etwas wirre Programm durchgestiegen ist.
Das PicKit 2 ist übrigens teilweise besser geeignet weil es auch mit
anderen Compilern zusammenarbeitet und auch als Terminal dient über den
man z.B. Texte Statis und Variablen ausgeben kann.
Peter Dannegger schrieb:> Will man einen Jump oder Call in eine andere Page machen, muß man> deshalb vor jedem Call das PCLATH berechnen.> Die DT-Anweisung ist eigentlich ein RETLW und benötigt auch einen CALL,> d.h. vor jedem Byte lesen muß PCLATH berechnet werden.
Nun, beim 16F886 ist eine Codebank 2k groß (11 Bit Adresse im 14 Bit
Instruction Word), ist das Programm kleiner als 2k muß garnichts
berechnet werden.
Der Rächer der Transistormorde schrieb:> Damit kannst du dein Programm debuggen. Es dauert aber eine gewisse Zeit> bis man durch dieses etwas wirre Programm durchgestiegen ist.
Was daran wirr sein soll, ist mir nicht klar. Es ist die Netbeans IDE.
Nun kann man Eclipse oder Visual Studio besser finden, ist eine
Geschmacksfrage. Aber wirr ??
MfG Klaus
Ergänzend zum Beitrag von vorhin hier noch folgendes (auch wenn ich dies
neulich erst schrieb bei
Beitrag "Re: PIC Programmiereinstieg"):
Du sparst dir viel Mühsal, wenn du gleich noch in C programmierst.
Es gibt für besagte uC keine Notwendigkeit und keinen Grund noch
Assembler einzusetzen.
Lerne gleich in C zu programmieren -- ist sinnvoller.
Auf der CD zum "DV164131" sind 10-12 Beispiele, diese systematisch
durcharbeiten und und bist gut aufgestellt.
Parallel dazu kannst die Aufgaben auch vom dortigen PIC18F45K20 auf den
Chip deiner Wahl umarbeiten. Wobei der 16F1933 oder 16F1936 die neueren
28-Pin Typen sind.
Gerade mit den (kleinen) Pic16 ist Assembler ein Bankswitching und
"retlw" Kauderwelch ohne Ende. Sinnlos.
Und nochwas, aber das schrieb auch schon einer: lange Listings hier
einstellen, das schreckt eher ab. Dateianhang ist besser.
Gruss
Klaus schrieb:> Nun, beim 16F886 ist eine Codebank 2k groß (11 Bit Adresse im 14 Bit
Sorry, ich war irgendwie beim PIC12.
Die PIC unterscheiden sich ja erheblich im Core.
Die 8051 haben alle den gleichen Core. Es gab zwar Versuche, den 8051
aufzubohren (Dallas 80C390, Intel 251, Philips MX) zu 16Bit und mehr
Adreßraum, aber das hat gefloppt.
Peter
Hallo R. S. (frederenke)
Besteht Dein Problem noch?
In dem Fall kann ich Dir ein LCD-Basisprogramm in MPLAB-Assembler
(beruht auf Sprut) zukommen lassen, welches ich mal für den 16F876
geschrieben habe und welches auch funktioniert, bzw. worauf Due aufbauen
kannst.
Zum 16F886 dürften wohl keine Unterschiede bestehen, welche die Funktion
der LCD-Ausgabe gefährden könnten.
mfG Ottmar
R. S. schrieb:> Hallo Ottmar> gerne - kann man in dem Programm Strings angeben?> Gruß
zunächst "nein". Das Programm gibt lediglich diesen 2 Zeiler aus:
"LDC READY 4 YOU!. Damit weiß man aber, dass das LCD funktioniert und
man den Fehler anderswo suchen muss.
Eine passende Routine zur Ausgabe von Strings Sub Lcd_Out (auch bei
www.sprut.de gesehen) hänge ich dir zusätzlich an. Die Routine hatte ich
zur Ausgabe von Menüs, Registerinhalten etc verwendet. Für lediglich 8
Zeichen oder so ist diese Sub etwas zu ausladend geraten. Ihre Stärke
hat sie aber bei der Ausgabe von zig Menüs oder beim Debuggen.
Evtl. mußt Du da nochmals nachfragen, falls nicht ganz verständlich,
ist jetzt doch etwas spät.
mfg Ottmar