Hallo zusammen,
ich möchte mit einem Taster einen Synthesizer ansprechen.
Mich interessiert jetzt nur mal die Programmierung in C in Bezug auf den
NXP Mikrocontroller P89LPC 935FA.
Ich weiß, dass ich für mein Projekt folgende Messages brauche:
1) note on
2) note off (Abschaltung muss erfolgen sonst Dauerton)
die beiden Befehle am besten im running Modus um Bits und Bytes zu
sparen
3) einen festen Midi Notenkanal von 10
4) eine feste Velocity (Lautstärke)
5) eine variable Tonhöhe von 0 bis 127 (entspricht meiner
Percussionauswahl)
Mit einem weiteren Taster oder Inkrementalgeber soll die
Percussionauswahl gemacht werden.
Ich weiß wie der Hex-Code aufgebaut ist und ich versteh diesen auch.
(siehe dazu Bild)
Außerdem ist mir auch bekannt, dass die Midi-Schnittstelle auf der UART
basiert und dass diese nicht spannungssteuert ist wie die RS-232,
sondern stromgesteuert.
Die Midi Schnittstelle arbeitet als Stromquelle mit einer Stromstärke
von 5 mA. "Strom an" bedeutet logisch "0". Der Optokoppler am MIDI IN
eines Synhesizers muss auf weniger als 5 mA ansprechen.
Was ich aber nicht weiß ist wie ich einen Übergang vom Taster am LPC
(low/ hig Pegel) zu dem Midi Hex Code herstelle, damit am RX (Senden)
Port ein Datenstrom generiert wird?
Und dieser Datenstrom dann letzt endlich meinen Synhesizer einschaltet,
damit ich ein Percussionsound höre?
Könnt ihr mir da bitte helfen, indem ihr mir C Beispiele hier postet.
Oder mir eure Hile anbietet. Momentan bin ich da noch sehr hilflos.
Ich hoffe, dass ihr mir da weiterhelfen könnt.
Vielen Dank
Tim
Such dir das billigste Beispielprogramm heraus, wo ein Taster eingelesen
wird. Da steht drin, wie man einen Taster einliest.
Dann such dir eins aus den Beispielprojekten heraus, das eine/die
serielle/-n Schnittstelle/-n irgendwie benutzt. Finde heraus, wie man
die Baudrate einstellt. Finde heraus, wie man ein Byte abschickt.
Schicke mehrere hintereinander.
Zum Drehencoder sollte es einen Artikel geben: Drehgeber
Wenn dir ein Begriff nichts sagen sollte, ab damit in deine
Lieblingssuchmaschine :) Und kauf dir ein gutes C-Buch.
mf
Danke soweit. Hast du evtl konkrete Beispiele, Internetseiten oder
Quellcodes in C.
Also einen Taster einlesen ist kein Problem.
Die Baudrate einstellen ist auch noch nachvollziehbar.
Aber unklar ist mir die eigentliche Programmierung, wie spreche ich mit
einem Bits durch den Taster z.B.: einen Midi Hex Code an.
Das ist mein Problem.
Wenn ich das wüßte wäre ich einiges weiter.
Danke nehm gerne weitere Hilfen und Tipps entgegen.
Normalerweise schreibt man da 3 einzelne Funktionen und ein main() mit
Endlosschleife.
-Eine/mehrere Funktionen zum Initialisieren von Port und UART.
-Eine Funktion zum Taster abfragen mit Entprellung.
-Eine/mehrere Funktion zum zusammenstellen und senden der Midi
Kommandos.
Dein main() ruft zuerst die Initialisierung auf. Anschließend ruft es in
einer Endlosschleife immer wieder abwechselnd die beiden Funktionen auf.
Taster abfragen, entscheidet was zu tun ist, Midi Funktion aufrufen.
Schlagzeuger schrieb:> konkrete Beispiele, Internetseiten oder> Quellcodes in C
Gibts da keine bei NXP? Sind bei deinem Dev-Board keine dabei? War da
eine CD mit beigelegt oder ein Link angegeben?
mfg mf
Schlagzeuger schrieb:> Mich interessiert jetzt nur mal die Programmierung in C in Bezug auf den> NXP Mikrocontroller P89LPC 935FA.
Das ist schlecht, die Scheuklappen kannst du gleich wieder ablegen.
> Ich weiß, dass ich für mein Projekt folgende Messages brauche:> 1) note on> 2) note off (Abschaltung muss erfolgen sonst Dauerton)> die beiden Befehle am besten im running Modus um Bits und Bytes zu> sparen> 3) einen festen Midi Notenkanal von 10> 4) eine feste Velocity (Lautstärke)> 5) eine variable Tonhöhe von 0 bis 127 (entspricht meiner> Percussionauswahl)> Mit einem weiteren Taster oder Inkrementalgeber soll die> Percussionauswahl gemacht werden.
Ok, das ist doch schon was.
> Ich weiß wie der Hex-Code aufgebaut ist und ich versteh diesen auch.> (siehe dazu Bild)
Naja, dazu gehört jetzt nicht viel.
> Außerdem ist mir auch bekannt, dass die Midi-Schnittstelle auf der UART> basiert und dass diese nicht spannungssteuert ist wie die RS-232,> sondern stromgesteuert.> Die Midi Schnittstelle arbeitet als Stromquelle mit einer Stromstärke> von 5 mA. "Strom an" bedeutet logisch "0". Der Optokoppler am MIDI IN> eines Synhesizers muss auf weniger als 5 mA ansprechen.>> Was ich aber nicht weiß ist wie ich einen Übergang vom Taster am LPC> (low/ hig Pegel) zu dem Midi Hex Code herstelle, damit am RX (Senden)> Port ein Datenstrom generiert wird?> Und dieser Datenstrom dann letzt endlich meinen Synhesizer einschaltet,> damit ich ein Percussionsound höre?
Ein Übergang, was soll das sein? Es läuft so: Die Tasten werden zyklisch
abgefragt, sobald eine betätigt wurde muss dein uC die passende
Bitsequenz über den USART rausschieben. Wenn Baudrate und elektrische
Verbindungen gepasst haben, sollte der MIDI-Empfänger auch etwas
empfangen.
>> Könnt ihr mir da bitte helfen, indem ihr mir C Beispiele hier postet.> Oder mir eure Hile anbietet. Momentan bin ich da noch sehr hilflos.> Ich hoffe, dass ihr mir da weiterhelfen könnt.
Klar bekommst du Hilfe, dafür ist ein Forum ja da. Aber einfach
C-Beispiele vorkauen, das macht nicht viel Sinn. Es führen vele Wege
nach Rom und es wäre nicht gut, wenn du immer den selben gehen musst
weil du nicht mehr kennst. Also such mit nach deinem eigenen Weg.
Danke Euch soweit. Das weiß ich allerdings schon alles. :-)
Dann frage ich mal konkreter. Benötige ich bei der Midi Programmierung
spezielle #include <.......> Bibliotheken?
Wie würdet ihr beim LPC 935 eine exakte Baudrate von 31250 Baud
einstellen.
Muss ich dazu einen externen Taktgeber verwenden oder tut es auch noch
der Interne vom LPC?
In der Betriebsart 1 sind 8 bit UART mit variabler Baudrate einstellbar.
Ich würde die 31250 Baud gerne über den Timer umsetzen.
Ich weiß, dass es da eine Formel zur Berechnung gibt.
Wisst ihr diese?
Danke für Eure Hilfe und Tipps
Hallo Joachim,
nein da gibt es nichts.
Wenn ich solche Infos hätte und diese auch geben würde wäre ich nicht
hier im Forum. Deshalb bin ich auf eure Hilfen und Tipps angewiesen.
Schlagzeuger du scheinst keine große Ahnung von der Programmierung eines
LPC900 (8051er) Controllers zu haben. Am besten lernst du erst mal die
grundsätzliche Programmierung von 8051 Controllern im allgemeinen und
dann der LPC900 im speziellen.
Auf der Webseite www.c51.de gibt es ein paar gute Codebeispiele für
diverse Funktionen speziell für LPC900 Controller. Dort gibt es auch ein
paar passende Bücher zu kaufen, falls du mit Web-Tutorials nicht zurecht
kommst.
Ciao,
Rainer
Hallo Rainer,
danke für den Tipp.
Das Buch Keil C51 / Philips LPC900 hab ich sogar und bringt mir in der
MIDI Programmierung überhaupt nichts.
Also ahnungslos bin ich nicht.
Aber das momentane Wissen bringt mir nichts für die Ansteuerung einer
Midi Schnittstelle.
Wenn du so ein gebaltes Wissen hast dann schreib mir doch mal konkrete
Fakten wie ich diese Dinge in meine C Programmierung einbauen kann:
1) note on
2) note off (Abschaltung muss erfolgen sonst Dauerton)
die beiden Befehle am besten im running Modus um Bits und Bytes zu
sparen
3) einen festen Midi Notenkanal von 10
4) eine feste Velocity (Lautstärke)
5) eine variable Tonhöhe von 0 bis 127 (entspricht meiner
Percussionauswahl)
Vielleicht schafft ja du es. Ich wäre dir dankbar.
MfG
Tim
Also wenn du dieses Buch hast, in welchem die komplette Hard- und
Software der LPC900 Familie inklusive deren Programmierung beschrieben
wird, und trotzdem nicht weisst, wie du anfangen sollst, dann brauchst
du einfach etwas mehr Übung. :)
Fang mit etwas einfacheren Testprogrammen erst mal an und arbeite dich
dann heran. Ich habe ebenfalls dieses Buch und habe viele verschiedene
Testprogramme damals geschrieben gehabt (zu finden unter [1]) um die
einzelnen hardware Features zu testen.
Du solltest vorab auch überlegen, ob du die Midi Schnittstelle mit Hilfe
des integrierten UART oder über bit-banging der Pins realisieren willst.
Sobald du dann eine Implementierung der Schnittstelle hast ist der
weitere Weg nur noch Software.
Nachdem du bisher aber noch nicht mal einen Anfang von eigenem Code
gezeigt hast bin ich nicht bereit von Null auf diesen für dich zu
schreiben. Aber ich helfe dir gerne, wenn du an gewissen Punkten nicht
weiter kommst. :)
Ciao,
Rainer
[1] https://quakeman.homelinux.net/viewvc/uVision/trunk/
Hallo Rainer,
danke für deine Unterstützung.
Übung macht bekanntlich den Meister.
Ich habe vor die integrierte UART zu verwenden.
Bei Midi muss eine Baudrate von 31250 Baud eingestellt werden.
Ich würde das gerne über die Betriebsart 1 umsetzen, weil der Timer mit
dem TH1 SFR berechnet werden kann und so eine exakte Baudrate von 31250
Bauds erzeugt werden kann.
Die Betriebsart 1 bedeutet: 8 bit UART mit variabler Baudrate.
Genau das brauch ich. Die Stop und Start Bits kommen von der UART selber
diese müssen nicht programmiert werden.
Die CCLK ist der RC-Oszillator. Vermutlich der interne Taktgeber von
7,3738 MHz?
1 PLCK = 2 CCLK.
CCLK = OSCCLK / (DIVM * 2)
Im Buch auf der Seite 197 steht unter Abb 163. eine Formel zur
Berechnung der Baudrate für den Timer 1 in Betriebsart 2.
Irgendwie gibt es für die Betriebsart 1 keine Formel.
Wird ein externer Quarz beschalten so läuft es laut Blockschaltbild über
das DIVM Register. Hier wird der hohe Takt heruntergeteilt.
Soll zur Baudrate von 31250 Baud ein externer Quarz oder der intere RC
Oszillator verwendet werden?
Welche Formel muss ich verwenden?
Da werd ich mit dem Buch absolut nicht schlau.
Rainer kannst du mir da bitte weiterhelfen.
Danke Tim
Hallo Rainer,
hab noch etwas vergessen.
Letzten endlich würde ich somit eine RS-232 Schnittstelle mit 8 Bit und
31250 Bauds haben, die allerdings am PIN 18 nur "Datenströme" sendet.
Ich muss hier keine Pegelanpassung machen, da ich mit dem TX eine
Konstantstromquelle von 5mA ein und ausschalten lasse.
RX benötige ich gar nicht, da keine Steuerdaten vom Synthesizer
zurückkommen lasse.
Bei Midi sind Spannungen uninteressant, da diese auf Ströme reagiert.
Die Midi Schnittstelle arbeitet als Stromschleife. "Strom an" bedeutet
logisch "0".
Ist am TX ein low Signal dann liefert die Konstantstromquelle 5mA an den
Midi IN Eingang des Synthesizers.
Ich verwende auch deshalb nicht irgendeine Stromquelle, sondern eine
Konstantstromquelle. Die liefert immer 5mA konstanten Strom auch wenn
das Kabel 15 Meter hat.
Aus Recherchen hat sich ergeben, dass diese Optokoppler bereits bei 5mA
ansprechen müssen.
Ich verwende diese Konstantstromquelle auch als Überstromschutz, damit
der Optokoppler am MIDI In Eingang des Synthesizers nicht kaputt geht.
Als Synhtesizer soll ein Roland TD-8 Soundmodul dienen.
Das wars von mir. Rainer jetzt bin ich wieder auf deine Hilfe
angewiesen.
Danke
Ich möchte dich jetzt noch etwas fragen.
Hast du schon mal etwas mit MIDI gemacht bzw. programmiert?
Benötige ich bei der C Programmierung eventuell exotische include
Dateien, damit der meine Midi-Befehle der Synthesizer angesprochen wird?
Hab da schon etwas gesehen, aber nicht in Verbindung mit einem
Mikrokontroller.
So warte ich erst mal ab bis zu mir wieder etwas antwortest.
Wäre gut möglichst bald wieder etwas von dir oder von euch zu hören.
Danke
Anregungen und Tipps neheme ich gerne entgegen.
> Ich weiß,> Ich weiß wie der Hex-Code aufgebaut ist und ich versteh diesen auch.> Das weiß ich allerdings schon alles. :-)> Ich weiß, dass es da eine Formel zur Berechnung gibt.
und
> Welche Formel muss ich verwenden?
passen nicht wirklich zusammen.
> Anregungen und Tipps neheme ich gerne entgegen.
Mein Tipp: Behaupte nicht, dass du schon alles weist. Immerhin hast du
mit sehr einfachen Dingen (Formel ableiten, Baudratengenerator
initialisieren) enorme Probleme, da wäre etwas mehr Demut sicher
hilfreich.
> So warte ich erst mal ab bis zu mir wieder etwas antwortest.> Wäre gut möglichst bald wieder etwas von dir oder von euch zu hören.> Wenn du so ein gebaltes Wissen hast dann schreib mir doch mal konkrete> Fakten wie ich diese Dinge in meine C Programmierung einbauen kann:
Niemand hier muss dir antworten, also sei nicht so altklug und fordernd,
sonst wird das nichts. Kein Mensch ist hier auf dein Projekt angewiesen,
aber dein Projekt anscheinend auf die Menschen hier, weil du es allein
nicht stemmen kannst. Denk mal drüber nach.
Gruß,
Edson
...
Warum das Rad neu erfinden ?
Wenn du schon alles weißt, kennst du bestimmt auch diese Seite ?
http://www.megadrum.info
Ich hoffe der Link geht in Ordnung, ansonsten bitte löschen.
Bege
Hallo Edison,
weiß bedeutet bei mir sicher nicht allwissend sonst wäre ich nicht hier.
Sondern ich bin darüber informiert, nur fehlt mir die Praxis zur
Umsetzung, deshalb bin ich teilweise etwas unsicher. Ich bitte um
Entschuldigung, wenn ich den falschen Ton gewählt habe. Ich bin unter
Zeitdruck und ich bekomme hier manchmal Antworten, die mir nicht
hilfreich sind.
Weißt du, ob ich die Baudrate von 31250 Baud mit dem internen oder doch
eher mit einem externen Quarz erzeugen soll?
Welche Formel würdest du denn nehmen? (evtl. Seitenangabe Buch)
Edison was du am Schluss geschrieben hast gebe ich dir vollkommen recht.
Ich bitte dich, dass du mich nicht verurteilst, nur weil du mich evtl.
mißverstehst und nicht persönlich kennst.
Ich hoffe auf gute Zusammenarbeit.
Danke für deine kompetente Unterstützung.
Also die Formeln auf Seite 197 Unten (Abb. 163/164) beschreiben die
Berechnung für die Baudrate oder den Reloadwert für Modus 1 und 3 des
Uart.
Wenn man nun von dem internen 7,3728MHz Takt ausgeht kommt man mit
Timer1 auf folgende mögliche Baudraten:
Benötigter Reloadwert bei SMOD1=0
TH1=248,7
Möglicher Reloadwert
TH1=249 -> 32914Bps
TH1=248 -> 28800Bps
Benötigter Reloadwert SMOD1=1
TH1=241,4
Möglicher Reloadwert
TH1=241 -> 30720Bps
TH1=242 -> 32914Bps
Diese liegen deutlich daneben. Aber wenn du den internen
Baudratengenerator benutzt kommst du auf sehr gute Werte:
Benötigter Reloadwert
BRGR=218,06
Möglicher Reloadwert
BRGR=218 -> 31507Bps
Diese Abweichung beträgt gerade mal 0,02% und ist innerhalb der
Toleranzen für eine asynchrone Übertragung.
Bezüglich deiner Frage der Include Dateien solltest du nichts besonderes
benötigen. Du brauchst für dein Programm nicht mehr als die Controller
SFR Definitionen. Den Rest musst du sowieso selber programmieren, da es
keine fertige Midi Bibliotheken für den Controller gibt (zumindest kenne
ich keine).
Ich habs selber bisher noch nichts mit Midi gemacht, aber nach deiner
Beschreibung ist es ja nur gering unterschiedlich zu einer standard
RS232 Übertragung. :)
Ciao,
Rainer
Hallo Rainer,
die Formel auf der Seite 197 hat anscheinend einen Fehler, weil
auf der Seite 198 bei einer Baudrate von 28800 Bauds ein TH1 von 0x04
also 4hex -> 4dez heraus kommt.
Lässt man bei der Formel in Abb. 163 die 256 weg stimmen die Werte wie
auf der Seite 198.
Ich würde sehr gerne einen externen Quarz auf XTAL1 (Pin8) und XTAL2 auf
den LPC(Pin9) hängen.
Durch meine Recherche habe ich herausgefunden, dass bei Midi 12MHz ideal
ist. Der OSCCLK Spanne beim LPC liegt zwischen 20kHz bis 20 MHz. Liegt
also noch im machbaren Bereich.
Welche Formel kann ich beim externen Taktgeber anwenden?
Wenn der Takt über das DIVM Register läuft kann die UART dann in der
Betriebsart 1 (8 bit mit variabler Baudrate) verwendet werden?
Stimmt die Midi basiert auf der RS-232 Schnittstelle. Nur halt mit dem
Unterschied, dass Midi stromgesteuert und die RS-232 spannungsgesteuert
ist.
Gedanken für eine Pegelanpassung muss ich mir hier schon mal nicht
machen.
Hast du eine Idee wie ich meine Midi Messages (note on, note off,
velocity, Tonhöhe) in meine Funktionen bzw. Unterprogramme einarbeiten
kann.
Beim Ausschalten durch den "note off" Befehl ist eine gewisse Delay
notwendig bis der Synthesizer reagiert. Sonst fühlt er sich gar nicht
angesprochen. Das könnte dann mit einer Zeitschleife umgesetzt werden.
-> Weiß einer von Euch hier evtl. diese Zeit wielang diese sein muss?
Wenn durch die externe 12MHz keine 31250 Baud einstellbar sind.
Dann ist die Baudratenerzeugung noch sinnvoller als der Timer.
Deine Möglicher Reloadwert von BRGR=218 -> 31507Bps versteh ich nicht
ganz.
Verwende ich die Tabelle (Baudratengenerator) Seite 198
so steht bei
Baudrate BRGR0 Dezimalwert(BRGR0)
28800 0xF0 240
38400 0xB0 176
BRGR1 ist ab 28800 Baud = 0
Die BRGR1 muss also bei höheren Baudraten in der Berechnung nicht
berücksichtigt werden?
Könntest du bitte mal vorrechnen wie du auf die 218 gekommen bist. Danke
Gibt es da ein Dokument oder einen Internetlink wo steht wie hoch die
Abweichung sein darf?
Danke Euch allen, Danke dir Rainer
> Wenn man nun von dem internen 7,3728MHz Takt ausgeht kommt man mit> Timer1 auf folgende mögliche Baudraten:
Stimmt fasst, da ist dir beim Abschreiben ein kleiner Fehler
unterlaufen.
Der RC- Oszillator hat 7,3738 MHz.
> Diese Abweichung beträgt gerade mal 0,02% und ist innerhalb der> Toleranzen für eine asynchrone Übertragung.
Hast du mir dazu ein Dokument oder einen Link.
Danke dir
Hi,
also zuerst muss ich meine vorherige Berechnungen korrigieren. Denn bei
der Berechnung für Timer1 habe ich CCLK und nicht PCLK in der Formel
verwendet gehabt. Dadurch ändern sich die Werte bei internem Takt.
Richtige Werte bei internen 7,3728MHz Takt:
Benötigter Reloadwert bei SMOD1=0
TH1=252,34
Möglicher Reloadwert
TH1=253 -> 38400Bps
TH1=252 -> 28800Bps
Benötigter Reloadwert SMOD1=1
TH1=248,68
Möglicher Reloadwert
TH1=249 -> 32914Bps
TH1=248 -> 28800Bps
Die Formeln auf Seite 197 sind korrekt und in der Tabelle auf Seite 198
hat er wohl das TH1=256-... vergessen. Denn die Formeln sind identisch
mit den Formeln im Datenblatt des Herstellers. Das macht auch Sinn, wenn
man bedenkt, dass Timer1 hier im Modus 2 läuft. Dabei arbeitet er im
auto-reload Modus und zählt hoch. Also ein größerer Reloadwert erzeugt
auch einen höheren Takt, da der Abstand zu 256 geringer wird.
So nun zu dem Baudratengenerator. Dieser besitzt ein 16Bit Register zum
auto-reload, wodurch deutlich mehr Abstufungen möglich sind, und zählt
herunter (im Gegensatz zum Timer1). Mit der zweiten Formel in Abb.164
Auf S.197 rechnest du den nötigen Reloadwert aus:
BRGR = 7,3728MHz/31500 - 16 = 218,05...
Mit der ersten Formel bestimmst du dann die tatsächlich erreichte
Baudrate:
Baudrate = 7,3728MHz/(218 + 16) = 31507,7Bps (0,02% Abweichung)
Wenn du nun z.B. einen externen 12MHz Quarz verwenden willst berechnest
du es auf die gleiche weise.
1. BRGR = 12MHz/31500 - 16 = 364,95...
2. Baudrate = 12MHz/(365 + 16) = 31496,06Bps (0,0125% Abweichung)
Also würde ein 12MHz Quarz ebenfalls gut funktionieren. Bedingt durch
die deutlich höhere Genauigkeit des Quarzes im Gegensatz zum internen RC
Oszillator hättest du damit ein besseres Ergebnis.
Und die Uart kann, egal von welchem Takt ausgehend, immer verwendet
werden. Der Takt wird auch immer durch DIVM (default 1) geteilt.
Bei der RS232 liegt die maximal erlaubte Abweichung der Baudrate bei ca.
2%. Und wenn Midi ebenfalls 8N1 benutzt sollte die maximale Abweichung
im gleichen Bereich liegen. Und mit 0,0125% Abweichung liegst du da weit
drunter. :)
Ciao,
Rainer
Schön wäre schon, wenn man mit dem externen Quarz exakt auf die 31250
Baud kommen könnte.
Wenns technisch nicht geht kann ich die Berechnung für den
Baudratengenerator nachvollziehen.
(CCLK = 7,3738 MHz)
Baudrate = (CCLK) / (BRGR1 * 256 + BRGR0 + 16 )
= (7,3738 MHz) / ( 0 * 256 + 220 + 16 )
= 7,3738 MHz / 236
Baudrate = 31244,91 Bauds
Somit kommt nur eine Abweichung von 5 Bauds zustande was 0,016%
entspricht.
Gibst du mir da recht Rainer?
Bei einer so geringen Abweichung bräuchte ich dann auch keinen 12 MHz
Quarz mehr.
Ich hab das auch deshalb vorgerechnet, damit andere User das bei ihren
Problemen verwenden können.
Auf der Seite 199 ist ja ein Quellcode eine UART in der Betriebsart 1
dargestellt.
Muss jetzt dann nur noch das SBRGS auf 1 gesetzt werden, damit der
Baudratengenerator verwendet wird und das BRGEN auf 0 gesetzt werden?
Ich schreib einfach mal einen Code, der wahrscheinlich nicht ganz
richtig ist.
$NOMOD51 //vergisst die alten C51 Symbole beim Assembler
#include <REG935.H>
sbit sbLatch = P0^2;
// Port P0.2 setzt ein Bit am sbLatch, was ist sbLatch?
main ( )
{
P1M1 = 0x00;
P1M1 = 0x00;
P1 = 0x0F;
SCON = 0x40; //Betriebsart 1 setzen
ES = 1; // Interrupt freigeben
EA = 1;
orl BRGCON, #0x02; // Baudratengenerator durch gezieltes setzen
verwenden
orl BRGCON, #0x01; // Aktivierung des Baudratengenerators
SBUF = 0x49;
while (1);
}
Wie kann ich jetzt das BRGR1 SFR auf DC (220dez) setzen, damit eine
Baudrate von 31244,91 Bauds zustande kommen?
Könntet ihr/du den Quellcode bitte korrigieren.
Danke
Hallo Rainer,
könntest du mir die Seite des Datenblattes (P89LPC933_934_935_936) sagen
wo man die Formel sehen kann.
Den Rest kann ich soweit jetzt alles nachvollziehen, nur mit meinem
Quellcode bin ich mir noch etwas unsicher.
Danke für deine/eure Hilfe
Hi Rainer,
eins muss ich dir noch mitteilen die Midi-Schnittstelle hat nicht 31500
Baud, sondern 31250 Baud.
Dank deines Tipps kann mit dem Baudratengenerator eine exakte Baudrate
von 31250 Baud erzeugt werden.
CCLK = externer Quarz von 12 MHz
Baudrate = (12MHz) / (368 + 16) = 31250 Baud
Besser geht es nicht mehr :-)
Jetzt hab ich noch das Problem wie ich den (386dez) 170hex in den
Quellcode hineinbringe?
Ich glaube, die 170hex kann ich gar nicht in den Quellcode
implementieren, da auf der Seite 198 das BRGR1 nur 2 Hexstellen
aufweist.
Das sind 8 Bit. Bei 170hex wären es max. 12 Bit schon.
SFR Register kann ich von 0x80 bis 0xFF adressieren. Diese haben maximal
leider nur 8 Bit mehr geht leider nicht.
Also muss ich beim internen RC-Oszillator mit einem BRGR1 SFR auf DC
(220dez) bleiben.
16 Bit hat beim LPC nur das codesegment cseg at 0x0000.
Alles andere ist nur mit max. 8 Bit adressierbar.
Bye
Hi,
habs eben auch gesehen, dass die Baudrate ja gar nicht 31500 sondern
31250 ist. Naja, die Formeln bleiben aber trotzdem die gleichen. :)
Die Formel zur Berechnung findest du im "User Manual" (und nicht
"Datasheet") auf Seite 72/73.
Der Reloadwert von 368 bei 12MHz passt wirklich genau für 31250Bps. Beim
internen RC Oszillator müsstest du 220 benutzen, womit du auf 31240,7Bps
(0,03% Abweichung) kommen würdest. Aber dabei musst du immer bedenken,
dass der interne RC Oszillator nur bis auf ~1% genau ist im Gegensatz zu
einem extern Quarz.
Wegen des Problems, dass die Zahl den 8Bit Rahmen sprengt solltest du
eigentlich verstanden haben, dass es einige 16Bit Register im Controller
gibt. Diese bestehen immer aus zwei zusammengehörigen 8Bit Registern.
Beim Baudratengenerator sind dies BRGR1 (High Byte) und BRGR0 (Low
Byte). Wenn du nun 0x0170 (368dec) in das 16Bit Register BRGR schreiben
willst teilst du das in zwei 8Bit Werte auf und setzt BRGR1=0x03 und
BRGR0=0x68.
Dein Beispielcode müsste noch um das Setzen von BRGR erweitert werden
und ES=1 sowie EA=1 aktiviert den Interrupt, welchen du aber nicht
abfängst. Also zum Test ohne diese beiden Zeilen.
Ciao,
Rainer
Noch etwas, in deiner Rechnung benutzt du 7,3738MHz, aber es sind
7,3728MHz. ;)
Und die Codezeile "sbit sbLatch = P0^2" bewirkt nur, dass du in deinem
Programm für Portpin P0.2 ein Synonym namens "sbLatch" benutzen kannst.
Das macht den Code einfach nur leserlicher, hat sonst aber keine andere
Auswirkung.
Und hier ein kurzes Codebeispiel um die Uart mit dem internen
Baudratengenerator zu betreiben:
Hallo Rainer,
ich hab die 7,3738 MHz verwendet, weil es so auf der Seite 187 steht.
Im Datenblatt auf der Seite 24 von 77 heißt es:
RCCLK — The internal 7.373 MHz RC oscillator output.
In der user manuell auf der Seite 137 von 149 heißt der internal RC
oscillator, 7.373 MHz ± 2.5 %.
Nur im Blockschaltbild user manuel auf der Seite 28 von 149 sieht man
einmal die Frequenz von (7.3728 MHz ±1 %).
Letzten endlich ist die Abweichung so gering, dass das nichts mehr
ausmacht.
Wird der externe Quarz von 12 MHz verwendet ist der interne RC
Oszillator sowie unwichtig.
Die Formel zur Berechnung in der user manuel heißt dort wie siehe
Tabelle.
In unserem Buch verwenden die in Abb. 163, jedoch die PCLK.
In der < siehe Tabelle> ist von der PCLK gar keine Rede. Dort verwenden
sie immer die CCLK.
Immerhin ist die PCLK die Hälfte der Frequenz von CCLK.
Wer hat hier einen Fehler gemacht?
Kann man beim Bandratengenerator das einfach so hinschreiben:
BRGR0 = 0xF0;
BRGR1 = 0x02;
Hast du mir da eine Seite im Buch?
Ich hab leider nichts gefunden.
Das High und Low Bit beim BRGR macht Sinn.
Kann man die 368dez so einfach aufteilen wie BRGR1=0x03 und
BRGR0=0x68?
Danke vielmals
Schlagzeuger schrieb:> Hallo Rainer,> ich hab die 7,3738 MHz verwendet, weil es so auf der Seite 187 steht.> Im Datenblatt auf der Seite 24 von 77 heißt es:> RCCLK — The internal 7.373 MHz RC oscillator output.>> In der user manuell auf der Seite 137 von 149 heißt der internal RC> oscillator, 7.373 MHz ± 2.5 %.> Nur im Blockschaltbild user manuel auf der Seite 28 von 149 sieht man> einmal die Frequenz von (7.3728 MHz ±1 %).
Ich denke, 7,3728MHz ist richtig und 7,373MHz wird meistens als Näherung
geschrieben. 7,3738MHz ist wohl ein Schreibfehler (wovon leider etliche
im Buch drin sind).
> Die Formel zur Berechnung in der user manuel heißt dort wie siehe> Tabelle.> In unserem Buch verwenden die in Abb. 163, jedoch die PCLK.> In der < siehe Tabelle> ist von der PCLK gar keine Rede. Dort verwenden> sie immer die CCLK.>> Immerhin ist die PCLK die Hälfte der Frequenz von CCLK.> Wer hat hier einen Fehler gemacht?
Da haben beide Recht. Der kleine aber feine Unterschied liegt im Teiler,
der ebenfalls angepasst wurde. Im Buch sind es 16/32 mit PCLK und im
Datenblatt 32/64 mit CCLK. Das kommt dann auf das gleiche heraus. :)
> Kann man beim Bandratengenerator das einfach so hinschreiben:> BRGR0 = 0xF0;> BRGR1 = 0x02;> Hast du mir da eine Seite im Buch?> Ich hab leider nichts gefunden.
Genau so schreibst du die hex Zahl 0x2F0 in das 16Bit Register. Das sind
allgemeine Grundlagen, wie man mit hexadezimalen Zahlen arbeitet. Ich
glaube, dass steht so nicht direkt im Buch drin und wird als Wissen
vorausgesetzt. ;)
> Das High und Low Bit beim BRGR macht Sinn.> Kann man die 368dez so einfach aufteilen wie BRGR1=0x03 und> BRGR0=0x68?
Nein, denn dezimale Zahlen lassen sich nicht einfach aufteilen. Das geht
nur mit hexadezimalen Zahlen. Also du müsstest 368dez in 0x170 (0x am
Anfang markiert immer eine hex Zahl) umwandeln und das dann in 0x01 und
0x70 aufteilen.
Ich würde dir empfehlen dich etwas in die Arbeitsweise mit hexadezimalen
Zahlen einzulesen, denn da wirst du bei der Programmierung kaum herum
kommen und solltest das aus dem FF können.
Ciao,
Rainer
Danke Rainer,
ich kann jetzt alles nachvollziehen.
Hab etwas zu komplziert gedacht, sorry.
Das versteh ich hier noch nicht ganz:
// RXD Pin P1.1 Quasi-bidirectional und TXD Pin 1.0 Push-Pull
konfigurieren
P1M1 = P1M1 & 0xFC;
P1M2 = P1M2 | 0x01;
Warum ist empfangen quasi bidirektional
und senden auf push pull?
Ich bräuchte in meinem Fall doch nur TXD, weil keine Mididaten empfangen
werden.
// Ser0: Mode=1 REN=1
SCON = 0x50;
REN könnte ich 0 machen also sperren, weil ich nichts empfange?
Was SCON und ES ist habe ich bis jetzt im Buch nicht gefunden.
Hast du einen Seitentipp.
Danke
Hallo Rainer,
SCON bedeutet Auswahl der Betriebsarten von 0 bis 3 (serial port
control)
Wenn man die Betriebsart 1 haben möchte muss SM0 = 0; und SM1 = 1 sein
das bedeutet, dass das SCON
0100 0000 haben muss => 0x40 für Betriebsart 1
der Code könnte dann bei 12MHz so aussehen:
#include <REG935.H>
main ( )
{
P1M1 = P1M1 & 0xFC; // noch unklar weshalb
P1M2 = P1M2 | 0x01; // noch unklar weshalb
SCON = 0x40; //Betriebsart 1 setzen
BRGR0 = 0x70;
BRGR1 = 0x01;
BRGCON = 0x03;
ES = 1; // sagt mir nichts
EA = 1; // Interrupt freigeben
SBUF = 0x49; // Wozu braucht man den Datenpuffer und warum 0x49?
while (1); // was macht die Dauerschleife hier
}
jetzt fehlt nur noch der eigentliche Interrupt,
da muss ich doch bei mir nur den Serial Port TX Interrupt verwenden?
Ich weiß jetzt nicht wie in den einbauen soll?
Danke
Hallo Rainer,
SBUF habe ich jetzt doch noch gefunden.
Der serielle Buffer enthält das empfangene bzw. das zu sendende Zeichen
für die serielle Schnittstelle.
Weshalb steht der auf SBUF auf 0x49?
Die 0x49 ist doch in diesem Fall eine Adresse?
Aber weshalb gerade diese wie kommen die da drauf?
Danke dir
bye
Das mit dem quasi-bidirectional und push-pull musst du an deinen Fall
anpassen. Du brauchst nur TXD, als kannst du die Konfiguration von RXD
weglassen. Und ob der Ausgang push-pull oder quasi-bidirektional
konfiguriert ist macht meistens keinen Unterschied. Push-pull hat eben
mehr Leistung gegen logisch 1 (siehe Beschreibung der verschiedenen
Modes im Buch oder Datenblatt).
Der Wert 0x49 in SBUF ist nur ein Beispiel, wie du diesen Wert über die
RS232 sendest. Er hat keine spezielle Bedeutung.
ES=1 aktiviert den Interrupt für den Uart. Wird nur in Zusammenhang mit
EA=1 benötigt. Um den Interruptbetrieb zu verstehen solltest du im Buch
das Kapitel und die Beispielprogramme dazu mal durcharbeiten.
while(1) bewirkt nur eine Endlosschleife nach dem Senden von 0x49, da
ansonsten das Programm danach bis zum Ende des Programmspeichers laufen
würde und dann wieder von vorne anfängt. Dies bewirkt dann aber ein
unvorhersagbares Verhalten deines Programms. Das gehört dann schon
wieder zum Grundwissen, wie man überhaupt ein Programm erstellt.
Eigentlich hättest du viele deiner Fragen dir selber beantworten können,
wenn du das Buch von Anfang bis Ende durchgelesen und die Beispiele
angeschaut hättest. Da wird das alles nämlich erklärt und mit
Beispielprogrammen behandelt. ;)
Ciao,
Rainer
Da gebe ich dir recht. Nur wie du siehst bin ich teilweise noch sehr
unsicher und so bekomme ich von einem Erfahreren ein Feedback.
Probleme und Verständnis sind dann das eine.
Von dem her bin ich dir sehr dankbar für deine Hilfe und Unterstützung.
Schlagzeuger schrieb:> hast du eine Idee wie ich die Baudrate mit dem Oszi messen kann?
Wenn du eine Bitfolge wie z.B. 0xAA (10101010) sendest hast du nach
jedem Bit einen Wechsel und du kannst mit dem Oszi die Zeit zwischen den
Flanken messen. Damit kannst du es dann ausrechnen.
Okay,
wenn ich soweit bin werde ich es dir dann sagen.
Bis mein Tastenschlagzeug läuft werden noch ein paar Wochen vergehen.
Ich danke dir/ euch für eure Unterstützung.
Danke
Tim
Hallo Rainer,
es wäre nett, wenn wir in Kontakt bleiben könnten.
Mich kannst du auch unter tastenschlagzeug@gmx.de erreichen.
Es wäre schön, wenn du von mir auch eine Mail zukommen lässt.
Danke
Also solange es sich um dein Projekt handelt sollten wir das lieber über
das Forum hier machen. So können eventuell andere auch noch davon
profitieren. :)
Natürlich find ich in Ordnung.
Schaust am besten jeden Tag hier mal rein.
Mit der Mail wollte ich nur bezwecken, dass der Kontakt nicht abreißt.
So ist es auch vollkommen in okay.
Danke
Hallo,
vielleicht klingt das jetzt popelig. Aber nachdem ich mehrere Jahre ein
Drum to Midi Projekt nicht fertiggestellt habe und irgendwann eigentlich
nur einen Fußtaster brauchte, der mir den Drumsound eines Synthis
abspielt, bin ich pragmatisch geworden. Ich habe einfach ein billiges
Midi-Masterkeyboard genommen und an die untersten zwei Tastenkontakte
Fußtaster gelötet (Schließer, natürlich nett mit Klinkenbuchse und
so...) Jetzt kann ich mit den Füßen zwei Drumsounds spielen und die
restlichen Tasten sogar noch mit irgendeinem Solosound belegen.
Ansonsten möchte ich noch auf die Firma Doepfer verweisen...
Gruß,
Jens
ich wollte damit nur sagen, dass ich von Grundauf etwas selber bauen
möchte und keine Bausatz kaufen möchte, so verstehe ich das
Mikrocontroller programmieren und die Midi besser.
Es ist ein Projekt, dass ich mir selber gesetzt habe. Von daher hoffe
ich, dass in ein paar Wochen den ersten Ton hören kann, wenn der Taster
gedrückt wird.
Hallo Rainer,
hab mal einen funktionierenden Synthesizer ausgemessen, siehe dazu die
Oszillogramme.
Von links beginned kann man als erstes das Startbit dann den Midikanal
(1-15)Stoppbit sehen.
Danach dann gleich wieder ein Starbit dann folgen die Bits der
Midinotennummer, was der Percussionauswahl entspricht (0-127)und endet
mit einem Stoppbit. Als letztes folgt wieder ein Startbit dann die Bits
der Velocity, also der Lautstärke (0-127) und endet mit einem Stoppbit.
Wie man auf den Oszillgrammen erkennen kann beginnt das LSB eher links
und HSB dann rechts. Kannst du mir da zustimmen?
Es müssen über die UART 3x 8Bits an Daten laufen.
Da die UART ja nur 8 Bits auf einmal herausgeben kann, wo würdest du
sagen werden die restlichen Bits zwischengepseichert?
Etwa im Buffer der UART?
Kann man hier aus den Oszillogrammen eine Baudrate von 31250 Baud
ablesen?
Bye Tim
Schlagzeuger schrieb:> Hallo Zusammen,> ihr könnt neben dem dowonloaden der Osziollogramme auch gerne eure> Meinung zu meinem Beitrag geben.
Also solche Aussagen solltest du dir sparen. Damit machst du dir keine
Freunde, wenn man bedenkt, dass wir dir bei deinem Problem in unserer
Freizeit helfen. ;)
Nun zurück zu dem eigentlichen Thema.
Ich habe dein erstes Oszillogramm mal ausgewertet und es kommt genau das
heraus, was du auch schon vermutet hast. Das LSB ist das erste Bit und
das MSB das letzte Bit eines Bytes in der Übertragung. Ich habe das
erste Bild mal mit ungefähren Bitmarken versehen und man sieht dann
schön die einzelnen Daten.
Erstes Byte 10011111 = Befehl 9, Kanal 16
Zweites Byte 00000000 = Note 0
Drittes Byte 01111111 = Velocity 127
Bei 31250Bps ist ein Bit genau 32µs lang. Die Auflösung der Bilder
reicht zwar nicht aus um den Wert so genau zu bestimmen, aber man sieht,
dass es ungefähr in diesem Bereich liegen müsste.
Wenn du nun diesen Befehl senden willst, dann schickst du nacheinander
genau diese drei Bytes über die Uart heraus. Also erst 0x9F gefolgt von
0x00 und 0x7F. In deinem Programm prüfst du einach nach jedem Byte ob
der Sendevorgang fertig ist und schickst anschließend das nächste Byte
heraus.
Ciao,
Rainer
Danke soweit. Ich werde mir das zu Herzen nehmen was du mir gesagt hast.
Ich wollte allerdings nur Leute zum Schreiben animieren. Dass es eher
negativ bei dir/euch ankam tut mir leid. Sorry nochmals. In Zukunft
werde ich nur noch technische Fakten schreiben. Danke für eure
Unterstützung.
Danke dir Rainer für die Auswertung.
Schau das meinte ich, wenn man etwas praktisch macht, dann kann man es
besser nachvollziehen. Die Auswertung des Oszillogrammes habe ich nun
verstanden und die Baudrate von 31250 Baud kann man bis zu 33us genau
herauslesen.
Ich kann die 3x 8 Bits alle hineindander herausschicken und diese
zwischenzuspeichern?
Schlagzeuger schrieb:> Ich kann die 3x 8 Bits alle hineindander herausschicken und diese> zwischenzuspeichern?
Was meinst du mit zwischenspeichern?
In deinem Programm hast du z.B. ein Array, welches die drei Bytes
enthält.
1
unsignedcharbefehl[]={0x9F,0x00,0x7F};
Wenn du nun diesen Befehl senden willst machst du das in einer einfachen
Schleife.
1
unsignedchari;
2
3
for(i=0;i<3;i++){
4
TI=0;
5
SBUF=befehl[i];
6
while(!TI);
7
}
Natürlich würdest du später diese drei Bytes automatisch zusammenbauen
lassen und nicht statisch speichern. Aber das Beispiel zeigt, wie du
exemplarisch drei Bytes über die Uart schicken kannst.
Ciao,
Rainer
Hallo Rainer,
die Programmierung sitzt.
Habs schon mal simuliert laut uVision werden 3Bytes gesendet.
Hier mein Quellcode zum Senden eines Midistreams:
------------------------------------------------------------------------
#include <REG935.H>
void main ( )
{
unsigned char i, MIDIstream[ ] = {0x9F, 0x28, 0x7F};
/*Die UART sendet am Port PIN 1.0 (TXD) zum Synthesizer
den MIDI-Befehl "note-on" auf Kanal 15,
mit einer Midinotenummer von 40 dez welches einer
"Snare-Drum" Auwahl entspricht wie auch
mit einer maximalen Lautstärke von 127 dez. */
P1M1 = 0x00;
P1M2 = 0x00;
SCON = 0x40; // Auswahl Betriebsart 1; Bandbreite variable bei 8-Bit
BRGR0= 0x68; // SFR für ext. 12 MHz Quarz
BRGR1= 0x03; // SFR für ext. 12 MHz Quarz
//ENCLK= 0x00; // Bit muss bei extern deaktiviert sein Seite 143
TI = 0; //TI-Flag gelöscht ermöglich Sendevorgang
for ( i = 0 ; i < 3 ; i++ )
SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte
}
-----------------------------------------------------------------------
1) Muss das TI-Flag immer gelöscht werden? Die Stelle am Quellcode
passt?
2) Muss das nach Beendigung auch mal auf TI = 1 gesetzt werden?
3) Die Baudrate in uVision Simulation zeigt bei Peripherals -> unten
rechts generell eine Baudrate von 750000 an. Irgendwie stimmt das nicht
mit dem berechneten. Es sollten 31250 Baud dort stehen. Evtl. kann das
uVision gar nicht richtig kalkulieren. Keine Ahnung!
4)Wenn ein externer Quarz verwendet wird Seite 143 muss das Bit ENCLK
deaktiviert werden wie auch an XTAL2 soll ein Widerstand gebaut werden.
Kennst du dich da aus? Wie hoch soll den R sein?
5)da am Ausgang des LPC kein Last geschalten wird könnte eigentlich
alles auf quasi-bidirektional gestellt werden?
Wenn ich am Freitag dazu komme werde ich mal mit dem Oszi versuchen die
Baudrate zu messen. Heute konnte es zeitlich nur simulieren, da mein
Quellcode ein paar Tücken gehabt hat. Jetzt funktioniert dieser aber
ohne Fehler!
Danke für die Beantwortung meiner Fragen.
Schlagzeuger schrieb:> die Programmierung sitzt.> Habs schon mal simuliert laut uVision werden 3Bytes gesendet.
Nichts für Ungut, aber bei der Programmierung sitzt noch lange nichts
richtig. In deinem Beispielcode sind fünf Fehler drin.
1. Du hast versucht den dezimalen Reloadwert von 368 in zwei Bytes 0x03
und 0x68 aufzuteilen. Dies ist völliger Unsinn, was ich dir aber schon
in einem Post weiter oben erklärt hatte. Du musst die Zahl in
hexadezimale Darstellung umwandeln, was 0x170 ergibt. Und diese Zahl
kannst du dann in 0x01 und 0x70 für high und low Byte aufteilen.
2. Du hast vergessen das Register BRGCON zu beschreiben um den
Baudratengenerator überhaupt zu starten, wodurch die Uart gar nicht
arbeitet.
3. Du setzt das TI Flag nur einmal vor der Schleife zurück und nicht
innerhalb.
4. Du fragst das TI Flag innerhalb der Schleife gar nicht ab bevor du
ein neues Byte sendest. Dadurch würde der Sendevorgang des vorherigen
Bytes abgebrochen werden.
5. Du hast am Ende keine Endlosschleife um dein Programm nach dem Senden
in einem definierten Zustand zu halten. Ohne diese würde das Programm
bis zum Ende des Flash durchlaufen und wieder von vorne anfangen, was zu
unvorhersehbarem Verhalten führt.
Hier mal eine korrigierte Version. Und ENCLK brauchst du nicht zu
verändern, da es default deaktiviert ist.
1
#include<REG935.H>
2
voidmain()
3
{
4
unsignedchari,MIDIstream[]={0x9F,0x28,0x7F};
5
/*Die UART sendet am Port PIN 1.0 (TXD) zum Synthesizer
6
den MIDI-Befehl "note-on" auf Kanal 15,
7
mit einer Midinotenummer von 40 dez welches einer
8
"Snare-Drum" Auwahl entspricht wie auch
9
mit einer maximalen Lautstärke von 127 dez. */
10
11
P1M1=0x00;
12
P1M2=0x00;
13
SCON=0x40;// Auswahl Betriebsart 1; Bandbreite variable bei 8-Bit
14
BRGR0=0x70;// SFR für ext. 12 MHz Quarz
15
BRGR1=0x01;// SFR für ext. 12 MHz Quarz
16
BRGCON=0x03;
17
18
for(i=0;i<3;i++)
19
{
20
TI=0;//TI-Flag gelöscht ermöglich Sendevorgang
21
SBUF=MIDIstream[i];// Sendet pro Durchlauf 1 Byte
22
while(!TI);
23
}
24
25
while(1);
26
}
> 1) Muss das TI-Flag immer gelöscht werden? Die Stelle am Quellcode> passt?
Nein, siehe oben. :)
> 2) Muss das nach Beendigung auch mal auf TI = 1 gesetzt werden?
Nein, das macht die Uart automatisch nach jedem gesendeten Byte.
> 3) Die Baudrate in uVision Simulation zeigt bei Peripherals -> unten> rechts generell eine Baudrate von 750000 an. Irgendwie stimmt das nicht> mit dem berechneten. Es sollten 31250 Baud dort stehen. Evtl. kann das> uVision gar nicht richtig kalkulieren. Keine Ahnung!
Da BRGCON nicht richtig initialisiert wird kann auch keine korrekte
Baudrate angezeigt werden. Zweitens musst du schauen, dass in den
Projekteinstellungen die Quarzfrequenz auch auf 12MHz steht.
> 4)Wenn ein externer Quarz verwendet wird Seite 143 muss das Bit ENCLK> deaktiviert werden wie auch an XTAL2 soll ein Widerstand gebaut werden.> Kennst du dich da aus? Wie hoch soll den R sein?
Wie in der Beschreibung weiter unten steht, wird der Widerstand meistens
nur bei Frequenzen < 100kHz benötigt. Wegen dem ENCLK Bit steht im Buch
korrekterweise, dass dieses Bit deaktiviert bleiben und nicht
deaktiviert werden muss.
> 5)da am Ausgang des LPC kein Last geschalten wird könnte eigentlich> alles auf quasi-bidirektional gestellt werden?
Korrekt. :)
Ich würde dir empfehlen im Buch das Kapitel 8 und 9 mal durchzuarbeiten.
Denn deine Fehler im Programm zeigen, dass du noch ein paar Defizite im
Verständnis der C-Programmierung hast. Und die Codebeispiele im Kapitel
10 zu der Peripherie im Controller sind auch sehr nützlich beim
Verständnis der hardware nahen Programmierung.
Ciao,
Rainer
Hier mal eine korrigierte Version. Und ENCLK brauchst du nicht zu
verändern, da es default deaktiviert ist.
#include <REG935.H>
void main ( )
{
unsigned char i, MIDIstream[ ] = {0x9F, 0x28, 0x7F};
/*Die UART sendet am Port PIN 1.0 (TXD) zum Synthesizer
den MIDI-Befehl "note-on" auf Kanal 15,
mit einer Midinotenummer von 40 dez welches einer
"Snare-Drum" Auwahl entspricht wie auch
mit einer maximalen Lautstärke von 127 dez. */
P1M1 = 0x00;
P1M2 = 0x00;
SCON = 0x40; // Auswahl Betriebsart 1; Bandbreite variable bei 8-Bit
BRGR0= 0x70; // SFR für ext. 12 MHz Quarz
BRGR1= 0x01; // SFR für ext. 12 MHz Quarz
Das hab ich leider vergessen
> BRGCON = 0x03;
for ( i = 0 ; i < 3 ; i++ )
{
TI = 0; //TI-Flag gelöscht ermöglich Sendevorgang
SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte
> while (!TI);
!TI bedeutet doch, dass TI gleich null ist könnte ich in der Bedingung
auch TI == 0 schreiben?
> }> while(1);
Eine while Schleife ist ja eine kopfgesteurte Schleife. In diesem Fall
ist sie immer wahr, weil die Bedingung auf true also 1 steht.
Das ist also eine Endlosschleife die nie beendet wird?
Also wenn die nicht da wäre würde das Programm beim Abblauf eventuell
Fehler machen bzw. unstabil laufen?
Das Programm kann doch gar nie aufhören, weil es immer auf den selben
Punkt springt. Ich versteh hier den Sinn der Programmierung nicht.
Beim C in Verbindung mit Mikrocontroller muss am Ende immer eine
Endlosschleife stehen?
> }
Dank dir bis bald mal wieder
Schlagzeuger schrieb:>> while (!TI);> !TI bedeutet doch, dass TI gleich null ist könnte ich in der Bedingung> auch TI == 0 schreiben?
!TI ist die gleiche Bedingung wie TI == 0.
Diese Kurzschreibweise geht generell nur bei bitadressierbaren Bits,
wenn du es auf == 0 oder != 0 prüfen willst.
>> while(1);> Eine while Schleife ist ja eine kopfgesteurte Schleife. In diesem Fall> ist sie immer wahr, weil die Bedingung auf true also 1 steht.> Das ist also eine Endlosschleife die nie beendet wird?> Also wenn die nicht da wäre würde das Programm beim Abblauf eventuell> Fehler machen bzw. unstabil laufen?> Das Programm kann doch gar nie aufhören, weil es immer auf den selben> Punkt springt. Ich versteh hier den Sinn der Programmierung nicht.> Beim C in Verbindung mit Mikrocontroller muss am Ende immer eine> Endlosschleife stehen?
Das Programm arbeitet ja Byte für Byte den Code im Flash ab. Also fängt
es mit den einzelnen Befehlen zur Initialisierung der verschiedenen SFR
an. Dann kommt es zur "for" Schleife und durchläuft diese genau drei
mal. Wäre danach keine Endlosschleife würde der Controller im Flash
Speicher einfach die nächste Adresse einlesen und abarbeiten. Und danach
wieder die nächste Adresse usw. Irgendwann ist er am Ende des Flash
Speichers angekommen und hat einen Überlauf, wonach er wieder bei
Adresse 0 im Flash startet. Nachdem du aber nach deinem Programm keine
Befehle im Flash definiert hast, kannst du auch nicht vorhersagen, was
dort eventuell drin steht und ausgeführt werden würde.
Du brauchst also irgend eine Endlosschleife in deinem Programm, welche
üblicherweise deine eigentlich abzuarbeitende Routine ausführt. In
diesem simplen Beispiel sollen ja nur einmal drei Bytes gesendet werden
und anschließend nichts mehr. Da reicht auch eine Endlosschleife die
ansonsten nichts mehr macht.
Ich hoffe, ich konnte das Problem damit halbwegs verständlich erklären.
:)
Ciao,
Rainer
danke dir habs glaub ich verstanden.
Ich habs so versanden: Durch die Endlosschleife am Schluss wird ein
gezielter Sprung immer wieder aufdieselbe Adresse durchgeführt.
Wäre das nicht kommt es wie du es gut erklärt hast zu einem Überlauf
bzw. zur Abarbeitung irgendwelcher Befehle im data Speicher.
Wenn man beim Mikrocontroller nun größere Programme schreibt können am
Ende dann gernell Endlosschleifen gesetzt werden?
Wie kann man Befehle im Flash definieren?
Wenn man dies macht könnte man eine Endlosschleife weglassen, weil dann
die Befehle im data Speicher bekannt sind.
Bis jetzt hast du alles gut erklärt. Danke vielmals.
Hi,
Wenn nichts abgeändert wird geht nichts ins SBUF!
Den Fehler hatte ich gestern schon, deshalb habe ich das abgeändert.
Abhilfe Vorschlage Varianten 1-4.
Das wichtigste habe ich zur späten Stund gestern noch vergessen, nämlich
das
Register BRGCON = 0x03;
Erst durch das 0x03 setzen der Bits wird der Baudratengenerator
verwendet (SBRGS) und der Baudratengenerator wird erst aktiviert
(BRGEN).
Hab jetzt mehrere Wege gefunden wo es geht:
Variante 1:
TI = 0;
for ( i = 0 ; i < 3 ; i++ )
{
TI = 0; //TI-Flag gelöscht ermöglich Sendevorgang
SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte
}
while(1);
}
Variante 2:
for ( i = 0 ; i < 3 ; i++ )
{
TI = 0; //TI-Flag gelöscht ermöglich Sendevorgang
SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte
TI = 1;
}
while(1);
}
Variante 3:
for ( i = 0 ; i < 3 ; i++ )
{
TI = 0; //TI-Flag gelöscht ermöglich Sendevorgang
SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte
while (TI == 1);
}
while(1);
}
Variante 4:
TI = 0;
for ( i = 0 ; i < 3 ; i++ )
{
SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte
}
while(1);
}
Welche Variante würdest du nehmen?
Die am wenigsten Speicher braucht z.B.: Variante 4.
Die zweite while Schleife kann man doch weglassen?
Wenn ich diese zweite while Schleife einbaue muss diese auf TI = 1
stehen, weil sonst würde immer auf Sendevorgang prüfen.
Jedoch nachdem das Byte versendet wurde sollte das Flag auf
Senderegister leer prüfen stehen. (Seite 194)
Wie du auf dem Screenshot sehen kannst kann die 31250 Baud generiert
werden. Auf der Seite 142/143 ist bei 12MHz (High Frequenz) noch die
Rede von FOSC0 bis FOSC2. Muss hier etwas programmiert werden?
Würdest du die 12 MHz erst noch runterteilen? Im Endeffekt ist es doch
egal, ob ich mit DIVM den Takt etwas runter teile und dann auf die
genaue Baudrate mit BRGR0 und BRGR1 komme. Oder man lässt das DIVM
komplett weg und löst alles über die BRGR0 und BRGR1.
Wo ich etwas drehe ist doch auch egal entscheidend ist doch die richtige
Baudrate. Ist das so alles richtig.
Muss das beim Quellcode noch beachtet werden?
Wie hoch sind die Kapazitäten am externen Quarz?
Ciss input capacitance [6] jeweils 15 pF
Schlagzeuger schrieb:> Wenn nichts abgeändert wird geht nichts ins SBUF!
Mein Beispielcode funktioniert genau so wie ich ihn gepostet habe völlig
korrekt.
> Das wichtigste habe ich zur späten Stund gestern noch vergessen, nämlich> das> Register BRGCON = 0x03;> Erst durch das 0x03 setzen der Bits wird der Baudratengenerator> verwendet (SBRGS) und der Baudratengenerator wird erst aktiviert> (BRGEN).
Genau was ich dir geschrieben hatte. ;)
> Hab jetzt mehrere Wege gefunden wo es geht:>> Variante 1:> TI = 0;> for ( i = 0 ; i < 3 ; i++ )> {> TI = 0; //TI-Flag gelöscht ermöglich Sendevorgang> SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte> }>> while(1);> }
Funktioniert nicht!
> Variante 2:> for ( i = 0 ; i < 3 ; i++ )> {> TI = 0; //TI-Flag gelöscht ermöglich Sendevorgang> SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte> TI = 1;> }>> while(1);> }
Funktioniert nicht!
> Variante 3:> for ( i = 0 ; i < 3 ; i++ )> {> TI = 0; //TI-Flag gelöscht ermöglich Sendevorgang> SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte> while (TI == 1);> }>> while(1);> }
Funktioniert nicht!
> Variante 4:> TI = 0;> for ( i = 0 ; i < 3 ; i++ )> {> SBUF = MIDIstream [i]; // Sendet pro Durchlauf 1 Byte> }>> while(1);> }
Funktioniert nicht!
> Welche Variante würdest du nehmen?
Keine, da alle murks machen.
> Die am wenigsten Speicher braucht z.B.: Variante 4.> Die zweite while Schleife kann man doch weglassen?
Du brauchst bei diesem Beispiel immer zwei while Schleife. Einmal um
das TI Flag abzufragen und einmal am Ende um das Programm in einem
definierten Zustand zu halten.
> Wenn ich diese zweite while Schleife einbaue muss diese auf TI = 1> stehen, weil sonst würde immer auf Sendevorgang prüfen.> Jedoch nachdem das Byte versendet wurde sollte das Flag auf> Senderegister leer prüfen stehen. (Seite 194)
Also du scheinst leider nicht wirklich verstanden zu haben, wie der
Controller arbeitet. :(
Das TI Flag wird automatisch nach dem Senden eines Bytes gesetzt. Mit
while(!TI); wartest du solange, bis das Byte gesendet wurde. Mit TI=0;
setzt du das Flag zurück, damit du erneut darauf prüfen kannst.
> Wie du auf dem Screenshot sehen kannst kann die 31250 Baud generiert> werden. Auf der Seite 142/143 ist bei 12MHz (High Frequenz) noch die> Rede von FOSC0 bis FOSC2. Muss hier etwas programmiert werden?
Diese Register werden beim programmieren des Controllers gesetzt. Die
Einstellungen dazu findest du in der Include Datei START900.A51, welche
du im Projekt eingebaunden haben solltest.
> Würdest du die 12 MHz erst noch runterteilen? Im Endeffekt ist es doch> egal, ob ich mit DIVM den Takt etwas runter teile und dann auf die> genaue Baudrate mit BRGR0 und BRGR1 komme. Oder man lässt das DIVM> komplett weg und löst alles über die BRGR0 und BRGR1.> Wo ich etwas drehe ist doch auch egal entscheidend ist doch die richtige> Baudrate. Ist das so alles richtig.
Lass DIVM auf standard und stell einfach nur per BRGR die Baudrate ein.
> Wie hoch sind die Kapazitäten am externen Quarz?> Ciss input capacitance [6] jeweils 15 pF
Hmmm, also so langsam frage ich mich, ob du überhaupt schon jemals eine
Controllerschaltung aufgebaut hast.
Ich würde dir wirklich raten erst mal ein fertiges Experimentierboard zu
kaufen und damit sehr einfache Programme wie LED blinken usw zu
programmieren. Wenn das funktioniert kannst du dich an dein Projekt
wagen. Du hast meiner Meinung nach nämlich deutlich zu viele Defizite in
dem Verständnis der Hardware und Software um dein Projekt zum laufen zu
bringen. Und ich habe auch keine Lust dir andauernd jede einzelne Zeile
Code zu korrigieren, weil du das Grundverständnis einfach noch nicht
hast.
Ich finde es ja schön, dass du versuchst solch ein Projekt zu
realisieren, aber der gesamte Thread zeigt leider nur, dass dir deutlich
Übung im Umgang mit Controllern fehlt. Und so langsam sehe ich da auch
kein Land mehr... :/
Deshalb rate ich dir nun zum x-ten mal, arbeite das Buch von vorne bis
hinten durch. Und wenn du etwas nicht verstanden hast, dann überspringe
es deswegen nicht. Du kannst dann gerne hier im Forum fragen, wie es
genau funktioniert. :)
Das hilft dir deutlich mehr als zu versuchen ein Projekt zu stemmen,
welches offensichtlich noch über deinem momentanen Wissensstand liegt.
Ich will dich mit dieser Aussage nicht demotivieren, oder sagen, dass du
es nie schaffen wirst. Aber du solltest so langsam auch mitbekommen
haben, dass es zur zeit noch nicht realistisch ist dein Projekt zu
realisieren.
Ciao,
Rainer
Hallo,
Wie du auf dem Screenshot sehen kannst kann die 31250 Baud generiert
werden. Auf der Seite 142/143 ist bei 12MHz (High Frequenz) noch die
Rede von FOSC0 bis FOSC2. Muss hier etwas programmiert werden?
>Diese Register werden beim programmieren des Controllers gesetzt. Die>Einstellungen dazu findest du in der Include Datei START900.A51, welche>du im Projekt eingebaunden haben solltest.
Ich werde die Kapitel noch intensiver durcharbeiten.
Jedoch weiß ich nicht woher ich die start900.a51 Datei bekomme und wie
ich die Register da setze.
Danke dir
Welche Entwicklungsumgebung benutzt du denn zum Programmieren?
Denn die Datei ATART900.A51 ist nur in der Keil Entwicklungsumgebung
enthalten und beim Anlegen eines neuen Projekts wirst du gefragt, ob du
diese Datei im einbinden willst.
Ciao,
Rainer
Ich verwende Keil uVision 4.
Wie die Datei herkommt weiß ich glaub ich.
Was muss ich in diese Datei nun hinschreiben?
Was wäre wenn dies nicht gemacht wird?
Also wegen den Varianten 1-4. Die habe ich das Wissen nur über die
Simulation gewonnen.
Die 3 Bytes konnte ich dann in dem Button SBUF sehen.
Mit deiner Variante sah ich nur das 1. Byte danach hielt die for
Schleife an.
Auf diese Tatsache habe ich die 4 Varanten entwickelt.
Ich hab jetzt auf Seite 196 schon gesehen, dass while (TI == 0) wartet
bis 8 Bits gesendet wird.
Ich werde das jetzt mal praktisch ohne Simulation ausprobieren.
Mit den Varianten 1-4 habe nicht an dir gezweifelt. Ich habe lediglich
die Programmierung solange abgestimmt bis die Simulation ging. Jetzt
geht es zwar irgendwie macht aber keinen Sinn und Logik.
Betrachtet man deine Programmierung die macht Logik und Sinn, jedoch in
der Simulation steht im SBUF nur das erste Byte. Danach bleibt die for
schleife stehen. Was ich dir sagen wollte Rainer ist, dass ich hier
nichts böse meine, sondern rein Objektiv handle.
Wenn ich dann etwas mit meinen Worten wiederhole dient es nur, dass ich
es verstanden habe. Es ist mir wichtig, damit ich nicht mehr unsicher
bin. Ich hoffe, dass du mich jetzt auch verstehst. Ich danke dir
weiterhin für deine Unterstützung und Hilfe.
Auf der Seite 142, 143 geht es um die Verwendung eines Quarzes.
Die Filterauswahl erfolgt im UCFG1.
Befindet sich das UCFG1 in der START900.A51 Datei?
Wo steht im Buch, dass man da die START900.A51 Datei überhaupt benötigt?
Ich hab leider nichts gefunden.
Hab jetzt mich vorgetastet. Ich Buch auf der Seite 143 steht eine Reset
Value von 0x63. In der START900.a51 meinte ich an der richtigen Stelle
folgendes gelesen zu haben: UCFG1 EQU 0x43
Der Unterschied ist einmal, dass BOE unterschiedlich ist.
BOE: (UCFG1.5) Brownout Detect Configuration
Brownout Detect Enable (1 = default on unprogrammed part)
Soll das wieder gesetzt werden?
Wozu braucht man das Bit?
Wegen der 12 MHZ soll in das UCFG1 nun der Wert
0x60 oder 0x40 geschrieben werden?
Ich müsste dann nur bei UCFG1 EQU 0x43
den Wert von 0x43 auf den neuen Wert abändern.
War das dann alles?
Wenn du die START900.A51 eingebunden hast, dann kannst du bei dieser am
unteren Fensterrand von "Text Editor" auf "Configuration Wizard"
umstellen. Damit lassen sich die Einstellungen sehr bequem erledigen
ohne die Register (UCFG, etc) von Hand setzen zu müssen. Dieser
Bearbeitungsmodus ist aber nur bei dieser speziellen Include Datei
vorhanden. (siehe beide Screenshots)
Der Code den ich gepostet hatte funktioniert wunderbar. Aber hast du
auch berücksichtigt, dass beim debuggen im einzelschritt Modus (step)
das Programm bei while(!TI); stehenbleibt und wartet, bis das Byte
gesendet wurde?
Dies kann unter Umständen sehr lange dauern und du musst sehr oft die
"step" Taste drücken um drüber hinaus zu kommen. Wenn du die gesamten
drei Bytes sofort sehen willst musst du den Code komplett durchlaufen
lassen mit "run".
Ciao,
Rainer
Hallo Rainer,
ich hab deine korrigierte Programmierung nun mal in der Praxis
ausprobiert.
Ich habe von Keil das Emulatorboard und das entsprechende
Experimentierboard mit Inkrementalgeber,LC Display, 7-Segmentanzeigen,
Balkenanzeigen, Taster, Schieber, usw.
Ich hab mit dem Board schon mal Ext Interrupt, Keyboard Interrupt,
Blinklicht, usw. programmiert.
Das was ich momentan mache ist für mich Neuland. Ich möchte ja nicht
immer dasselbe machen und ich hoffe, dass ich weiterhin auf deine
Unterstützung hoffen kann. Mich interessiert MIDI schon sehr, weil ich
selber Schlagzeuger bin.
Ich hab nun mal die korrigierte Programmierung mit dem Emulator und dem
Experimentierboard mit dem single step mode geprüft.
Das UCFG1 hab ich zwar mal abgeändert und zeigt nun laut Simulation auch
wieder die 31250 Baud an. Wechsle ich allerdings von der Simulation zum
Emulator dann versucht das Programm nach dem Debuggen immer in die
START900.a51 zu springen, dabei ignoriert das Programm ständig die
eigentliche Programmierung. Da bin ich schon mal nicht weiter gekommen.
Deshalb habe ich nochmals eine Testprojekt ohne Start900.a51 Datei
erstellt.
Dabei habe ich folgende Beobachtungen gemacht:
Beim ersten Durchlauf wird der erste Hexcode also das 1. Element gleich
i=0 niemals ausgeben. Die weiteren Elemente 1 bis 2 vom Vektor MIDIstram
werden nur bis 0x70 ausgeben. Drüber geschieht gar keine Ausgabe.
Unterhalb kann es mal vorkommen, dass nur Element 1 oder Element 2
ausgegeben werden. Eine richtige Ausgabe findet nur im unteren
Hex-Bereich statt(0x00 bis 0x40).Ich hab im Buch viel gelesen und
praktisch mehrere Stunden Fehlersuche betrieben, leider ohne Erfolg.
Das Bild zeigt mal einen gesendetes Byte von 0x40.
Das erste Byte wird nie gesendet.
Das zweite und dritte Byte wird nicht zuverlässig gesendet.
Warum das so ist weiß ich leider nicht. Ich war da jetzt etwa 10 Stunden
dort gesessen und komm ohne deine Hilfe da nicht weiter.
Danke dir für deine Hilfe
MfG
Tim
Ich hab das jetzt mal nach deinen Bildern gemacht.
Über den Configuration Wizard ist es wirklich einfach zu finden.
Ich habs nun so eingestellt wie bei dir.
Nun wollte ich mal wissen, wenn ich da den Button bis zu 20 MHz
anklicke, ob sich dann im Text Editor etwas getan hat.
Meine Festellung war die, dass sich nichts geändert hat. siehe pic2.
Eigentlich sollte doch jetzt ein anderer Hexcode als die 0x40 bei der
UCFG1 stehen. Wie soll die Filtereinstellung funktionieren, wenn kein
Wert übernommen wird?
Das angelegte Projekt schaut wie auf dem pic1 aus.
Jedesmal wenn ich debugge und im single step mode arbeiten möchte
springt das Programm in die Start900 Datei. Im Run Modus springt es zwar
nicht in die Start900 Datei, jedoch sind keine 3 Bytes auf dem
Oszischirm zu sehen.
Im den Target Options ->Debug-> Settings ->USE UCFG from Start900.A51
dachte ich mir sollte ich aktivieren, falls ein neuer Wert in der UCFG
steht.
Gemacht getan. Allerdings kamen dann beim Debuggen folgende
Fehlermeldungen:
Error: Command 'Read PC ( ) 'TIMEOUT
Error: Bad Response on Command 'Check Mon ( )'
Welche Target Optionen müssen eingestellt werden, damit die 3 Byte auf
dem Oszischirm zu sehen sind?
Jetzt habe ich ernsthafe Probleme, weil es nicht läuft, obwohl der
Quellcode bei dir einwandfrei funktioniert.
Ich würde gerne mal wieder vorankommen und einen kleinen Erfolg haben.
Ein kleiner Erfolg wäre schon, wenn ich die generierten 3 Bytes auf dem
Oszischirm sehen kann. :-)
Rainer ich muss dich echt loben, weil du ein guter Mentor bist.
Allerdings dein vorletzter Treadeintrag war schon ziemlich hart. Ich tu
doch schon alles, damit ich weiterkomme. So war ich heute mehrere
Stunden an der Sache gesessen. Bitte sei in Zukunft nicht mehr so streng
zu mir. Ich bin dir wirkich für alles dankbar. Natürlich hab ich nicht
soviel Erfahrungen wie du. Hinzu kommt manchmal meine Unsicherheit und
deshalb bin ich dir sehr dankbar für deine Hilfe und Unterstützung.Wie
sollen wir verbleiben? Wenn nicht mehr weiterkomme und Fehler habe kann
ich mich doch gerne bei dir/euch melden. Jetzt komme ich nicht mehr
weiter ich hab jetzt vieles versucht, sogar deine letzten Vorschläge und
Ideen umgesetzt.
Schlagzeuger schrieb:> Ich hab nun mal die korrigierte Programmierung mit dem Emulator und dem> Experimentierboard mit dem single step mode geprüft.> Das UCFG1 hab ich zwar mal abgeändert und zeigt nun laut Simulation auch> wieder die 31250 Baud an. Wechsle ich allerdings von der Simulation zum> Emulator dann versucht das Programm nach dem Debuggen immer in die> START900.a51 zu springen, dabei ignoriert das Programm ständig die> eigentliche Programmierung. Da bin ich schon mal nicht weiter gekommen.> Deshalb habe ich nochmals eine Testprojekt ohne Start900.a51 Datei> erstellt.
Dass er in die START900.A51 springt ist völlig normal, da in dieser
standardmäßig der RAM vor dem Start des eigentlichen Programms erst
gelöscht wird. Dies kannst du getrost abschalten indem du im
Configuration Wizard unter "Power-On Initialization of Memory" den Wert
auf 0x0000 setzt. Danach sollte er nicht mehr in diese Datei
reinspringen. Alternativ kannst du auch einen Breakpoint in der ersten
Zeile deines Programms machen und dann "run" sagen. Dann durchläuft er
die START900.A51 und springt direkt zur ersten Zeile deines Codes.
> Dabei habe ich folgende Beobachtungen gemacht:> Beim ersten Durchlauf wird der erste Hexcode also das 1. Element gleich> i=0 niemals ausgeben. Die weiteren Elemente 1 bis 2 vom Vektor MIDIstram> werden nur bis 0x70 ausgeben. Drüber geschieht gar keine Ausgabe.> Unterhalb kann es mal vorkommen, dass nur Element 1 oder Element 2> ausgegeben werden. Eine richtige Ausgabe findet nur im unteren> Hex-Bereich statt(0x00 bis 0x40).Ich hab im Buch viel gelesen und> praktisch mehrere Stunden Fehlersuche betrieben, leider ohne Erfolg.> Das Bild zeigt mal einen gesendetes Byte von 0x40.>> Das erste Byte wird nie gesendet.> Das zweite und dritte Byte wird nicht zuverlässig gesendet.> Warum das so ist weiß ich leider nicht. Ich war da jetzt etwa 10 Stunden> dort gesessen und komm ohne deine Hilfe da nicht weiter.
Ein ähnliches Problem hatte ich mal mit einem AVR XMega im einzelschritt
Modus gehabt. Es ging damals nur korrekt, wenn ich über die Ausgabe im
"run" Modus drübergesprungen bin. Dieses Phänomen kann mit dem Emulator
zusammenhängen. Dieser taktet nämlich den Controller extern, wodurch das
RS232 Timing nicht mehr korrekt ist. Ich könnte mir vorstellen, dass das
gleiche Problem auch bei dir auftritt. Denn wenn es in der Simulation
funktioniert sollte es auch zu 99% sicher auf der Hardware
funktionieren. Der Simulator von Keil ist sehr exakt bei dem, was er
simuliert.
Schlagzeuger schrieb:> Ich hab das jetzt mal nach deinen Bildern gemacht.> Über den Configuration Wizard ist es wirklich einfach zu finden.> Ich habs nun so eingestellt wie bei dir.> Nun wollte ich mal wissen, wenn ich da den Button bis zu 20 MHz> anklicke, ob sich dann im Text Editor etwas getan hat.> Meine Festellung war die, dass sich nichts geändert hat. siehe pic2.> Eigentlich sollte doch jetzt ein anderer Hexcode als die 0x40 bei der> UCFG1 stehen. Wie soll die Filtereinstellung funktionieren, wenn kein> Wert übernommen wird?
UCFG1 = 0x40 ist aber doch der korrekte Wert für die 20MHz Einstellung?
Mit den default Einstellungen steht bei mir dort 0x43 drin. Und sobald
ich etwas im Wizard ändere wird auch der Wert im Text Editor korrigiert.
> Das angelegte Projekt schaut wie auf dem pic1 aus.> Jedesmal wenn ich debugge und im single step mode arbeiten möchte> springt das Programm in die Start900 Datei. Im Run Modus springt es zwar> nicht in die Start900 Datei, jedoch sind keine 3 Bytes auf dem> Oszischirm zu sehen.>> Im den Target Options ->Debug-> Settings ->USE UCFG from Start900.A51> dachte ich mir sollte ich aktivieren, falls ein neuer Wert in der UCFG> steht.> Gemacht getan. Allerdings kamen dann beim Debuggen folgende> Fehlermeldungen:> Error: Command 'Read PC ( ) 'TIMEOUT> Error: Bad Response on Command 'Check Mon ( )'>> Welche Target Optionen müssen eingestellt werden, damit die 3 Byte auf> dem Oszischirm zu sehen sind?
Ich benutze (habe) keinen Emulator, weshalb ich die Programme anhand der
compilierten Hex Datei auf mein selber gebautes Experimentierboard per
RS232 aufspiele und teste. Ich kann dir deshalb keine Tipps zu dem
Emulator und dessen Einstellungen geben.
Benutzt du das LPC-Experimentierboard v1.3 zum Buch von der c51.de
Webseite in Verbindung mit dem EPM900 LPC Emulator?
Falls ja, dann kanst du auch ohne Emulator das Programm z.B. mit
Flashmagic direkt in das Experimentierboard per RS232 einspielen und
testen. Das wäre quasi der Weg, den ich mit meinem Board gehe zum
Testen. Eventuell verhält es sich dann ja etwas anderst als mit dem
Emulator. Ich würde an deiner Stelle zum Test die Baudrate auch auf z.B.
19200 stellen und die RS232 Ausgabe dann auf einem Terminal darstellen.
Wenn dies funktioniert kannst du ja weiter mit 31250Bps testen.
Ciao,
Rainer
> Dass er in die START900.A51 springt ist völlig normal, da in dieser> standardmäßig der RAM vor dem Start des eigentlichen Programms erst> gelöscht wird. Dies kannst du getrost abschalten indem du im> Configuration Wizard unter "Power-On Initialization of Memory" den Wert> auf 0x0000 setzt. Danach sollte er nicht mehr in diese Datei> reinspringen. Alternativ kannst du auch einen Breakpoint in der ersten> Zeile deines Programms machen und dann "run" sagen. Dann durchläuft er> die START900.A51 und springt direkt zur ersten Zeile deines Codes.
Pic1 zeigt Wizard Einstellungen
und in meinem main Programm habe ich diese Änderung gemacht:
breakpoint; run;
#include <REG935.H>
void main ( )
Ich hab jetzt mal beides gemacht. Dürfte doch so stimmen?
Es durchläuft nun nur noch einen winzigen kleinen Teil der Start900
Datei und springt dann in das Main Programm.
>> Dabei habe ich folgende Beobachtungen gemacht:>> Beim ersten Durchlauf wird der erste Hexcode also das 1. Element gleich>> i=0 niemals ausgeben. Die weiteren Elemente 1 bis 2 vom Vektor MIDIstram>> werden nur bis 0x70 ausgeben. Drüber geschieht gar keine Ausgabe.>> Unterhalb kann es mal vorkommen, dass nur Element 1 oder Element 2>> ausgegeben werden. Eine richtige Ausgabe findet nur im unteren>> Hex-Bereich statt(0x00 bis 0x40).Ich hab im Buch viel gelesen und>> praktisch mehrere Stunden Fehlersuche betrieben, leider ohne Erfolg.>> Das Bild zeigt mal einen gesendetes Byte von 0x40.
Das stimmt ursprünglich war 0x43 jetzt steht 0x40 drin.
Ich hatte gestern in meiner Berechnung ja 0x60 bzw. 0x40 herausgebracht.
Da war ich anscheinend gestern doch zulange am PC gesessen, weil ich
0x40 mit 0x43 vertauscht habe. Das ist noch das kleinste Problem :-)
>> Das erste Byte wird nie gesendet.>> Das zweite und dritte Byte wird nicht zuverlässig gesendet.>> Warum das so ist weiß ich leider nicht. Ich war da jetzt etwa 10 Stunden>> dort gesessen und komm ohne deine Hilfe da nicht weiter.> Ein ähnliches Problem hatte ich mal mit einem AVR XMega im einzelschritt> Modus gehabt. Es ging damals nur korrekt, wenn ich über die Ausgabe im> "run" Modus drübergesprungen bin. Dieses Phänomen kann mit dem Emulator> zusammenhängen. Dieser taktet nämlich den Controller extern, wodurch das> RS232 Timing nicht mehr korrekt ist. Ich könnte mir vorstellen, dass das> gleiche Problem auch bei dir auftritt. Denn wenn es in der Simulation> funktioniert sollte es auch zu 99% sicher auf der Hardware> funktionieren. Der Simulator von Keil ist sehr exakt bei dem, was er> simuliert.
In der Simulation hat es leider noch nie geklappt. Es hat nur ein
Zeichen herausgeschickt. Deshalb habe ich ja die Änderungen 1-4 gemacht.
Die For-Schleife in der SimulationSchleife wird leider nur einmal
durchlaufen.
Siehe Bild zur Simulation. Das Programm läuft nur bis Zeile 21, danach
bleibt es einfach stehen.
> Benutzt du das LPC-Experimentierboard v1.3 zum Buch von der c51.de> Webseite in Verbindung mit dem EPM900 LPC Emulator?
Richtig erkannt genau diese Kombination verwende ich.
Teste ich das Programm mit dem Experimentierboard und Emulator, dann
beginnt auch da das Programm in einem winzigen Teil der Start900 Datei
und springt dann in das Main Programm.
In dem Hauptprogramm kann es nur 19200 Baud übertragen. Mache ich die
Einstellung im Debug, dass es von dort die UCFG1 von der Start900 Datei
laden soll kommen Timing Errors, die ich dir schon geschrieben habe.
Achtung: Im Emulator läuft die for-Schleife durch, allerdings wird das
erste Byte nie gesendet und die zweiten und dritten Bytes werden nur
ausgegeben wenn die Hexwerte unter 0x40 sind. Auch dann kann mal
vorkommen, dass vom zweiten und dritten Byte nur ein Byte ausgegeben
wird.
Ist ein Byte über den Hexwert von 0x70 dann wird kein Byte der 3 Bytes
ausgegeben.
>Falls ja, dann kanst du auch ohne Emulator das Programm z.B. mit>Flashmagic direkt in das Experimentierboard per RS232 einspielen und>testen. Das wäre quasi der Weg, den ich mit meinem Board gehe zum>Testen. Eventuell verhält es sich dann ja etwas anderst als mit dem>Emulator. Ich würde an deiner Stelle zum Test die Baudrate auch auf z.B.>19200 stellen und die RS232 Ausgabe dann auf einem Terminal darstellen.>Wenn dies funktioniert kannst du ja weiter mit 31250Bps testen.
Ohne Emulator übertrage ich das Hexfile von meinem main Programm per
Software (Flashmagic) an den LPC?
Muss das Kabel 1:1 durchverbunden oder ist TX und RX vertauscht, also
ein Nullmodemkabel?
Entspricht die Übertragung mit Flashmagic wie die das von Flip?
Den Vorgang habe ich bis jetzt noch nicht so oft gemacht, deshalb frage
ich mal bei dir nach.
Also ich müßte das Experimentierboard mit einem LPC bestücken, den
Emulator abhängen, am Seriell Port X8 per Flashmagic oder Flip den
hexcode übertragen? Wäre dann alles richtig gemacht!?
Somit wäre dann das Programm im LPC ohne Emulator. Hoffen wir mal, dass
es ohne Emulator dann klappt. Danke für dein Feedback.
Weshalb aber das 1 Byte nicht gesendet wird kann ich nicht
nachvollziehen.
Weißt du darauf eine Antwort?
Danke
Schlagzeuger schrieb:> und in meinem main Programm habe ich diese Änderung gemacht:>> breakpoint; run;> #include <REG935.H>> void main ( )>> Ich hab jetzt mal beides gemacht. Dürfte doch so stimmen?> Es durchläuft nun nur noch einen winzigen kleinen Teil der Start900> Datei und springt dann in das Main Programm.
Hmm, ich kenne nur den Weg Breakpoints mit der Maus oder über das Menü
zu erzeugen. Dafür einfach neben die Zeile einen Doppelklick und der
Breakpoint wird angezeigt. Es als Text in der Zeile "breakpoint; run;"
hinzuschreiben sagt mir nichts.
> In der Simulation hat es leider noch nie geklappt. Es hat nur ein> Zeichen herausgeschickt. Deshalb habe ich ja die Änderungen 1-4 gemacht.> Die For-Schleife in der SimulationSchleife wird leider nur einmal> durchlaufen.> Siehe Bild zur Simulation. Das Programm läuft nur bis Zeile 21, danach> bleibt es einfach stehen.
Hast du diesbezüglich meinen Hinweis weiter oben gelesen gehabt?
Fox Mulder schrieb:>> Der Code den ich gepostet hatte funktioniert wunderbar. Aber hast du>> auch berücksichtigt, dass beim debuggen im einzelschritt Modus (step)>> das Programm bei while(!TI); stehenbleibt und wartet, bis das Byte>> gesendet wurde?>> Dies kann unter Umständen sehr lange dauern und du musst sehr oft die>> "step" Taste drücken um drüber hinaus zu kommen. Wenn du die gesamten>> drei Bytes sofort sehen willst musst du den Code komplett durchlaufen>> lassen mit "run".> Teste ich das Programm mit dem Experimentierboard und Emulator, dann> beginnt auch da das Programm in einem winzigen Teil der Start900 Datei> und springt dann in das Main Programm.> In dem Hauptprogramm kann es nur 19200 Baud übertragen. Mache ich die> Einstellung im Debug, dass es von dort die UCFG1 von der Start900 Datei> laden soll kommen Timing Errors, die ich dir schon geschrieben habe.>> Achtung: Im Emulator läuft die for-Schleife durch, allerdings wird das> erste Byte nie gesendet und die zweiten und dritten Bytes werden nur> ausgegeben wenn die Hexwerte unter 0x40 sind. Auch dann kann mal> vorkommen, dass vom zweiten und dritten Byte nur ein Byte ausgegeben> wird.> Ist ein Byte über den Hexwert von 0x70 dann wird kein Byte der 3 Bytes> ausgegeben.
Solch ein Phänomen kenne ich bei mir nicht.
> Ohne Emulator übertrage ich das Hexfile von meinem main Programm per> Software (Flashmagic) an den LPC?> Muss das Kabel 1:1 durchverbunden oder ist TX und RX vertauscht, also> ein Nullmodemkabel?> Entspricht die Übertragung mit Flashmagic wie die das von Flip?> Den Vorgang habe ich bis jetzt noch nicht so oft gemacht, deshalb frage> ich mal bei dir nach.> Also ich müßte das Experimentierboard mit einem LPC bestücken, den> Emulator abhängen, am Seriell Port X8 per Flashmagic oder Flip den> hexcode übertragen? Wäre dann alles richtig gemacht!?> Somit wäre dann das Programm im LPC ohne Emulator. Hoffen wir mal, dass> es ohne Emulator dann klappt. Danke für dein Feedback.
Wie du es mit Flashmagic auf dein Board überträgst und welche
Einstellungen du dafür brauchst steht im Handbuch zu deinem Board drin.
Habe mir das Handbuch als PDF vorhin nämlich mal angeschaut. ;)
Ciao,
Rainer
> Hmm, ich kenne nur den Weg Breakpoints mit der Maus oder über das Menü> zu erzeugen. Dafür einfach neben die Zeile einen Doppelklick und der> Breakpoint wird angezeigt.
Setzt man den Breakpoint in der Startdatei ganz oben hin und dann drückt
man nur noch den run Mode? Damit überspringt man dann das Programm.
Wenn das Programm mal läuft und es in den LPC geflasht wird muss man
dann da noch etwas beachten? Weil da kann man ja keinen Breakpoint usw.
setzen.
Da durchläuft es zuerst die Startdatei und dann meinen Quellcode ist das
so richtig?
>> In der Simulation hat es leider noch nie geklappt. Es hat nur ein>> Zeichen herausgeschickt. Deshalb habe ich ja die Änderungen 1-4 gemacht.>> Die For-Schleife in der SimulationSchleife wird leider nur einmal>> durchlaufen.>> Siehe Bild zur Simulation. Das Programm läuft nur bis Zeile 21, danach>> bleibt es einfach stehen.> Hast du diesbezüglich meinen Hinweis weiter oben gelesen gehabt?
Ja diesen habe ich gelesen. Mit single step geht es nicht! Ist
dasgleiche Problem wie bei dir damals. Mit run Mode läuft es, wie kann
man sich so etwas erklären?
Ich sehe dann im Simulationsfenster Serial Channel im SBUF nur noch das
letzte Zeichen, weil die Aussgabe ziemlich schnell ist. Deshalb hab ich
mal noch überprüft, ob die zugewiesenen Daten im Programmspeicher
richtig liegen. Wie man im Bild entnehmen kann stehen die selben
hexwerte. Also die Zuweisungen passen schon mal. Dann hoffe ich, dass
ich die 3 Byte auch bald mal messen kann. Ist das Zufall, dass die Daten
ab 0x0136 liegen?
Ich würde behaupten, dass das Zufall ist weil ich bei der Programmierung
nichts berücksichtigt habe.
> Wie du es mit Flashmagic auf dein Board überträgst und welche> Einstellungen du dafür brauchst steht im Handbuch zu deinem Board drin.> Habe mir das Handbuch als PDF vorhin nämlich mal angeschaut. ;)
Okay da werde ich mal nachlesen und dann versuche ich es ohne Emulator.
Mal sehen, ob ich dann die 3 Bytes auch mit dem Oszi messen kann. Bin
schon gespannt.
Schlagzeuger schrieb:>> Hmm, ich kenne nur den Weg Breakpoints mit der Maus oder über das Menü>> zu erzeugen. Dafür einfach neben die Zeile einen Doppelklick und der>> Breakpoint wird angezeigt.> Setzt man den Breakpoint in der Startdatei ganz oben hin und dann drückt> man nur noch den run Mode? Damit überspringt man dann das Programm.
Wenn du sowieso das Programm nur durchlaufen lassen willst brauchst du
natürlich gar keinen Breakpoint. ;)
> Wenn das Programm mal läuft und es in den LPC geflasht wird muss man> dann da noch etwas beachten? Weil da kann man ja keinen Breakpoint usw.> setzen.> Da durchläuft es zuerst die Startdatei und dann meinen Quellcode ist das> so richtig?
Jup
>>> In der Simulation hat es leider noch nie geklappt. Es hat nur ein>>> Zeichen herausgeschickt. Deshalb habe ich ja die Änderungen 1-4 gemacht.>>> Die For-Schleife in der SimulationSchleife wird leider nur einmal>>> durchlaufen.>>> Siehe Bild zur Simulation. Das Programm läuft nur bis Zeile 21, danach>>> bleibt es einfach stehen.>> Hast du diesbezüglich meinen Hinweis weiter oben gelesen gehabt?> Ja diesen habe ich gelesen. Mit single step geht es nicht! Ist> dasgleiche Problem wie bei dir damals. Mit run Mode läuft es, wie kann> man sich so etwas erklären?
Man kann eben nicht alles im Einzelschritt auf der Hardware debuggen.
> Ich sehe dann im Simulationsfenster Serial Channel im SBUF nur noch das> letzte Zeichen, weil die Aussgabe ziemlich schnell ist. Deshalb hab ich
Die Ausgabe zwigt aber normalerweise alle Zeichen und nicht nur das
Letzte an. Bei mir stehen dort drei Zeichen im Ausgabefenster, wenn ich
das Programm durchlaufen lasse.
> mal noch überprüft, ob die zugewiesenen Daten im Programmspeicher> richtig liegen. Wie man im Bild entnehmen kann stehen die selben> hexwerte. Also die Zuweisungen passen schon mal. Dann hoffe ich, dass> ich die 3 Byte auch bald mal messen kann. Ist das Zufall, dass die Daten> ab 0x0136 liegen?> Ich würde behaupten, dass das Zufall ist weil ich bei der Programmierung> nichts berücksichtigt habe.
Das macht dert Compiler automatisch.
Ciao,
Rainer
>> Ich sehe dann im Simulationsfenster Serial Channel im SBUF nur noch das>> letzte Zeichen, weil die Aussgabe ziemlich schnell ist. Deshalb hab ich> Die Ausgabe zwigt aber normalerweise alle Zeichen und nicht nur das> Letzte an. Bei mir stehen dort drei Zeichen im Ausgabefenster, wenn ich> das Programm durchlaufen lasse.
Also das Ausgabefenster ist bei dir das SBUF?
Ich könnte ja mal rein aus Testzwecken eine Verögerungszeitschleife
einbauen.
Im single Step geht es ja nicht und im run Modus sehe ich dann nur das
letzte Byte im Button SBUF.
Kannst du mir mal erklären was du gemacht hast und wo man bei dir was
sehen kann. Danke Rainer ich wünsch dir heute noch einen schönen Tag.
Bye Tim
Schlagzeuger schrieb:>>> Ich sehe dann im Simulationsfenster Serial Channel im SBUF nur noch das>>> letzte Zeichen, weil die Aussgabe ziemlich schnell ist. Deshalb hab ich>> Die Ausgabe zwigt aber normalerweise alle Zeichen und nicht nur das>> Letzte an. Bei mir stehen dort drei Zeichen im Ausgabefenster, wenn ich>> das Programm durchlaufen lasse.> Also das Ausgabefenster ist bei dir das SBUF?> Ich könnte ja mal rein aus Testzwecken eine Verögerungszeitschleife> einbauen.> Im single Step geht es ja nicht und im run Modus sehe ich dann nur das> letzte Byte im Button SBUF.> Kannst du mir mal erklären was du gemacht hast und wo man bei dir was> sehen kann. Danke Rainer ich wünsch dir heute noch einen schönen Tag.
Ich glaube ich weiß jetzt, wo dein Fehler liegt. Du schaust dir den Wert
im SBUF Register im Uart Peripherie Fenster an beim Debuggen. Dort
siehst du natürlich immer nur den letzten Wert und nicht alles was
gesendet wurde.
Du musst, um alle gesendeten Bytes zu sehen, das Serial Window 1 von
µVision benutzen. Dieses zeigt dir genau das an, was auch an einem
Endgerät, welches and er RS232 dran hängen würde, ankommt. ;)
Ciao,
Rainer
> Ich glaube ich weiß jetzt, wo dein Fehler liegt. Du schaust dir den Wert> im SBUF Register im Uart Peripherie Fenster an beim Debuggen. Dort> siehst du natürlich immer nur den letzten Wert und nicht alles was> gesendet wurde.> Du musst, um alle gesendeten Bytes zu sehen, das Serial Window 1 von> µVision benutzen. Dieses zeigt dir genau das an, was auch an einem> Endgerät, welches and er RS232 dran hängen würde, ankommt. ;)
So habe ich es leider immer gemacht.
Ich habe jetzt View->Serial Window-> UART#1 ausgewählt.
Bei mir ist nur auf UART1 etwas sichtbar, weil das die serielle
Schnittstelle ist?
Weshalb kann man dort gleich von UART1 bis Uart3 auswählen?
Ein LPC hat doch eigentlich nur eine serielle Schnittstelle.
Kann man die SPI und den I^C muss unter UART2 und UART3 sehen?
Ich hab jetzt mal einen String erzeugt, siehe Bild.
Ist die Ausgabe auf dem UART#1 immer in ASCI Zeichen?
Du hast mir ja einmal erklärt wie man im Configuration Wizard im Power
on Initialization of memory das gezielt auf 0x0000 setzt, damit das
Programm bei der Simulation nicht immer in die Start900 Datei springt.
Wenn ich das Programm in den LPC schreibe kann das so stehen bleiben
oder muss das abgeändert werden?
Wenn ich nichts machen muss wie gelangt das Programm dann in die
Start900 Datei, wenn ich dies auf 0x0000 gesetzt habe? Gelten da andere
Mechanismen?
Also nächstes möchte ich nun mal versuchen, ob die Bytes auf dem Oszi
mit zu messen sind, wenn nicht, dann werde ich den Mikrocontroller mit
Flashmagic selber flashen. Danke nochmals für den sehr guten Tipp, da
wäre ich niemals draufgekommen.
Schlagzeuger schrieb:>> Ich glaube ich weiß jetzt, wo dein Fehler liegt. Du schaust dir den Wert>> im SBUF Register im Uart Peripherie Fenster an beim Debuggen. Dort>> siehst du natürlich immer nur den letzten Wert und nicht alles was>> gesendet wurde.>> Du musst, um alle gesendeten Bytes zu sehen, das Serial Window 1 von>> µVision benutzen. Dieses zeigt dir genau das an, was auch an einem>> Endgerät, welches and er RS232 dran hängen würde, ankommt. ;)> So habe ich es leider immer gemacht.> Ich habe jetzt View->Serial Window-> UART#1 ausgewählt.> Bei mir ist nur auf UART1 etwas sichtbar, weil das die serielle> Schnittstelle ist?> Weshalb kann man dort gleich von UART1 bis Uart3 auswählen?> Ein LPC hat doch eigentlich nur eine serielle Schnittstelle.> Kann man die SPI und den I^C muss unter UART2 und UART3 sehen?
Es gibt auch Controller mit mehr als einer Seriellen Schnittstelle
integriert. Die Anzahl Fenster ändert sich aber nicht, egal welchen
Controller du simulierst. Ich glaube nicht, dass I2C oder SPI auf den
anderen Kanälen angezeigt wird, aber das habe ich auch noch nie
getestet. :)
> Ich hab jetzt mal einen String erzeugt, siehe Bild.> Ist die Ausgabe auf dem UART#1 immer in ASCI Zeichen?
Du kannst mit der rechten Maustaste in diesem Fenster die Ausgabe
umschalten zwischen Ascii, Hex und anderen Darstellungen.
> Du hast mir ja einmal erklärt wie man im Configuration Wizard im Power> on Initialization of memory das gezielt auf 0x0000 setzt, damit das> Programm bei der Simulation nicht immer in die Start900 Datei springt.> Wenn ich das Programm in den LPC schreibe kann das so stehen bleiben> oder muss das abgeändert werden?> Wenn ich nichts machen muss wie gelangt das Programm dann in die> Start900 Datei, wenn ich dies auf 0x0000 gesetzt habe? Gelten da andere> Mechanismen?
Du kannst es getrost auf 0x0000 stehen lassen. Das bewirkt nur, dass der
interne Ram vor dem Programmstart nicht explizit gelöscht wird. Aber
wenn du in deinem Programm deine Variablen immer initialisierst (was
sinnvoll ist), bevor du diese benutzt, hat das keine Relevanz für dich.
> Also nächstes möchte ich nun mal versuchen, ob die Bytes auf dem Oszi> mit zu messen sind, wenn nicht, dann werde ich den Mikrocontroller mit> Flashmagic selber flashen. Danke nochmals für den sehr guten Tipp, da> wäre ich niemals draufgekommen.
So langsam geht es doch voran. :)
Ciao,
Rainer
Hallo Rainer,
will ich ja schwer hoffen, dass es voran geht.
Es ist halt immer ein auf und ab. Aber wenn man dann einen Teilerfolg
hat, dann freut man sich danach umso mehr. Ich hoffe, dass dich die
Stringausgabe gefreut hat. Danke nochmals für alles.
Ich besitze ja diesen Emulator. Damit kann ich dasgleiche hardwaremäßig
simulieren wie mit der Softwaresimulierung von uVision. Kennst du die
Vorteile eines Emulator?
Nachteile habe ich ja jetzt schon welche kennengelernt.
Dass das nicht geht mit single step, obwohl der Emulator 12 MHz hat?
Ich denke mir Emulatoren kommen eher bei Entwickler in Frage die z.B.
viel mit Embedded Systems zu tun haben. Die Emulatoren sind ja nicht
ganz billig, da müßte es doch noch mehr Vorteile als nur den komfort
geben. Ein weiterer Vorteil ist, dass das Programm von uVision per USB
in den Emulator geladen werden kann und dass ein weiterer Port mit SMD
LEDs zur Verfügung stehen. Ich hab das damals mitgekauft, weil die das
im Paket angeboten haben.
Wenn du etwas dazu weißt kannst es mir gerne sagen.
Ich meld mich dann erst wieder, wenn ich die Messungen gemacht habe.
Ich hoffe, dass ich das Ende dieser Woche noch schaffen werde :-)
>> Du hast mir ja einmal erklärt wie man im Configuration Wizard im Power>> on Initialization of memory das gezielt auf 0x0000 setzt, damit das>> Programm bei der Simulation nicht immer in die Start900 Datei springt.>> Wenn ich das Programm in den LPC schreibe kann das so stehen bleiben>> oder muss das abgeändert werden?>> Wenn ich nichts machen muss wie gelangt das Programm dann in die>> Start900 Datei, wenn ich dies auf 0x0000 gesetzt habe? Gelten da andere>> Mechanismen?> Du kannst es getrost auf 0x0000 stehen lassen. Das bewirkt nur, dass der> interne Ram vor dem Programmstart nicht explizit gelöscht wird. Aber> wenn du in deinem Programm deine Variablen immer initialisierst (was> sinnvoll ist), bevor du diese benutzt, hat das keine Relevanz für dich.
Also der Punkt ist mir noch unklar.
0x0000 ist die Startadresse im Programmspeicher.
Gibt es auch einen Code mit 0x Rest keine Ahnung, wo ich das RAM löschen
kann?
Mit initialisieren meinst du, dass bei der Variablendeklaration eine
Variablendefinition gemacht wird?
zum Beispiel:
#include <REG935.H>
main ( )
{
char i = 0;
usw.
Variablendefinition = Initalisierung?
Was wäre denn wenn ich im Programmspeicher 0x0000 stehe lasse und keine
Initalisierung mache?
Dann könnte doch vorkommen, dass z.B.: in einem Vekor oder in einer
Zählvariable einer for-Schleife falsche Werte drinstehen. So müßte das
doch sein, wenn ich das richtig verstanden habe.
Danke für die Beantwortung. Ich meld mich dann erst wieder am Do oder
Fr. Bis dahin wünsche ich dir eine schöne und angenehme Woche.
Schlagzeuger schrieb:> Hallo Rainer,> will ich ja schwer hoffen, dass es voran geht.> Es ist halt immer ein auf und ab. Aber wenn man dann einen Teilerfolg> hat, dann freut man sich danach umso mehr. Ich hoffe, dass dich die> Stringausgabe gefreut hat. Danke nochmals für alles.> Ich besitze ja diesen Emulator. Damit kann ich dasgleiche hardwaremäßig> simulieren wie mit der Softwaresimulierung von uVision. Kennst du die> Vorteile eines Emulator?> Nachteile habe ich ja jetzt schon welche kennengelernt.> Dass das nicht geht mit single step, obwohl der Emulator 12 MHz hat?
Nunja, es gibt ein paar Einschränkungen bei Emulatoren, wie z.B. das
Problem mit dem single-step über manche peripherie Funktionen. Aber der
große Vorteil vom Emulator gegenüber der Simulation ist, dass du die
Auswirkungen direkt auf der Hardware beobachten und somit Fehler finden
kannst, die in der Simulation nicht oder nur schwer zu finden sind.
Schlagzeuger schrieb:>>> Du hast mir ja einmal erklärt wie man im Configuration Wizard im Power>>> on Initialization of memory das gezielt auf 0x0000 setzt, damit das>>> Programm bei der Simulation nicht immer in die Start900 Datei springt.>>> Wenn ich das Programm in den LPC schreibe kann das so stehen bleiben>>> oder muss das abgeändert werden?>>> Wenn ich nichts machen muss wie gelangt das Programm dann in die>>> Start900 Datei, wenn ich dies auf 0x0000 gesetzt habe? Gelten da andere>>> Mechanismen?>> Du kannst es getrost auf 0x0000 stehen lassen. Das bewirkt nur, dass der>> interne Ram vor dem Programmstart nicht explizit gelöscht wird. Aber>> wenn du in deinem Programm deine Variablen immer initialisierst (was>> sinnvoll ist), bevor du diese benutzt, hat das keine Relevanz für dich.>> Also der Punkt ist mir noch unklar.> 0x0000 ist die Startadresse im Programmspeicher.> Gibt es auch einen Code mit 0x Rest keine Ahnung, wo ich das RAM löschen> kann?
Also um das klar zu stellen. Die Angabe 0x0000 an dieser Stelle hat
nichts mit dem Code Speicher zu tun sondern ist nur eine
Längenangabe. Mit dieser legst du fest, wieviele Bytes im internen Ram
mit dem Startwert 0 initialisiert werden sollen. Machst du das nicht,
kann es sein, dass im Ram irgend welche Zufallszahlen drin stehen.
> Mit initialisieren meinst du, dass bei der Variablendeklaration eine> Variablendefinition gemacht wird?> zum Beispiel:>> #include <REG935.H>> main ( )> {> char i = 0;> usw.>> Variablendefinition = Initalisierung?
Genau das meine ich. Hier mal zwei Beispiele, welche das Problem etwas
verdeutlichen.
1. Beispiel korrekt:
1
voidmain(){
2
unsingedcharx;// x = ?, x ist undefiniert
3
4
...
5
x=0;// x = 0, x ist definiert
6
while(x<10){// 0 < 10
7
...
8
x=x+1;// x = 0 + 1
9
}
10
}
2. Beispiel nicht korrekt:
1
voidmain(){
2
unsingedcharx;// x = ?, x ist undefiniert
3
4
...
5
while(x<10){// ? < 10, x ist nicht definiert
6
...
7
x=x+1;// x = ? + 1, x ist nicht definiert
8
}
9
}
> Was wäre denn wenn ich im Programmspeicher 0x0000 stehe lasse und keine> Initalisierung mache?> Dann könnte doch vorkommen, dass z.B.: in einem Vekor oder in einer> Zählvariable einer for-Schleife falsche Werte drinstehen. So müßte das> doch sein, wenn ich das richtig verstanden habe.
Da du sämtliche Variablen vor der eigentlichen Benutzung initialisieren
musst ist es egal, was ursprünglich im Ram drin steht.
Ciao,
Rainer
soweit ist jetzt alles klar bei mir.
mit Ausnahme:
Ich habe in der Configuration Wizard das UCFG1 auf das 20 MHZ Filter,
also 0x40 eingestellt. Momentan durchläuft die Simulation nicht mehr die
Start900 Datei, sondern hüpft gleich in mein auszuführendes main
Programm.
Wenn ich jetzt das Programm in den LPC flash durchläuft es dann die
Startdatei900, weil da würden ja die Werte auf 0x00000 gesetzt.
Also es geht mir darum, ob das Filter für 20 MHz dann ausgewählt wird?
Ich versteh da den Zusammenhang nicht, weil einerseits in der Simulation
überspringt es die Start900 Datei. Jedoch wenn die Software geflasht
ist, also in der Praxis, muss doch als erstes auf die Startdatei
zugegriffen werden, um das Filter zu initalisieren zu können.
Nun die Frage muss man da etwas berücksichtigen oder nicht?
Falls nicht, weshalb geht es dann im geflashten Zustand und nicht in der
Simulations oder Emualtorbetrieb?
Ich hoffe, dass du meine Frage verstehen konntest.
Übrigens die Umstellung von ASCI auf Hex ist kein Problem.
Danke dir Tim
Schlagzeuger schrieb:> soweit ist jetzt alles klar bei mir.> mit Ausnahme:> Ich habe in der Configuration Wizard das UCFG1 auf das 20 MHZ Filter,> also 0x40 eingestellt. Momentan durchläuft die Simulation nicht mehr die> Start900 Datei, sondern hüpft gleich in mein auszuführendes main> Programm.>> Wenn ich jetzt das Programm in den LPC flash durchläuft es dann die> Startdatei900, weil da würden ja die Werte auf 0x00000 gesetzt.> Also es geht mir darum, ob das Filter für 20 MHz dann ausgewählt wird?> Ich versteh da den Zusammenhang nicht, weil einerseits in der Simulation> überspringt es die Start900 Datei. Jedoch wenn die Software geflasht> ist, also in der Praxis, muss doch als erstes auf die Startdatei> zugegriffen werden, um das Filter zu initalisieren zu können.> Nun die Frage muss man da etwas berücksichtigen oder nicht?> Falls nicht, weshalb geht es dann im geflashten Zustand und nicht in der> Simulations oder Emualtorbetrieb?
Wenn µVision den Code compiliert berücksichtigt es die Einstellungen für
UCFG1 und die anderen Konfigurationsregister und schreibt diese mit in
das Hex File hinein. Da diese Register aber nur beim Flashen des
Controllers relevant sind, wird natürlich kein Code explizit dafür
durchlaufen.
Nur wenn du in der Einstellung für "power on initialization of memory"
einen Wert größer 0 einträgst wird auch expliziter Code generiert um den
internen Ram zu Beginn zu löschen.
Du darfst dir diese Konfigurationsregister nicht wie normale SFR in
deinem Programm vorstellen, die der Controller selber bearbeitet. Diese
sind nur für die Konfiguration des Controllers relevant.
Ciao,
Rainer
Hallo Rainer,
ich hab heute folgende Feststellung gemacht:
Die Start900.a51 Datei hat keine Auswirkungen auf die Funktion.
Die Resultate sind mit oder ohne Start900.a51 Datei dieselben.
Im Single Step Modus mit Emulator wird nur das zweite und dritte Byte
bis zu einem hex Wert von ca. 0x60 ausgegeben. Hier ist dasselbe Problem
wie ohne Start900.a51 Datei. Das erste Byte wird nie ausgegeben.
Betreibt man das Programm in Verbindung mit dem Emulator in run-Modus so
werden keine Bytes ausgegeben.
Packet man um die for- Schleife eine Dauerschleife:
do
for ( i = 0 ; i < 3 ; i++ )
{
TI = 0; // Flag löschen, damit erneut 8 Bit versendet werden können.
SBUF = MIDIstream [i]; // Sendet pro Durchlauf 8 Bit
while (!TI); // Warten bis 8 Bit gesendet
}
while (1);
while(1);
}
So sind alle 3 Bytes sichtbar (Siehe dazu Bild 1) und können von 0x00
bis 0xFF eingestellt werden. Allerdings kann glaub ich nur eine Baudrate
von 19200 Baud erreicht werden. Siehe Bild dazu Bild 2.
Bei einem Bit habe ich 19,23kHz gemessen. Das wäre dann eine Baudrate
von 19230 Baud. Ist die Vermutung richtig?
Ich hoffe, dass ich mit dieser Methode meinen Emulator nicht schrotten
kann?
Weshalb kann mit dem Emulator nur 19200 Baud eingestellt werden?
Du meintest mal, weil die externe Taktung vom Emulator höher ist!?
Blickt man auf das Emulatorboard so sehe ich da ebenfalls einen 12 MHz
Quarz. Wie kann dann da die Taktung zu hoch sein? Mit dem LPC können
Quarze bis 20 MHz betrieben werden. Wo liegt hier die Ursache?
Wie kann man sich das erklären, dass ja eigentlich nichts richtig geht,
jedoch mit einer Dauerschleife um die for-Schleife sind alle 3 Bytes
sichtbar und beliebig einstellbar.
Das sind meine Feststellungen die ich heute gemacht habe.
Für mich sind da manche Dinge ein richtiges Phänomen. Wie kann man sich
das erklären?
Ist daran alleine der Emulator schuld?
Falls ja, weshalb?
Weshalb benutze ich einen Emulator, der dann Schwierigkeiten macht.
Mit dem flashen per Flashmagic bin ich heute leider nicht mehr
dazugekommen.
Ich werde mal schauen, ob ich die Sache morgen anpacken kann.
Bin schon gespannt, welche Phänomene da auftreten.
Gute Nacht
tim
Schlagzeuger schrieb:> Hallo Rainer,> ich hab heute folgende Feststellung gemacht:> Die Start900.a51 Datei hat keine Auswirkungen auf die Funktion.> Die Resultate sind mit oder ohne Start900.a51 Datei dieselben.
Wenn du die Start900.a51 weg lässt, dann werden die
Konfigurationsregister nicht verändert und bleiben auf dem letzten Wert,
der vorher mal eingestellt wurde. So gesehen wirst du auch keine
Änderung mehr sehen, da vermutlich die Werte im Flash schon korrekt
eingestellt sind. Willst du nun aber neue Werte in die
Konfigurationsregister schreiben geht das nur, wenn du die Start900.a51
dafür verwendest.
> Im Single Step Modus mit Emulator wird nur das zweite und dritte Byte> bis zu einem hex Wert von ca. 0x60 ausgegeben. Hier ist dasselbe Problem> wie ohne Start900.a51 Datei. Das erste Byte wird nie ausgegeben.>> Betreibt man das Programm in Verbindung mit dem Emulator in run-Modus so> werden keine Bytes ausgegeben.
Wie schon gesagt kenne ich mich mit diesem Emulator nicht aus und
benutze selber auch keinen für die LPC900 Controller. Da könntest du
höchstens direkt an Keil eine Email schreiben und dort um Hilfe bitten.
> Packet man um die for- Schleife eine Dauerschleife:>> do> for ( i = 0 ; i < 3 ; i++ )> {> TI = 0; // Flag löschen, damit erneut 8 Bit versendet werden können.> SBUF = MIDIstream [i]; // Sendet pro Durchlauf 8 Bit> while (!TI); // Warten bis 8 Bit gesendet> }> while (1);>> while(1);> }>> So sind alle 3 Bytes sichtbar (Siehe dazu Bild 1) und können von 0x00> bis 0xFF eingestellt werden. Allerdings kann glaub ich nur eine Baudrate
Die letzte while(1) Schleife ist unnötig, da du vorher ja schon eine
Endlosschleife eingebaut hast. ;)
Aber wenn du in diesem Fall alle drei Bytes immer wieder hintereinander
gesendet siehst, dann funktioniert es ja zumindest schon mal. Kann es
sein, dass du ohne diese Schleife eventuell die Bytes nur deshalb nicht
siehst, weil du dein Oszi nicht auf single-shot gestellt hast oder der
Trigger nicht korrekt gesetzt ist?
Um eine korrekte Triggerung zu erhalten könntest du z.B. einen Portpin
vor dem Senden togglen und an diesem den zweiten Kanal es Oszis
dranhängen zum triggern und mit aufzeichnen. Dann siehst du auf dem
zweiten Kanal genau zwei Signalwechsel, jeweils einen vor und einen
nach den gesendeten drei Bytes. Damit lässt sich dann schon deutlich
mehr über den korrekten Programmablauf aussagen.
Dafür könntest du in deinem Programm z.B. folgenden Code ergänzen:
1
sbitout=P2^0;
2
out=0;
3
P2M1&=0xFE;
4
P2M2&=0xFE;
5
6
out=1;
7
8
forschleife...
9
10
out=0;
11
12
whle(1);
Damit kannst du dann auf positive Flanke im single-shot Modus triggern.
> von 19200 Baud erreicht werden. Siehe Bild dazu Bild 2.> Bei einem Bit habe ich 19,23kHz gemessen. Das wäre dann eine Baudrate> von 19230 Baud. Ist die Vermutung richtig?> Ich hoffe, dass ich mit dieser Methode meinen Emulator nicht schrotten> kann?
Das mit der Baudrate stimmt soweit. Und deinen Emulator kannst du so
garantiert nicht schrotten.
> Weshalb kann mit dem Emulator nur 19200 Baud eingestellt werden?> Du meintest mal, weil die externe Taktung vom Emulator höher ist!?> Blickt man auf das Emulatorboard so sehe ich da ebenfalls einen 12 MHz> Quarz. Wie kann dann da die Taktung zu hoch sein? Mit dem LPC können> Quarze bis 20 MHz betrieben werden. Wo liegt hier die Ursache?>> Wie kann man sich das erklären, dass ja eigentlich nichts richtig geht,> jedoch mit einer Dauerschleife um die for-Schleife sind alle 3 Bytes> sichtbar und beliebig einstellbar.> Das sind meine Feststellungen die ich heute gemacht habe.>> Für mich sind da manche Dinge ein richtiges Phänomen. Wie kann man sich> das erklären?> Ist daran alleine der Emulator schuld?> Falls ja, weshalb?> Weshalb benutze ich einen Emulator, der dann Schwierigkeiten macht.
Keine Ahnung. Ich würde es eben noch mal ohne Emulator mit Flashmagic
probieren, ob es sich genauso verhält.
Ciao,
Rainer
Morgen Rainer,
auf der Seite 142 steht, dass durch TRIM 0x96 Einstellungen gemacht
werden können. TRIM.0 bis TRIM.5 sind Werkseinstellungen. Diese sind vom
Werk eingestellte Werte. Ich habe diese vermutlich gelöscht, weil ich
das ENCLK aktivieren wollte. Dabei habe ich die falsche Mskierung
angewendet.
Die Werte der TRIM kann im Data Flash abgelegt werden.
Befindet sich dieses Flash in der Start900.a51 Datei?
Hab dort schon gesucht hab leider nichts gefunden.
Weißt du wo man die Werte einstellen kann?
Kannst du mir evtl. deine Werte sagen, damit ich sie wieder bei mir
einstellen kann.
MfG Tim
Hab noch etwas vergessen und zwar siehe Bild.
Sieht man die Power On Initialization of Memory speziell, die Data
Memory length. Diese habe ich von 0x100 auf 0x000 gesetzt damit das
auszuführende Programm nicht in die Startdatei springt.
Was bedeutet nun die Adresse 0x100?
Es werden erst ab dieser Adresse abgelegt?
Weshalb springt es bei 0x00 nicht mehr in die Startdatei?
Da finde ich leider keinen Zusammenhang.
Vielen herzlichen Dank für die Beantwortung.
Die Triggerung war ein sehr guter Tipp.
Das ist auch verständlich, weil mit Pull-Up auf 5 Volt hochgezogen wird.
Erst wenn die Bits gesendet werden springt der Pegel auf Low. Deshalb
ist eine Triggerung auf fallende Flanke sehr sinnvoll.
Im MAP001 sieht man nun 3 gesendete Bytes 0x00, 0xAA, 0xFF
Es sind alle Werte von 0x00 bis 0xFF einstellbar.
Jetzt muss ich nur noch die Baudrate von 31250 Baud herstellen.
Dazu muss ich das mal mit Flashmagic versuchen.
Ist das normal, dass der 5 Volt Pegel nur noch auf 4 Volt hochkommt?
Betreibe ich den TXD Ausgang ohne Pull-Up Widerstand so kommt MAP002
zustande. Welcher Betrieb mit TXD ist in der Praxis sinnvoller? Mit oder
ohne Pull-Up Widerstand? Welche Betriebsart ist die sinnvollste die man
hier einstellen sollte? Weil wenn nichts gemacht wird liegt 5 Volt an.
Da könnte evtl. ein Strom in den LPC hineinfließen.
Du meintest doch auch, dass es eine Anleitung gibt wie ich das Programm
ohne Emulator auf den LPC bringe.
Wo stand das nochmals? In der Beschreibung vom Experimentierboard?
Mit Flashmagic kann nur das Programm übertragen werden.
Gibt es auch dazu ein Terminalprogramm, wo man ein wenig was sehen kann?
Angenommen ich habe die Übertragung erfolgreich ausgeführt.
Dann hänge ich mein Tastkopf auf Pin P1.0 (TXD) und schalte die
Versorgungsspannung des Experimentierboards ein und aus, dann sollten
auch 3 Bytes sichtbar sein und diese dann mit 31250 Baud?
Also auf was ich raus möchte ist.
Mit dem Emulator kann ich ja alles so bedienen wie mit der Simulation.
Wenn allerdings die Software direkt im LPC ist habe ich ja keinen
Zugriff mehr über uVision. Würdest du dann so vorgehen, um etwas zu
messen, wie ich bereits oben geschrieben habe?
Danke für die Antwort.
Eventuell habe ich heute schon eine Lösung gefunden.
Ich wäre dir trotzdem für deine Antworten dankbar.
In diesem Sinn wünsche ich dir ein schönes Wochenende.
Schlagzeuger schrieb:> Morgen Rainer,> auf der Seite 142 steht, dass durch TRIM 0x96 Einstellungen gemacht> werden können. TRIM.0 bis TRIM.5 sind Werkseinstellungen. Diese sind vom> Werk eingestellte Werte. Ich habe diese vermutlich gelöscht, weil ich> das ENCLK aktivieren wollte. Dabei habe ich die falsche Mskierung> angewendet.> Die Werte der TRIM kann im Data Flash abgelegt werden.> Befindet sich dieses Flash in der Start900.a51 Datei?> Hab dort schon gesucht hab leider nichts gefunden.> Weißt du wo man die Werte einstellen kann?> Kannst du mir evtl. deine Werte sagen, damit ich sie wieder bei mir> einstellen kann.
TRIM ist ein normales SFR, welches nach einem Reset den ursprünglichen
Wert wieder enthält. Du kannst es zur Laufzeit deines Programms
verändern, aber nicht permanent speichern. Der Hinweis mit dem Data
Flash ist nur dafür da, dass du diesen Wert nach dem Ausmessen dort
hinterlegen kannst um diesen nach einem Reset wieder erneut zu laden.
Schlagzeuger schrieb:> Die Triggerung war ein sehr guter Tipp.> Das ist auch verständlich, weil mit Pull-Up auf 5 Volt hochgezogen wird.> Erst wenn die Bits gesendet werden springt der Pegel auf Low. Deshalb> ist eine Triggerung auf fallende Flanke sehr sinnvoll.> Im MAP001 sieht man nun 3 gesendete Bytes 0x00, 0xAA, 0xFF> Es sind alle Werte von 0x00 bis 0xFF einstellbar.
Na also, geht doch. :)
> Jetzt muss ich nur noch die Baudrate von 31250 Baud herstellen.> Dazu muss ich das mal mit Flashmagic versuchen.> Ist das normal, dass der 5 Volt Pegel nur noch auf 4 Volt hochkommt?
Wieso 5V?
Der Controller arbeitet mit 3,3V und deshalb solltest du auch keine
Pull-Ups auf 5V benutzen, wenn es sich vermeiden lässt. Die Eingänge
sind zwar 5V tolerant, aber du hast den Pull-Up ja an einem Ausgang und
nicht Eingang dran. Das ist nicht gut.
> Betreibe ich den TXD Ausgang ohne Pull-Up Widerstand so kommt MAP002> zustande. Welcher Betrieb mit TXD ist in der Praxis sinnvoller? Mit oder> ohne Pull-Up Widerstand? Welche Betriebsart ist die sinnvollste die man> hier einstellen sollte? Weil wenn nichts gemacht wird liegt 5 Volt an.> Da könnte evtl. ein Strom in den LPC hineinfließen.
Ausgänge werden generell ohne Pull-Up betrieben. Die Betriebart für
RXD sollte Input-only oder Quasi-Bidirektional und für TXD
Quasi-Bidirektional oder Push-Pull sein. Es gehen auch andere
Kombinationen, aber diese funktionieren ziemlich gut.
> Du meintest doch auch, dass es eine Anleitung gibt wie ich das Programm> ohne Emulator auf den LPC bringe.> Wo stand das nochmals? In der Beschreibung vom Experimentierboard?
Genau, im Handbuch zu deinem Experimentierboard. Ich hatte mir das PDF
mal von der Keil Homepage heruntergeladen gehabt.
> Mit Flashmagic kann nur das Programm übertragen werden.> Gibt es auch dazu ein Terminalprogramm, wo man ein wenig was sehen kann?
Du kannst die RS232 von deinem Experimentierboard mit einem Kabel an
deinen PC anschließen und dort ein Terminalprogramm laufen lassen. Ob
dies nun ein gedrehtes Kabel oder 1:1 durchgeschleift sein muss sollte
ebenfalls in dem Handbuch stehen.
> Angenommen ich habe die Übertragung erfolgreich ausgeführt.> Dann hänge ich mein Tastkopf auf Pin P1.0 (TXD) und schalte die> Versorgungsspannung des Experimentierboards ein und aus, dann sollten> auch 3 Bytes sichtbar sein und diese dann mit 31250 Baud?
Es reicht auch schon, wenn du den Reset Taster auf dem Board betätigst
anstatt die Versorgungsspannung zu trennen.
> Also auf was ich raus möchte ist.> Mit dem Emulator kann ich ja alles so bedienen wie mit der Simulation.> Wenn allerdings die Software direkt im LPC ist habe ich ja keinen> Zugriff mehr über uVision. Würdest du dann so vorgehen, um etwas zu> messen, wie ich bereits oben geschrieben habe?
Das ist ein vernünftiger Weg es so zu analysieren.
Ciao,
Rainer
Fox Mulder schrieb:> TRIM ist ein normales SFR, welches nach einem Reset den ursprünglichen> Wert wieder enthält. Du kannst es zur Laufzeit deines Programms> verändern, aber nicht permanent speichern. Der Hinweis mit dem Data> Flash ist nur dafür da, dass du diesen Wert nach dem Ausmessen dort> hinterlegen kannst um diesen nach einem Reset wieder erneut zu laden.
1)wenn TRIM ein SFR ist, dann steht es im Datenspeicher.
2)SFR sind immer flüchtige Speicher?
3)TRIM nimmt nach Reset den Wert wieder an: Welchen Wert, den des
Werkes?
4)Das Data Flash ist ein SFR?
5)Die Sache mit dem Ausmessen und hinterlegen verstehe ich nicht.
Wenn ich etwas hinterlegen kann und nach dem Reset wiederzugreifen kann,
dann ist es kein flüchtiger Speicher mehr.
Außerdem wären doch die Einstellungen vom Werk dann überschrieben.
6) Wie kann ich in dem Data Flash etwas hinterlegen TRIM 0x96?
Bin da jetzt etwas verwirrt worden. Kannst du das wieder entwirren.
Einmal ist ja die Rede, dass nach dem Reset den ursprünglichen Wert
annimmt z.B. Werkeinstellungen andernseits kann nach dem Reset wieder
etwas geladen werden. Dann ist aber der vorherige Wert weg. Ich hoffe,
dass du mein Problem auch siehst.
> Wieso 5V?> Der Controller arbeitet mit 3,3V und deshalb solltest du auch keine> Pull-Ups auf 5V benutzen, wenn es sich vermeiden lässt. Die Eingänge> sind zwar 5V tolerant, aber du hast den Pull-Up ja an einem Ausgang und> nicht Eingang dran. Das ist nicht gut.
Das Experimentierboard hat 3 Widerstandsnetzwerke a 10kOHm auf Vcc
hängen.
Auf dem TXD Pin hängt auch ein Widerstandsnetzwerk.
Diese sind allerdings steckbar. Das würde bedeuten, dass ich mit dem
Arbeiten der UART diese abziehe.
Wie verhält sich der Signalzustand wenn auf der UART ein Signal
ausgegeben wird:
1) geht der High-Pegel auf Low Pegel wenn ein Zeichen gesendet wird?
2) oder geht der Low Pegel auf High Pegel wenn ein Zeichen gesendet
wird?
Anders gesagt, wenn das Startbit kommt war das Signal zuvor noch auf
Low.
Nach dem Senden des Bytes kommt das Stoppbit, danach ist das Sigal auf
High-Pegel und bleibt dort bis wieder ein Startbit kommt.
Ist diese These richtig, dann ist nämlich die Aussage 2) richtig!?
Schlagzeuger schrieb:> Fox Mulder schrieb:>> TRIM ist ein normales SFR, welches nach einem Reset den ursprünglichen>> Wert wieder enthält. Du kannst es zur Laufzeit deines Programms>> verändern, aber nicht permanent speichern. Der Hinweis mit dem Data>> Flash ist nur dafür da, dass du diesen Wert nach dem Ausmessen dort>> hinterlegen kannst um diesen nach einem Reset wieder erneut zu laden.> 1)wenn TRIM ein SFR ist, dann steht es im Datenspeicher.> 2)SFR sind immer flüchtige Speicher?> 3)TRIM nimmt nach Reset den Wert wieder an: Welchen Wert, den des> Werkes?> 4)Das Data Flash ist ein SFR?> 5)Die Sache mit dem Ausmessen und hinterlegen verstehe ich nicht.> Wenn ich etwas hinterlegen kann und nach dem Reset wiederzugreifen kann,> dann ist es kein flüchtiger Speicher mehr.> Außerdem wären doch die Einstellungen vom Werk dann überschrieben.> 6) Wie kann ich in dem Data Flash etwas hinterlegen TRIM 0x96?> Bin da jetzt etwas verwirrt worden. Kannst du das wieder entwirren.> Einmal ist ja die Rede, dass nach dem Reset den ursprünglichen Wert> annimmt z.B. Werkeinstellungen andernseits kann nach dem Reset wieder> etwas geladen werden. Dann ist aber der vorherige Wert weg. Ich hoffe,> dass du mein Problem auch siehst.
SFR liegen immer im RAM (flüchtig). Nur ein paar wenige
Konfigurationsregister liegen im Flash (nicht flüchtig). Alle SFR im Ram
verlieren ihren aktuellen Inhalt nach einem Reset oder Powercycle und
werden mit den default Werten geladen (diese stehen im Datenblatt).
Beim TRIM Register sind die default Werte bei der Herstellung hinterlegt
worden und nach einem Reset aktiv. Du kannst aber durch dein Programm
natürlich im Flash auch einen eigenen Wert permanent speichern, welchen
du aber manuell in deinem Programm nach dem Start in das TRIM Register
erst wieder schreiben musst.
>> Wieso 5V?>> Der Controller arbeitet mit 3,3V und deshalb solltest du auch keine>> Pull-Ups auf 5V benutzen, wenn es sich vermeiden lässt. Die Eingänge>> sind zwar 5V tolerant, aber du hast den Pull-Up ja an einem Ausgang und>> nicht Eingang dran. Das ist nicht gut.> Das Experimentierboard hat 3 Widerstandsnetzwerke a 10kOHm auf Vcc> hängen.> Auf dem TXD Pin hängt auch ein Widerstandsnetzwerk.> Diese sind allerdings steckbar. Das würde bedeuten, dass ich mit dem> Arbeiten der UART diese abziehe.
Genau, ohne Widerstände dran ist es richtig.
> Wie verhält sich der Signalzustand wenn auf der UART ein Signal> ausgegeben wird:> 1) geht der High-Pegel auf Low Pegel wenn ein Zeichen gesendet wird?> 2) oder geht der Low Pegel auf High Pegel wenn ein Zeichen gesendet> wird?>> Anders gesagt, wenn das Startbit kommt war das Signal zuvor noch auf> Low.> Nach dem Senden des Bytes kommt das Stoppbit, danach ist das Sigal auf> High-Pegel und bleibt dort bis wieder ein Startbit kommt.> Ist diese These richtig, dann ist nämlich die Aussage 2) richtig!?
Das Startbit ist immer eine 0 und das Stopbit eine 1. Wenn du genauere
Infos zur RS232 haben willst ist google dein Freund. ;)
Ciao,
Rainer
Hallo Rainer,
jetzt mal konkreter:
ich hab das Trimm mit einer UND Maskierung unabsichtlich auf 0x40
gesetzt.
Mit einer UND Maskierung werden Bits gezielt gelöscht. Ich habe
folgendes durchgeführt:
anl TRIM, #0x40
Sind nun die Werkseinstellungen nach dem Reset wieder da oder nicht.
[5] The only reset source that affects these SFRs is power-on reset.
[6] On power-on reset, the TRIM SFR is initialized with a factory
preprogrammed value. Other resets will not cause initialization of the
TRIM register.
Laut [5] und [6] sind diese wieder da und ich muss mir keine Sorgen
machen.
Das siehst du doch auch so?
------------------------------------------------------------
Sieht man die Power On Initialization of Memory speziell (Bild siehe
17.11.2012 03:20), die Data
Memory length. Diese habe ich von 0x100 auf 0x000 gesetzt damit das
auszuführende Programm nicht in die Startdatei springt.
Was bedeutet nun die Adresse 0x100?
Es werden erst ab dieser Adresse abgelegt?
Weshalb springt es bei 0x00 nicht mehr in die Startdatei?
Da finde ich leider keinen Zusammenhang.
----------------------------------------------------------
Laut diesem Bild:
http://www.societyofrobots.com/images/microcontroller_uart_async.gif
Befindet sich links vom Startbit ein high- Pegel.
Da dies bei mir nicht der Fall ist müßte ich das Ausgangssignal auf
einen Inverter schicken?
---------------------------------------------------------------------
Welches Teriminalprogramm würdest du Flashmagic verwenden?
Nachtrag.
Ich hab jetzt nochmals den Synthesizer ausgemessen.
Wenn man nicht spielt sieht man, dass ein High-Pegel von ca.4 Volt
anliegt und ca. alle 20ms kommt eine fallende Flanke. (Bild Synth ohne)
Also wenn der von Haus aus High-Pegel hat müßte ich das doch bei meinen
Projekt auch anpassen?
Sind die 20ms irgendwelche Abfragebits oder keine Ahnung.
Hast du da evtl. eine Idee, was das sein kann?
Bild Synth spielen zeigt, dann ein gesendetes MIDI-Byte. Dieses Signal
hast du schon mal ausgewertet. ( Autor: Fox Mulder (quakeman)
Datum: 04.11.2012 12:32 )
Danke für deine Auskunft
So schaut mein Schaltungsentwurf aus.
Die Konstantstromquelle liefert immer 5mA und versort auf PIN4 MIDI
Buchse den Optokoppler. Schaltet der LPC TXD auf GND so ist über die
MIDI Buchse PIN 5 der Stromkreis zum Optokoppler geschlossen und die
Mididaten können fließen. Strom an bedeutet logisch 0 und Strom aus
bedeutet logisch 1.
Das heißt, dass ich entweder den Ausgang vom LPC invertieren muss, weil
Pull-UP sagst du sei ja nicht so gut.
Durch ein Low Singal am TXD vom LPC werden kann der Optokoppler
arbeiten.
So müßte es funktionieren, siehst du das auch so?
Jetzt sind es 3 Einträge wäre nett, wenn du diese beantworten könntest.
Ich schau jetzt mal wie das mit Flashmagic und so geht.
Danke dir. Ich wünsch dir noch eine schönes Wochenende.
MfG Tim
Schlagzeuger schrieb:> Hallo Rainer,>> jetzt mal konkreter:> ich hab das Trimm mit einer UND Maskierung unabsichtlich auf 0x40> gesetzt.> Mit einer UND Maskierung werden Bits gezielt gelöscht. Ich habe> folgendes durchgeführt:> anl TRIM, #0x40>> Sind nun die Werkseinstellungen nach dem Reset wieder da oder nicht.>> [5] The only reset source that affects these SFRs is power-on reset.> [6] On power-on reset, the TRIM SFR is initialized with a factory> preprogrammed value. Other resets will not cause initialization of the> TRIM register.>> Laut [5] und [6] sind diese wieder da und ich muss mir keine Sorgen> machen.> Das siehst du doch auch so?
Nach einem Powercycle sind wieder die Werkseinstellungen da. Nach einem
Reset per Reset Leitung wird das TRIM scheinbar nicht verändert. Dachte
das wäre auch so, aber nun ist es ja geklärt. Also Strom weg und wieder
dran und alles ist zurückgesetzt.
> ------------------------------------------------------------> Sieht man die Power On Initialization of Memory speziell (Bild siehe> 17.11.2012 03:20), die Data> Memory length. Diese habe ich von 0x100 auf 0x000 gesetzt damit das> auszuführende Programm nicht in die Startdatei springt.>> Was bedeutet nun die Adresse 0x100?> Es werden erst ab dieser Adresse abgelegt?> Weshalb springt es bei 0x00 nicht mehr in die Startdatei?> Da finde ich leider keinen Zusammenhang.
Ich habe dir schon einmal geschrieben gehabt, dass 0x100 keine Adresse
sondern eine Länge ist. Diese gibt an, wieviele Bytes im RAM mit 0
initialisiert werden sollen. 0x100 = 256 Bytes. Damit wird der interne
Ram von der Adresse 0x00 bis 0xFF gelöscht. Wenn dieser Wert 0 ist, dann
braucht der interne Ram nicht gelöscht zu werden und somit gibt es
keinen Code in der Start900.a51 der ausgeführt werden soll. Also muss
auch nicht in diese Datei am Anfang reingesprungen werden.
> ----------------------------------------------------------> Laut diesem Bild:> http://www.societyofrobots.com/images/microcontroller_uart_async.gif> Befindet sich links vom Startbit ein high- Pegel.> Da dies bei mir nicht der Fall ist müßte ich das Ausgangssignal auf> einen Inverter schicken?
Du hast in beiden Bildern einen High-Pegel links von deinem Startbit. Im
zweiten Bild wird dieser erst kurz vor dem Senden des Bytes eingestellt
durch die kurze positive Flanke. Um von Anfang an den High-Pegel zu
haben kannst du z.B. den TXD Pin einmalig auf 1 setzen während der
Initialisierung der Portpins. Sobald die Uart Daten sendet hält sie den
Pin dann automatisch auf High-Pegel.
> ---------------------------------------------------------------------> Welches Teriminalprogramm würdest du Flashmagic verwenden?
Also dieser Satz bedarf einer etwas besseren Rechtschreibung. ;)
Ich benutze das opensource Programm "Realterm", welches du per Google
schnell finden kannst.
Schlagzeuger schrieb:> Nachtrag.> Ich hab jetzt nochmals den Synthesizer ausgemessen.> Wenn man nicht spielt sieht man, dass ein High-Pegel von ca.4 Volt> anliegt und ca. alle 20ms kommt eine fallende Flanke. (Bild Synth ohne)>> Also wenn der von Haus aus High-Pegel hat müßte ich das doch bei meinen> Projekt auch anpassen?
Nein, siehe vorherige Erklärung dazu.
> Sind die 20ms irgendwelche Abfragebits oder keine Ahnung.> Hast du da evtl. eine Idee, was das sein kann?
Nein, kenne mich mit dem Gerät nicht aus.
Schlagzeuger schrieb:> So schaut mein Schaltungsentwurf aus.> Die Konstantstromquelle liefert immer 5mA und versort auf PIN4 MIDI> Buchse den Optokoppler. Schaltet der LPC TXD auf GND so ist über die> MIDI Buchse PIN 5 der Stromkreis zum Optokoppler geschlossen und die> Mididaten können fließen. Strom an bedeutet logisch 0 und Strom aus> bedeutet logisch 1.> Das heißt, dass ich entweder den Ausgang vom LPC invertieren muss, weil> Pull-UP sagst du sei ja nicht so gut.> Durch ein Low Singal am TXD vom LPC werden kann der Optokoppler> arbeiten.> So müßte es funktionieren, siehst du das auch so?
Schau dir mal die Schaltpläne unter [1] an. Dort findest du eine sehr
einfache und funktionierende Variante, wie du einen Mikrocontroller an
den Midi Bus anschließen kannst. Die benötigte Invertierung der
eingehenden und ausgehenden Daten ist dabei schon integriert.
Denn wenn der Txd Ausgang auf Low-Pegel (logisch 0) steht fließt der
Strom durch den Optokoppler auf der Gegenseite. Und der Rxd Eingang
liegt ebenfalls auf Low-Pegel (logisch 0), wenn von der Gegenseite Strom
auf die Leitung gegeben wird. Das entspricht genau der Definition des
Midi Bus
Ciao,
Rainer
[1] www.mikrocontroller.net/articles/Midi_Rekorder_mit_MMC/SD-Karte
Ich dank dir soweit Rainer.
Wenn ich Flashmagic betreiben möchte benötige ich ein Crossoverkabel
(Nullmodemkabel, wobei RX und TX getauscht sind).
Solch ein Kabel muss ich mir erst noch besorgen.
Hast du eigentlich auch das Experimentierboard wie ich ohne Emulator?
Danke nochmals für deine Antworten.
Ich wünsch dir noch einen schönen Sonntag.
Schlagzeuger schrieb:> Ich dank dir soweit Rainer.> Wenn ich Flashmagic betreiben möchte benötige ich ein Crossoverkabel> (Nullmodemkabel, wobei RX und TX getauscht sind).> Solch ein Kabel muss ich mir erst noch besorgen.
Selber bauen. Es sind gerade mal drei Kabel die du verlöten musst pro
Seite. ;)
> Hast du eigentlich auch das Experimentierboard wie ich ohne Emulator?
Nein, ich hatte mir damals selber ein Experimentierboard gebaut gehabt.
Ciao,
Rainer
Hallo Rainer,
ich hab mal eine Frage zum SCON.
Obwohl ich im Programm SCON = 0x40 (Betriebsart 1) lade steht nach dem
Run-Durchlauf das SCON auf 0x42. Buch S.194 oben sieht man das SCON
Register. Wandelt man den 0x42 Wert in Binär um so erhält man 1000010.
Das bedeutet, dass hier das TI Flag von 0 auf 1 gesetzt wurde.
Ist das normal?
Ein Vermutung von mir ist, dass es automatisch auf 1 gesetzt wurde, weil
das Senderegister leer wurde, indem die 3 Bytes gesendet worden sind.
Ist meine Vermutung richtig?
----------------------------------------------------
Ich möchte jetzt mal die Baudrate mit dem internen RC- Oszillator
nochmals testen.
Baudrate = (CCLK) / (BRGR1 * 256 + BRGR0 + 16 )
= (7,3738 MHz) / ( 0 * 256 + 220 + 16 )
= 7,3738 MHz / 236
Baudrate = 31244,91 Bauds
BRGR1 = 0x00
BRGR0 = 0xDC
Das wäre dann eine Abweichung von 0,016288%
Ist diese Aussage richtig, wenn MIDI eine Baudrate von 31250 Baud hat.
Somit bin ich noch innerhalb der 2% Toleranz.
Bei der RS232 liegt die maximal erlaubte Abweichung der Baudrate bei ca.
2%. => Hast du mir da bitte noch eine Quelle, wo du die 2% gefunden
hast.
Kann man bei MIDI auch von 2% ausgehen?
Dank dir
Hallo Rainer,
hab noch etwas vergessen:
Um von Anfang an den High-Pegel an der UART zu
haben kannst du z.B. den TXD Pin einmalig auf 1 setzen während der
Initialisierung der Portpins.
Wie kann man das machen? Ich komm da einfach nicht drauf.
Danke für deine Hilfe.
Hallo Rainer,
habe mal bei der Midi Association,http://www.midi.org/, nachgefragt.
Da hieß es:
The acceptable tolerance is not specified numerically in MIDI.
Rather, a suggested circuit is specified, and therefore the
acceptable amount of tolerance can be determined based on the
known tolerance of the components in that circuit, combined
with common sense.
Das einzige was festgelegt wurde ist das bereits bekannte:
http://www.midi.org/techspecs/electrispec.php
Über eine 2% Toleranz bei UART hab ich noch nichts gefunden.
Schlagzeuger schrieb:> ich hab mal eine Frage zum SCON.> Obwohl ich im Programm SCON = 0x40 (Betriebsart 1) lade steht nach dem> Run-Durchlauf das SCON auf 0x42. Buch S.194 oben sieht man das SCON> Register. Wandelt man den 0x42 Wert in Binär um so erhält man 1000010.> Das bedeutet, dass hier das TI Flag von 0 auf 1 gesetzt wurde.> Ist das normal?> Ein Vermutung von mir ist, dass es automatisch auf 1 gesetzt wurde, weil> das Senderegister leer wurde, indem die 3 Bytes gesendet worden sind.> Ist meine Vermutung richtig?
Korrekt. Deshalb hab ich in der Schleife ja vor dem Senden die Zeile TI
= 0; drin gehabt um das Flag vorher zu löschen. Ansonsten funktioniert
die while(!TI) Prüfung ja nicht korrekt.
> ----------------------------------------------------> Ich möchte jetzt mal die Baudrate mit dem internen RC- Oszillator> nochmals testen.> Baudrate = (CCLK) / (BRGR1 * 256 + BRGR0 + 16 )> = (7,3738 MHz) / ( 0 * 256 + 220 + 16 )> = 7,3738 MHz / 236> Baudrate = 31244,91 Bauds>> BRGR1 = 0x00> BRGR0 = 0xDC>> Das wäre dann eine Abweichung von 0,016288%> Ist diese Aussage richtig, wenn MIDI eine Baudrate von 31250 Baud hat.> Somit bin ich noch innerhalb der 2% Toleranz.
CCLK ist 7,373MHz oder 7,3728MHz, je nachdem, wo man im Datenblatt
schaut. Aber nicht 7,3738MHz. ;)
Also mit einem Reloadwert von 220 hättest du dann 7,3728 MHz / 236 =
31240,68Bps. Das ist dann eine Abweichung von 0,03% und somit völlig
akzeptabel.
> Bei der RS232 liegt die maximal erlaubte Abweichung der Baudrate bei ca.> 2%. => Hast du mir da bitte noch eine Quelle, wo du die 2% gefunden> hast.>> Kann man bei MIDI auch von 2% ausgehen?
Midi basiert ja auf der ursprünglichen RS232, womit die gleichen Regeln
gelten. Die maximal erlaubte Abweichung von 1%-2% findet man hin und
wieder in manchen Beschreibungen der RS232 im Internet. Aber eine
definitive Aussage scheint es dort auch nicht zu geben. Man sollte also
einfach nur versuchen möglichst darunter zu bleiben, was mit 0,03% ja
definitiv der Fall ist. :)
Schlagzeuger schrieb:> Hallo Rainer,> hab noch etwas vergessen:> Um von Anfang an den High-Pegel an der UART zu> haben kannst du z.B. den TXD Pin einmalig auf 1 setzen während der> Initialisierung der Portpins.> Wie kann man das machen? Ich komm da einfach nicht drauf.
Naja, du musst einfach nur den Pin auf 1 setzen.
Hier ein Beispiel:
1
#include<REG935.H>
2
sbittxd=P1^0;
3
4
voidmain()
5
{
6
unsignedchari,MIDIstream[]={0x9F,0x28,0x7F};
7
8
P1M1=0x00;
9
P1M2=0x00;
10
txd=1;// TXD Pin auf High-Pegel legen
11
SCON=0x40;
12
BRGR0=0xDC;// Reloadwert für internen RC Oszillator
13
BRGR1=0x00;// Reloadwert für internen RC Oszillator
Rainer ich dank dir soweit.
Was sagst du über die Antwort von der MIDI Association?
Anscheinend ist da ja nichts festgelegt.
Betrachtet man die Auswertung vom Autor: Fox Mulder (quakeman)
Datum: 04.11.2012 12:32, dann sieht man hier nur die Bytes bei einem
MIDI "Note on" Befehl.
Ich hab jetzt nochmals bei dem Synthesizer nachgemessen.
Siehe passende Bilder vom Autor: Schlagzeuger (Gast)
Datum: 17.11.2012 17:46
Dort sieht man, dass generell ein High Pegel anliegt und dass alle 20ms
eine fallende Flanke kommt. Löse ich die Zeitachse im Oszi größer auf so
kann man keine weiteren Bitfolgen sehen. Das Signal ist an dieser Stelle
generall auf Low-Pegel.
Was ich damit sagen möchte ist, dass ich in dem Roland Syntesizer nie
einen "Note off" Befehl sehen kann.
Jetzt frage ich mich wie die den Ton abschalten?
--------------------------------------------------------------
Theorie:
Abschalten kann ich, indem ich nochmals den "note on" Befehl mit einer
Lautstärke von 0x00 sende oder den seperaten Befehl "note off" verwende.
In der Praxis wird die Ausschaltung mit Lautstärke 0x00 gemacht.
------------------------------------------------------------------
Damit die Sendung meiner Bytes erfolgreich funktioniert sollte ich hier
in dem Projekt nur mit Interrupts arbeiten? Was meinst du dazu?
Ich könnte jetzt in einen Interrupt die Bytes packen für die "Note on"
und im main ( ) in der Schleife die Bytes packen zum Aussschalten.
Die Ausschaltung dürfte nicht Dauerhaft erfolgen sondern nach einer
bestimmten Zeit.
Die Zeitschleife könnte ich doch folgendermaßen erzeugen.
#define delay 2000
void main ( )
{
unsigned char i;
.
.
.
for ( i = 0; i < delay ; i++ );
.
.
.
}
Beim Assembler weiß ich, dass ein Befehl 1-3 Maschinenzyklen sein darf.
Daraus kann man mit dem fosz = 12 MHz genau die Dauer der Schleife
berechnen.
Wie kann ich die Zeit genau bei C bestimmen in Verbindung mit dem 12 MHz
Quarz? Da komm ich leider nicht drauf. Weißt du wie das geht?
Danke
MfG Tim
Schlagzeuger schrieb:> Rainer ich dank dir soweit.> Was sagst du über die Antwort von der MIDI Association?> Anscheinend ist da ja nichts festgelegt.
Das kann gut sein. Aber solange du nur solch geringe Abweichungen vom
Takt hast brauchst du dir da keine Gedanken zu machen.
> Damit die Sendung meiner Bytes erfolgreich funktioniert sollte ich hier> in dem Projekt nur mit Interrupts arbeiten? Was meinst du dazu?
Deine Schlussfolgerung, weshalb du in diesem Fall speziell Interrupts
benutzen sollst, verstehe ich nicht.
> Die Zeitschleife könnte ich doch folgendermaßen erzeugen.>> #define delay 2000> void main ( )> {> unsigned char i;> .> .> .> for ( i = 0; i < delay ; i++ );> .> .> .> }> Beim Assembler weiß ich, dass ein Befehl 1-3 Maschinenzyklen sein darf.> Daraus kann man mit dem fosz = 12 MHz genau die Dauer der Schleife> berechnen.>> Wie kann ich die Zeit genau bei C bestimmen in Verbindung mit dem 12 MHz> Quarz? Da komm ich leider nicht drauf. Weißt du wie das geht?
Du kannst, um eine genaue Zeitverzögerung hinzubekommen, den eingebauten
RTC benutzen. Dieser wird mit CCLK/128 getaktet und ist 16Bit breit.
Somit kannst du bei 12MHz Verzögerungen im Bereich von 10,67µS bis zu
0,699s erreichen, je nach Reloadwert. Ich benutze z.B. den RTC für
Delays folgendermassen:
1
voidv_Sleep_RTC(unsignedintuiSleepTime){
2
RTCL=uiSleepTime&0xFF;
3
RTCH=uiSleepTime>>8;
4
5
// Timeout Zähler starten
6
RTCCON=RTCCON|1;
7
8
// Unterlauf Flag abfragen
9
while(!(RTCCON&0x80));
10
11
// Timeout Zähler stoppen und Unterlauf Flag löschen
12
RTCCON=RTCCON&0x7E;
13
}
Diese Methode rufst du dann an den Stellen im Code auf, an welcher du
ein Delay brauchst. Der Übergabewert (16Bit) bestimmt dann die
Verzögerungszeit abhängig vom verwendeten Quarz oder RC Oszillator.
Ciao,
Rainer
Fox Mulder schrieb:>> Damit die Sendung meiner Bytes erfolgreich funktioniert sollte ich hier>> in dem Projekt nur mit Interrupts arbeiten? Was meinst du dazu?> Deine Schlussfolgerung, weshalb du in diesem Fall speziell Interrupts> benutzen sollst, verstehe ich nicht.
Würdest du die Sache dann mit Bitbefehle lösen?
z.B.:
sbit Taster = P1^3;
if (!Taster)
{
hier steht dann der Quellcode um den Synthesizer einzuschalten
}
if (Taster == 1)
{
delay RTC
hier steht der Quellcode um den Synthesizer auszuschalten
}
Unterprogrogramm delay mt RTC
-------------------------------------
Seite 230 heißt es bei RTCF 23 bit timer usw. Ist das hier ein Fehler?
Müßte doch 16 bit heißen.
void v_Sleep_RTC(unsigned int uiSleepTime) Ich versteh hier unsigned int
uiSleepTime in der Klammer nicht.
Normalerweise ist die Klammer leer oder steht ein Zeiger drin. Den Sinn
verstehe ich hier leider nicht.
So kann man es doch auch schreiben? Dann macht es Sinn und ich versteh
es. Deine Schreibweise kannte ich bis dato nicht.
void v_Sleep_RTC( )
{
unsigned int uiSleepTime;
RTCL = uiSleepTime & 0xFF;
RTCH = uiSleepTime >> 8;
}
Hab die Formel gefunden. Habs leider nicht geschafft die 10,67µS bis zu
0,699s nachzurechnen. Könntest du mir das bitte vorrechnen.
Bei dieser Zeile versteh ich leider auch nicht den Sinn wie es
funktioniert: RTCH = uiSleepTime >> 8;
Wie bist du auf die 8 gekommen und weshalb wesentlich größer als 8?
Könntest du das bitte erklären.
RTCL = uiSleepTime & 0xFF;
Hast du hier einfach den größten Wert genommen oder wurde das auch
berechnet?
Im Buch findet man über RTC nur 3 Seiten, diese habe ich alle gelesen
und konnte meine Fragen nicht beantworten.
Danke für deine Antworten Rainer.
Bis morgen eventuell.
Schlagzeuger schrieb:> Fox Mulder schrieb:>>> Damit die Sendung meiner Bytes erfolgreich funktioniert sollte ich hier>>> in dem Projekt nur mit Interrupts arbeiten? Was meinst du dazu?>> Deine Schlussfolgerung, weshalb du in diesem Fall speziell Interrupts>> benutzen sollst, verstehe ich nicht.>> Würdest du die Sache dann mit Bitbefehle lösen?> z.B.:> sbit Taster = P1^3;> if (!Taster)> {> hier steht dann der Quellcode um den Synthesizer einzuschalten> }>> if (Taster == 1)> {> delay RTC> hier steht der Quellcode um den Synthesizer auszuschalten> }>> Unterprogrogramm delay mt RTC
Ah ok, du meintest also, ob du die Taster per Interrupt abfragen sollst
oder nicht. Dafür sind Interrupts schon Sinnvoll. In der ISR setzt du
dann, abhängig davon, welche Taste gedrückt wurde, ein Bit und wertest
dieses in deinem Hauptprogramm dann aus.
> Seite 230 heißt es bei RTCF 23 bit timer usw. Ist das hier ein Fehler?> Müßte doch 16 bit heißen.
Der Timer hat 16Bit, aber zusätzlich einen festen 7Bit Vorteiler.
Deshalb hatte ich ja geschrieben, dass der Takt CCLK/128 ist.
> void v_Sleep_RTC(unsigned int uiSleepTime) Ich versteh hier unsigned int> uiSleepTime in der Klammer nicht.> Normalerweise ist die Klammer leer oder steht ein Zeiger drin. Den Sinn> verstehe ich hier leider nicht.>> So kann man es doch auch schreiben? Dann macht es Sinn und ich versteh> es. Deine Schreibweise kannte ich bis dato nicht.> void v_Sleep_RTC( )> {> unsigned int uiSleepTime;> RTCL = uiSleepTime & 0xFF;> RTCH = uiSleepTime >> 8;> }
Also wenn du diese "Schreibweise" nicht verstehst solltest du wirklich
mal etwas mehr Codebeispiele im Buch durcharbeiten. Denn das ist einfach
nur eine Methode mit einem Übergabeparameter. Der Übergabeparameter ist
vom Typ "unsiged int" (16Bit) und hat den Namen "uiSleepTime" (beliebig
wählbar). Du rufst diese Methode im Hauptprogramm dann z.B. mit
v_Sleep_RTC(10000) auf, womit der RTC 10000 Takte herunter zählt bis er
auf 0 steht.
> Hab die Formel gefunden. Habs leider nicht geschafft die 10,67µS bis zu> 0,699s nachzurechnen. Könntest du mir das bitte vorrechnen.
Der Takt für den RTC ist 12MHz/128 = 93750Hz. Das sind gerundet 10,67µS
pro Takt und bei einem 16Bit Timer dann maximal 65536 * 10,67µS =
0,699s.
> Bei dieser Zeile versteh ich leider auch nicht den Sinn wie es> funktioniert: RTCH = uiSleepTime >> 8;> Wie bist du auf die 8 gekommen und weshalb wesentlich größer als 8?>> RTCL = uiSleepTime & 0xFF;> Hast du hier einfach den größten Wert genommen oder wurde das auch> berechnet?
">>" ist kein Vergleich sondern eine Bit-Schiebeoperation. Damit werden
alle Bits in der Variable um 8 Stellen nach rechts verschoben. Dadurch
werden die oberen 8 Bits an die Position der unteren 8 Bits gestellt.
Und die Operation "& 0xFF" maskiert die oberen 8 Bits der 16Bit Zahl
aus, womit nur die unteren 8Bits erhalten bleiben. Diese beiden Zeilen
machen nichts anderes als die 16Bit Zahl uiSleepTime in High- und
Low-Byte aufzuteilen.
Aber leider ich muss mal wieder sagen, dass es erschreckend ist, dass du
grundlegende Syntax der Methodendefinition sowie die Schiebeoperation
sowie Bitmaskierung nicht verstanden hast. Das lässt mich mal wieder
daran zweifeln, dass du schon soweit bist solch ein Programm selber auf
die Beine zu stellen. Du brauchst definitiv viel mehr Übung im
Programmieren in C. :(
Ich kann dir nicht jede einzelne Zeile Code immer wieder erklären. Du
solltest dir schon selber erst mal genug Programmierkenntnisse in C
aneignen, damit du überhaupt verstehst, wie man in C programmiert. Ich
bin kein Lehrer und habe deshalb nicht vor dir alles Schritt für Schritt
zu erklären.
Der Thread hier hat mittlerweile schon über 100 Beiträge und ich sehe
leider immer noch kein Land in Sicht für dich.
Ich verstehe auch wirklich nicht, wieso du nicht im Buch Kapitel 8
einfach mal durcharbeitest, bevor du hier weiter machst. Dort wird die
Programmierung in C von Grund auf erklärt inklusive dem meisten was ich
dir hier schon erklärt habe. Also bitte mach dies erst mal, bevor du
weiter versuchst auf Biegen und Brechen hier dein Projekt hin zu
bekommen.
Wenn du das Kapitel durch hast kannst du hier gerne weiter machen. :)
Ciao,
Rainer
Hallo Rainer,
ich bin wieder da. Hab jetzt mal das Kapital 8 durchgelesen. Dort war
leider kein Schiebebefehl erklärt. Mir ist jetzt aber bewußt wie dieser
funktioniert.
Deine Schreibweise habe ich so bis jetzt noch nicht gekannt:
RTCCON = RTCCON | 1;
Ich bin es so gewohnt:
RTCCON |= 1;
Bei der RTCL Maskierung habe ich anders gedacht als du:
dein Weg war: RTCL = uiSleepTime & 0xFF;
mein Weg war von der Denkweise: RTCL = uiSleepTime | 0x00;
Habs praktisch ausprobiert. Es geht beides. :-)
Meine Denkweisen und evtl. falsche Ausdrucksweise haben einst deine
Kritik gegen mich hervorgerufen.
In Zukunft werde ich mehr nachlesen und selber ausprobieren.
Wenn ich das mache darf ich mich doch dann jederzeit an dich wenden
Rainer?
Unklar ist mir bis jetzt nur noch eine Sache und zwar, siehe Bild UP.
Im Bild UP hab ich mal ein Unterprogramm mit Schiebebefehl geschrieben.
Funktioniert ohne Fehler.
Nun die eigentliche Frage:
Wo ist bei deiner RTC eigentlich die Prototypendeklaration?
Dein Quellcode funktioniert, allderings kann ich mir das nicht erklären
wie das ohne Prototypendeklaration funktionieren soll?
Kannst du mir das bitte erklären.
Weitere Frage:
Wieviel Zeilen darf ich bei einer ISR-Routine programmieren, ohne dass
ich Schwierigkeiten mit dem Hauptprogramm bekomme?
Danke dir Rainer
MfG Tim
Schlagzeuger schrieb:> Hallo Rainer,> ich bin wieder da. Hab jetzt mal das Kapital 8 durchgelesen. Dort war> leider kein Schiebebefehl erklärt. Mir ist jetzt aber bewußt wie dieser> funktioniert.
Das klingt doch schon mal gut.
> Deine Schreibweise habe ich so bis jetzt noch nicht gekannt:> RTCCON = RTCCON | 1;>> Ich bin es so gewohnt:> RTCCON |= 1;
Normalerweise benutze ich auch die Kurzschreibweise x |= y und nicht x =
x | y. Ich hatte es nur zum besseren Verständnis extra ausgeschrieben
gehabt. Grundsätzlich arbeiten beide Schreibweisen identisch.
> Bei der RTCL Maskierung habe ich anders gedacht als du:> dein Weg war: RTCL = uiSleepTime & 0xFF;> mein Weg war von der Denkweise: RTCL = uiSleepTime | 0x00;> Habs praktisch ausprobiert. Es geht beides. :-)
Hmm, da ist ein Denkfehler drin. Ich schreibe beide Zeilen mal in
Binärdarstellung hin, dann wird es klar:
Meine Zeile RTCL = uiSleepTime & 0000000011111111
Deine Zeile RTCL = uiSleepTime | 0000000000000000
In meiner Zeile werden die oberen 8 Bits in uiSleepTime auf 0 gesetzt
und die unteren 8 Bits bleiben erhalten. Somit habe ich im Ergebnis nur
noch das untere Byte.
In deiner Zeile bleiben alle 16 Bits erhalten, da eine "oder"
Verknüpfung mit 0 keine Auswirkung hat. Es kann sein, dass der Compiler
in deinem Fall automatisch erkennt, dass nur die unteren 8 Bits benutzt
werden sollen, weshalb das Ergebnis das Gleiche ist. Aber grundsätzlich
hat deine Zeile keine Auswirkung auf den Inhalt der Variablen.
> Meine Denkweisen und evtl. falsche Ausdrucksweise haben einst deine> Kritik gegen mich hervorgerufen.> In Zukunft werde ich mehr nachlesen und selber ausprobieren.> Wenn ich das mache darf ich mich doch dann jederzeit an dich wenden> Rainer?
Klaro.
> Unklar ist mir bis jetzt nur noch eine Sache und zwar, siehe Bild UP.> Im Bild UP hab ich mal ein Unterprogramm mit Schiebebefehl geschrieben.> Funktioniert ohne Fehler.>> Nun die eigentliche Frage:> Wo ist bei deiner RTC eigentlich die Prototypendeklaration?> Dein Quellcode funktioniert, allderings kann ich mir das nicht erklären> wie das ohne Prototypendeklaration funktionieren soll?> Kannst du mir das bitte erklären.
Also in deinem Beispiel liegt die Prototypdeklaration innerhalb der Main
Methode, was eigentlich nicht der richtige Platz ist. Üblicherweise
macht man diese direkt zu Beginn der C Datei nach den includes.
Jetzt aber zu der angenehmen Seite. Der Compiler ist mittlerweile schlau
genug um auch ohne Prototypdeklaration die passende Methode innerhalb
der gleichen C Datei zu finden und referenzieren. Also solange du nur
innerhalb einer C Datei arbeitest brauchst du keine Prototypdeklaration
mehr.
Arbeitest du mit mehreren C Dateien musst du wiederum die Methoden der
einen C Datei der anderen C Datei bekannt geben, insofern du diese dort
auch benötigst. Dies geschieht dann aber in einer Header Datei, welche
du per include einbindest. Dies wirst du aber erst später benötigen.
> Weitere Frage:> Wieviel Zeilen darf ich bei einer ISR-Routine programmieren, ohne dass> ich Schwierigkeiten mit dem Hauptprogramm bekomme?
Es gibt es die Empfehlung, dass man in einer ISR keinen langwierigen
Code ausführen sollte. Aber das ist alleine davon abhängig, wie dein
Programmablauf aufgebaut ist. Deshalb gibt es da auch keine festen
Regeln. Theoretisch kannst du dein gesamtes Programm in einer ISR
ablaufen lassen und in der main Methode ist nur eine Endlosschleife.
Andersherum kannst du auch in der ISR nur ein paar Bits setzen und diese
dann in der main Methode auswerten für deine Programmsteuerung.
Das ist also alleine dir überlassen, wie du in einer ISR arbeitest.
Ciao,
Rainer
Ich dank dir soweit Rainer.
Ich kann ich das in der Kurzschreibweise schreiben?
while (!(RTCCON & 0x80));
Ist es überhaupt möglich? Wenn ja, dann kannst es mir gerne
hinschreiben, weil ich nicht draufgekommen bin.
MfG
Tim
Schlagzeuger schrieb:> Ich kann ich das in der Kurzschreibweise schreiben?> while (!(RTCCON & 0x80));> Ist es überhaupt möglich? Wenn ja, dann kannst es mir gerne> hinschreiben, weil ich nicht draufgekommen bin.
Das ist eigentlich nur einfache boolsche Logik. Dafür gibt es keine
Kurzschreibweise. ;)
Erst werden mit RTCCON & 0x80 alle bis auf das höchste Bit auf 0
gesetzt. Dann wird mit !(..) geprüft, ob das Ergebnis gleich 0 ist. Dies
ist erfüllt, solange das Unterlauf Flag noch nicht gesetzt ist. Sobald
der RTC den Zählerstand 0 erreicht wird das höchste Bit in RTCCON
gesetzt und die Prüfung schlägt fehl. Somit wartet die Schleife solange,
bis der RTC auf 0 heruntergezählt hat.
Ciao,
Rainer
Besser hätte ich es nicht erklären können.
Danke dir. Mir war die Logik in dem Fall schon klar.
Ich dachte mir halt, ob es noch etwas kürzeres zu schreiben gibt.
Dies ist anscheinend nicht der Fall. Danke
--------------
Ich hab hier jetzt mal im Forum gesehen, dass Delay auch mit
festhinterlegen Funktionen geht. Ist das beim NXP nicht der Fall?
Bei Atmega ist und bei anderen Controllern ist das teilweise möglich.
Ich hab hier folgendes gefunden:
Beitrag "unter C die Funktion Sleep() nutzen"
In der Hilfe steht folgendes:
sleep
Summary void Sleep (ulong milliseconds) /* Delay script n milliseconds
*/
Description The sleep function may be used to delay script execution
in debug functions or signal functions. The sleep function is useful
to allow small delays in the script language execution and can be used
in simulation mode and target debugging mode.
Return Value None
Example The following script switches the oscillator on an ARM device
for fast download speed.
// Switching from Slow Clock to Main Oscillator for faster Downloading
_WDWORD(0xFFFF4020, 0x002F0002); // APMC_CGMR: Enable Main
Oscillator
_sleep_(10); // Wait for stable Main Oscillator
_WDWORD(0xFFFF4020, 0x002F4002); // APMC_CGMR: Switch to Main
Oscillator
Ich hab das mal ausprobiert. Leider geht es bei mir nicht.
Wozu gibt es dann die sleep Funktion, wenn es nicht geht?
In der Hilfe heißt es ja, dass die Ausführung durch eine Delay verzögert
werden kann.
Bin mal gespannt was du dazu zu sagen hast.
Danke dir
Bye Tim
Ich habe die Sleep Funktion nie benutzt gehabt. Hatte mir, wenn ich so
etwas brauchte, immer selber eine solche Funktion geschrieben gehabt.
Ich bin nämlich kein Freund davon fertige Funktionen zu benutzen, da ich
dabei nichts lerne. ;)
Dementsprechend kann ich dir zu der vorgefertigten Sleep Funktion nichts
sagen.
Ciao,
Rainer
Da geb ich dir recht Rainer.
Allerdings wäre es doch interessant zu wissen, ob die Funktion
tatsächlich funktioniert.
Das herauszufinden ist doch auch eine Herausforderung.
Ich habs versuch, leider bin ich gescheitert.
Welche Funktionen, die beim uVision Compiler hinterlegt sind gehen
überhaupt?
Angenommen ich hab eine Firma und nutz den Compiler, dann ist dem Kunden
es egal wie es funktioniert. Der Kunde möchte gute Ware für wenig Geld.
Wenn du etwas herausfinden kannst wäre es nett, ansonsten habe ich Pech
gehabt.
Danke dir
Hallo Rainer,
auf der Seite 143 sieht man die Beschaltung mit Quarz.
Wenn man die C weglässt funktioniert es trotzdem.
Im Datenblatt vom Quarz beträgt die load capacitance 10 bis 32pf.
Mit den C kann der Quarz leicht verändert werden? (Trimmkondensator)
oder sind die Kondensatoren notwendig damit der kapazitive Anteil im
Schwingkreis passt?
Beim Atmel Mikrocontroller habe ich immer 32pF angebaut. Wäre doch hier
auch okay oder?
Danke für deine Antwort.
Schlagzeuger schrieb:> Welche Funktionen, die beim uVision Compiler hinterlegt sind gehen> überhaupt?> Angenommen ich hab eine Firma und nutz den Compiler, dann ist dem Kunden> es egal wie es funktioniert. Der Kunde möchte gute Ware für wenig Geld.>> Wenn du etwas herausfinden kannst wäre es nett, ansonsten habe ich Pech> gehabt.
Wieso sollte ich versuchen es herauszufinden, wenn es dich und nicht
mich interessiert? ;)
Eventuell gibt es keine Sleep Funktion für jeden Controller in Keil.
Wenn du es genauer wissen willst, dann frag im Keil Forum nach. Dort
müsstest du eine Antwort darauf bekommen können.
Und wenn du das mit den Kondensatoren am Quarz genau wissen willst, dann
lies dir das Kapitel 6.3.2 im Quarzkochbuch (deutsch) unter [1] durch.
Dort wird es ganz genau erklärt. Grundsätzlich kann man mit diesen
Kondensatoren die Quarzfrequenz geringfügig verändern.
Ciao,
Rainer
[1] http://www.axtal.com/info/buch.html
Hallo Rainer,
ich wollte dir noch sagen, dass es mit der Konstantstromquelle genau so
gut geht wie mit der 5V Spannungsversorgung und den 2x 220 Ohm (MIDI
Out) + 1x 220Ohm (MIDI IN) Widerstände in Reihe.
Der Optokoppler benötigt ca. 5mA damit er anspricht.
Die Optkoppler Sendediode hat ca. eine Uf von 2 V.
Bei (5V-2V) / 66Ohm = 4,54mA
Durch meine Recherche habe ich herausgefunden, dass die 5mA in Ordnung
sind.