Forum: Mikrocontroller und Digitale Elektronik Tastenschlagzeug mit NXP LPC 935 selber bauen


von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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

von Achim M. (minifloat)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von Kein Name (Gast)


Lesenswert?

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.

von Achim M. (minifloat)


Lesenswert?

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

von Edson (Gast)


Lesenswert?

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.

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von Achim M. (minifloat)


Lesenswert?

Der LPC935 ist ein 8051er mit kürzerem Zyklus als normal. Dazu sollte 
sich doch was finden lassen.mf
PS: Schau mal 
da:http://www.nxp.com/products/microcontrollers/8_16_bit_legacy/lpc900/P89LPC935FDH.html#documentation

von Schlagzeuger (Gast)


Lesenswert?

Hallo Joachim,
den Baustein habe ich schon und Datenblätter ebenso.
Was ich brauche wäre zum ein Anstatz welche include Dateien ich brauche.
Danke

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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/

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von Edson (Gast)


Lesenswert?

> 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

von Bernd G. (bege)


Lesenswert?

...
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

von Schlagzeuger (Gast)


Lesenswert?

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.

von Schlagzeuger (Gast)


Lesenswert?

Hallo Bernd,
diese Seite wie auch www.edrum.info sind mir bekannt.
Leider muss ich das Rad neu erfinden.
Danke für den Tipp.

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

> 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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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:
1
// RXD Pin P1.1 Quasi-bidirectional und TXD Pin 1.0 Push-Pull konfigurieren
2
P1M1 = P1M1 & 0xFC;
3
P1M2 = P1M2 | 0x01;
4
5
// Ser0: Mode=1 REN=1
6
SCON = 0x50;
7
8
// 9600Bps bei 7,3728MHz
9
BRGR0 = 0xF0;
10
BRGR1 = 0x02;
11
BRGCON = 0x03;

Ciao,
     Rainer

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von Schlagzeuger (Gast)


Lesenswert?

Hallo Rainer,
hast du eine Idee wie ich die Baudrate mit dem Oszi messen kann?

von R. W. (quakeman)


Lesenswert?

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.

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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. :)

von Schlagzeuger (Gast)


Lesenswert?

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

von Jens Witte (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

Danke Jens,
für die Info.
Ich allerdings muss einen Eigenbau bewerkstelligen.
Darum bin ich euch auch für jede Hilfe dankbar.

von R. W. (quakeman)


Lesenswert?

Wieso musst du einen Eigenbau bewerkstelligen?
Klingt ja schon fast nach einer Hausaufgabe. ;)

von Schlagzeuger (Gast)


Lesenswert?

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.

von Schlagzeuger (Gast)



Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

Hallo Zusammen,
ihr könnt neben dem dowonloaden der Osziollogramme auch gerne eure 
Meinung zu meinem Beitrag geben.
Danke

von R. W. (quakeman)


Angehängte Dateien:

Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von Schlagzeuger (Gast)


Lesenswert?

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?

von R. W. (quakeman)


Lesenswert?

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
unsigned char befehl[] = {0x9F, 0x00, 0x7F};

Wenn du nun diesen Befehl senden willst machst du das in einer einfachen 
Schleife.
1
unsigned char i;
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

von Schlagzeuger (Gast)


Lesenswert?

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.

von R. W. (quakeman)


Lesenswert?

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
void main ( )
3
{
4
  unsigned char i, 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

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von Schlagzeuger (Gast)


Lesenswert?

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.

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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?

von R. W. (quakeman)


Angehängte Dateien:

Lesenswert?

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

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

Hallo Rainer,
sorry deinen letzten Eintrag habe ich noch nicht gesehen.
Ich werde mal das versuchen was in den Bildern gezeigt wird.
mfg tim

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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.

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

> 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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

> 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.

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

>> 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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

> 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.

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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 :-)

von Schlagzeuger (Gast)


Lesenswert?

>> 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.

von R. W. (quakeman)


Lesenswert?

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
void main() {
2
  unsinged char x;  // 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
void main() {
2
  unsinged char x;  // 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

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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
sbit out = P2^0;
2
out = 0;
3
P2M1 &= 0xFE;
4
P2M2 &= 0xFE;
5
6
out = 1;
7
8
for schleife...
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

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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.

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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!?

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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?

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

Danke für die Info.
Leider habe momentan kein Material (Sub-D Buchse) rumliegen :-(

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von Schlagzeuger (Gast)


Lesenswert?

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.

von R. W. (quakeman)


Lesenswert?

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
sbit txd = P1^0;
3
4
void main()
5
{
6
  unsigned char i, 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
14
  BRGCON = 0x03;
15
16
  for (i = 0;i < 3;i++)
17
  {
18
    TI = 0;
19
    SBUF = MIDIstream [i];
20
    while (!TI);
21
  }
22
  
23
  while(1);
24
}

Ciao,
     Rainer

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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
void v_Sleep_RTC(unsigned int uiSleepTime) {
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

von Schlagzeuger (Gast)


Lesenswert?

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.

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Angehängte Dateien:

Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

von R. W. (quakeman)


Lesenswert?

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

von Schlagzeuger (Gast)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.