Forum: Mikrocontroller und Digitale Elektronik Card12 mit EVAL-AD5781 verbinden


von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hallo!

Meine Frage an euch: Wie verbinde ich am besten die Eingänge SDIN, SCLK 
und SYNC des D/A-Wandlers mit dem µC der Card 12? Anbei die Schaltpläne!

Danke schon einmal im Voraus!

Also anders gefragt, welche Ports würdet ihr bei diesem Freescale µC 
verwenden?

THX!

von J. R. (cia_man)


Lesenswert?

Ich werde das ganze per SPI miteinander verbinden!

Kann mir hierzu jmd Tipps geben?

Im Datenblatt sehe ich, dass der SCK auf dem µC den Clock erzeugt und so 
mit meinem SCLK auf dem DAC zu verbinden ist.

von J. R. (cia_man)


Lesenswert?

Neue Frage:

Was bedeuten genau die Bezeichnungen MOSI pin und MISO pin???

Master Output, Slave Input bzw. Master Input, Slave Output sagen mir 
jetzt nicht so 100%tig was! Bzw nicht in dem Zusammenhang!

Vlt hat von euch jmd für mich eine Erklärung parat?

DANKE!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

MOSI und MISO sind die eigentlichen Datenleitungen des SPI.
Eine recht gute Erklärung zum SPI findest Du dort:
http://de.wikipedia.org/wiki/Serial_Peripheral_Interface

Ich bin mir auf Anhieb nicht ganz sicher ob Du den 5781 ohne Fummelei am 
SPI zum rennen bekommst. Ist was her das ich damit gespielt habe und 
daher habe ich nicht mehr im Kopf das der SYNC am DAC für eine hatte.

Hast Du vorher schon mal mit dem 5781 gearbeitet?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> MOSI und MISO sind die eigentlichen Datenleitungen des SPI.
> Eine recht gute Erklärung zum SPI findest Du dort:
> http://de.wikipedia.org/wiki/Serial_Peripheral_Interface
>
> Ich bin mir auf Anhieb nicht ganz sicher ob Du den 5781 ohne Fummelei am
> SPI zum rennen bekommst. Ist was her das ich damit gespielt habe und
> daher habe ich nicht mehr im Kopf das der SYNC am DAC für eine hatte.
>
> Hast Du vorher schon mal mit dem 5781 gearbeitet?
>
> Grüße
> Frank

Nein leider nicht! Ist für mich alles neu. Von daher bin ich halt für 
jeden Tipp dankbar! ;)

Danke!

von J. R. (cia_man)


Lesenswert?

Ein Problem, das sich mir zum Beispiel stellt ist, dass ich nicht weiß, 
über was ich den LDAC ansteuern soll.... dieser Eingang wird beim DAC 
unbedingt benötigt. Er muss zwar "nur" auf 0 gesetzt werden, aber dafür 
finde ich beim SPI-Interface keinen PIN oder Möglichkeit! :(

von Frank S. (franksanderdo)


Lesenswert?

Hi Jochen,

ok dann wollen wir das mal gemeinsam versuchen ;-)
Ich habe derzeit keine Hardware zur Verfügung, also kann ich net 
parallel mit probieren. Trotzdem glaube ich bekommen wir das ans laufen.

Wichtig ist eine Frage ganz vorne weg. Kannst Du beim SPI auf deinem 
Board bestimmen wie lang das Datenpaket sein soll?
Der 5781 will immer 24 Bit sehen. Will meinen wir müssen uns den SPI 
hinbiegen das der mit 24 Bit am stück arbeitet.

Generelle Funktion des Schieberegisters am 5781:
SYNC pin fallende Flanke mach das Schieberegister bereit zur Aufnahme
SYNC MUSS dann für 24 Clk Zyklen auf 0 bleiben.
mit jedem Clk Zyklus werden der Zustand des DI übernommen.

Soweit mal im Groben wie Du Daten in den DAC bekommst.
Das schöne an dem Teil: Du kannst dieses Prozedere mit sogar mit 
Schaltern simulieren ;-)
Will damit sagen das ganze ist in keiner Form Zeitkritisch.

Weitere Fragen?
Immer her damit ;-)

Grüße Frank

von Frank S. (franksanderdo)


Lesenswert?

Hi Jochen,

das geht glaube ich gerade was verquer ;)
check mal deine Nachrichten ;-)

Gruß
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hi Jochen,

zu der Frage mit dem LDAC.
Das hängt dann von deiner Anwendung ab.
Du kannst den auf 0 festnageln, damit wird immer mit der steigenden SYNC 
Flanke der Wert auf den Ausgang geschaltet.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hi Jochen,
>
> zu der Frage mit dem LDAC.
> Das hängt dann von deiner Anwendung ab.
> Du kannst den auf 0 festnageln, damit wird immer mit der steigenden SYNC
> Flanke der Wert auf den Ausgang geschaltet.
>
> Grüße
> Frank

Hey!

Das mit dem Festnageln hört sich gut an.... geht das dann Hardwaremäßig? 
Sicher oder?

>Der 5781 will immer 24 Bit sehen. Will meinen wir müssen uns den SPI
>hinbiegen das der mit 24 Bit am stück arbeitet.

Er macht immer nur Standard mäßig 16-bit!

Aber ich denke, das kann man auch ohne weiteres ergänzen! Und was auch 
noch wichtig für das Endprodukt ist ist, dass es mit vollen 4 MHz läuft! 
Also das max was der 912DG128A Chip kann.....

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hi Jochen,

Da haste Dir was vorgenommen ;-)

Festnageln geht Hardwaremäßig, z.B. mit einer Brücke gegen Masse.
Ich empfehle aber (wenn frei) einen Port des uC darauf zu legen. damit 
erhalten wir uns die Funktionalität auch wenn wir sie jetzt nicht sofort 
benutzen.

Mit den 16 Bit kommen wir nicht wirklich weit. Um da was zu drehen 
müsste ich mich in den genutzten uC einlesen. Da ist die Frage ob wir 
das nicht anders schöner lösen können. Da brauche ich dann deinen Input 
was mit dem uC geht und was nicht ;-)

Aber erst mal kurz zu den 4MHz.
Ich gehe davon aus Das Du den Prozessor Takt meinst?

Grüße aus Saudi
Frank
P.S. Ich sag ja "weiter weg" :-D

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hi Jochen,
>
> Da haste Dir was vorgenommen ;-)
>
> Festnageln geht Hardwaremäßig, z.B. mit einer Brücke gegen Masse.
> Ich empfehle aber (wenn frei) einen Port des uC darauf zu legen. damit
> erhalten wir uns die Funktionalität auch wenn wir sie jetzt nicht sofort
> benutzen.
>
> Mit den 16 Bit kommen wir nicht wirklich weit. Um da was zu drehen
> müsste ich mich in den genutzten uC einlesen. Da ist die Frage ob wir
> das nicht anders schöner lösen können. Da brauche ich dann deinen Input
> was mit dem uC geht und was nicht ;-)
>
> Aber erst mal kurz zu den 4MHz.
> Ich gehe davon aus Das Du den Prozessor Takt meinst?
>
> Grüße aus Saudi
> Frank
> P.S. Ich sag ja "weiter weg" :-D

Ja des mit dem Port hört sich gut an! ;)

Zum Mikrocontroller kann ich auch noch jmd fragen, falls es da Probleme 
mit den 24-bit gibt ;)

Der Prozessor von mir hat 8 MHz und da diese von ihm mindestens durch 2 
geteilt werden 4 MHz für den Bus!

Viele Grüße nach Saudi^^ ;)

von Christoph S. (christoph2) Benutzerseite


Lesenswert?

Hi Jochen,

Dem einen Scan entnehme ich, das du einen HC12DG60(A) verwendest,
also ist die SPI-Schnittstelle an PortS.
Was du in jedem Fall (genau so) miteinander verbinden musst:

  HC12    AD5781
  --------------
  SCK     SCLK
  MISO    SDO
  MOSI    SDIN

Slave-Select (/SS-Pin) wird nicht benötigt, du hast die Wahl
wo (SYNC, LDAC, CLR, RESET) du ihn anschließt.

Für den Rest würde ich nahe legen PortA Pins - die sich
ebenso wie die SPI-Schnitstelle an der Leiste ST6 befinden -
zu verwenden.

Für weiteres (Initialisierung Parameter für das HC12 SPI-Modul usw.) 
muss ich zunächst das AD5781 Datenblatt durchsehen.

von J. R. (cia_man)


Lesenswert?

Christoph Schüler schrieb:
> Hi Jochen,
>
> Dem einen Scan entnehme ich, das du einen HC12DG60(A) verwendest,
> also ist die SPI-Schnittstelle an PortS.
> Was du in jedem Fall (genau so) miteinander verbinden musst:
>
>   HC12    AD5781
>   --------------
>   SCK     SCLK
>   MISO    SDO
>   MOSI    SDIN
>
> Slave-Select (/SS-Pin) wird nicht benötigt, du hast die Wahl
> wo (SYNC, LDAC, CLR, RESET) du ihn anschließt.
>
> Für den Rest würde ich nahe legen PortA Pins - die sich
> ebenso wie die SPI-Schnitstelle an der Leiste ST6 befinden -
> zu verwenden.
>
> Für weiteres (Initialisierung Parameter für das HC12 SPI-Modul usw.)
> muss ich zunächst das AD5781 Datenblatt durchsehen.

Danke! So habe ich mir das nach dem Datenblatt-Studium bisher auch 
gedacht!

Warum würdest du nicht den SS verwenden? Macht er nicht die Funktion für 
den Fall, wie benötigt?

Übrigens verwende ich den HC12DG128A.

Danke für die bisherige Hilfe.

Gruß Jochen

von Frank S. (franksanderdo)


Lesenswert?

Hallo Christoph,

super, danke.
Da bin ich nimmer alleine und vor allem jemand der den Prozessor kennt 
dabei.

Das wichtigste für den DAC ist das er immer 24bit sehen will.
Die fallende Flanke am Sync leitet die Übertragung ein und die Steigende 
Flanke beendet sie. Dazwischen müssen exakt 24 CLK Zyklen sein.

Kann man dem Prozessor 24 Bit Pakete auf dem SPI beibiegen?
Kann man evtl. den Slave Select am SYNC nutzen um um den Anfang der 
Übertragung zu vermitteln?

Grüße
Frank

von Christoph S. (christoph2) Benutzerseite


Lesenswert?

Hi Frank,

Ich hatte den ganzen Tag zu tun, aber ich werde morgen auf das Thema 
HC12 und SPI mal ausführlicher eingehen.

Bis denno

Chris

von Christoph S. (christoph2) Benutzerseite


Lesenswert?

Sorry, hatte wieder ganzen Tag zu tun, muss mich deswegen leider kurz 
fassen.
Deswegen werde ich erst morgen genauer auf die eigentliche 
HC12-SPI-Programmierung usw. eingehen können.

Verschiedene serielle (SPI) EEPROMs akzeptieren Schreibzugriffe nur, 
wenn diese einer genau definierten, "schiefen" Länge (27 Bits, 39 Bits, 
whatever) entsprechen - da hat man dann in der Tat ein Problem.

Nicht aber wenn Länge des SPI-Daten-Register (üblicherweise 8Bit) ein 
ganzzahliges Vielfaches davon ist.
In unserem Fall:

  24 / 8 = 3

Ergo teilt man den gesamten Transfer in drei Einzelbyte-Transfers auf.

Zu den Kontroll-Signalen (SYNC, LDAC, CLR, RESET):
Alle sind Low-aktiv, d.h. um unseren guten AD5781 nicht zu irritieren, 
wäre es schön, wenn wir nach einen Reset definierte High-Pegel hätten.

Die Ausgangssituation: Die allermeisten HC12-Pins sind nach einen Reset 
als Eingänge konfiguriert (auch PortA) -  außerdem ist PortA nicht 
Open-drain fähig - was zumindest wünschenswert wäre - und nu?

Ganz einfach:
Man verbindet die entsprechende Port-Pins mit Pullup-Widerständen (sorgt 
für den definierten +5V Pegel nach dem Reset) und verwendet als 
Ausgangpunkt folgenden Code-Schnipsel.

Ich verwende als Notation pseudo-pseudo Code (Funktioniert je nach 
verwendetem C-Compiler tatsächlich).
1
void SetPortA(int num, int level)
2
{
3
  if (level == 0) {
4
    PORTA &= ~(1 << num); /* Output Latch auf Null setzen. */
5
    DDRA |= (1 << num); /* Port-Pin als Ausgang konfigurien. */
6
  } else if (level == 1) {
7
    DDRA &= ~(1 << num); /* Port-Pin als Eingang konfigurieren, der Pullup-Widerstand stellt jetzt wieder +5V Pegel ein. */
8
  }
9
}

Wir machen morgen weiter...


Bis denno

Chris

von J. R. (cia_man)


Lesenswert?

Christoph Schüler schrieb:

> Zu den Kontroll-Signalen (SYNC, LDAC, CLR, RESET):
> Alle sind Low-aktiv, d.h. um unseren guten AD5781 nicht zu irritieren,
> wäre es schön, wenn wir nach einen Reset definierte High-Pegel hätten.
>
> Die Ausgangssituation: Die allermeisten HC12-Pins sind nach einen Reset
> als Eingänge konfiguriert (auch PortA) -  außerdem ist PortA nicht
> Open-drain fähig - was zumindest wünschenswert wäre - und nu?
>
> Ganz einfach:
> Man verbindet die entsprechende Port-Pins mit Pullup-Widerständen (sorgt
> für den definierten +5V Pegel nach dem Reset) und verwendet als
> Ausgangpunkt folgenden Code-Schnipsel.
>

Achso.... also muss ich auch CLR und RESET ansteuern.... okay!

Ansonsten wären sie ja aktiv, wegen dem LOW-Pegel der anliegt.

Kannst du das nochmal etwas genauer mit dem Open-drain fähig und den 
Pullup-Widerständen erklären? Das verstehe ich nicht ganz?

Danke!!!

Gruß

von J. R. (cia_man)


Lesenswert?

Eine weitere Frage:

Kann mir hier jemand noch einmal auf verständliche Art und Weise 
erklären, wie man nun die Versorgungsspannungen VDD und Vss anlegt? Ich 
verstehe das noch nicht so ganz... was ich verstehe ist, dass diese den 
Aussteuerungsbereich festlegen. Jedoch tue ich mir etwas schwer mit der 
richtigen Einstellung dieser Werte...

Grund hierfür ist, dass es auch noch Vrefn und Vrefp gibt und diese 
anscheinend zusätzlich beim Bereich eine Rolle spielen... Jedoch weiß 
ich jetzt nicht wie Vrefn und Vrefp mit VDD und Vss zusammenhängen? Und 
kann man bzw besser muss man Vrefn und Vrefp zusätzlich von außen 
einspeisen?

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ich versuch mich mal an der Erklärung:
Ich kenne jetzt deine Anwendung nicht deswegen stelle ich ein par 
Behauptungen auf ;-)
Behauptung 1: Du möchtest -5 bis +5 Volt am Ausgang einstellen
Behauptung 2: Du hast eine -10 bis +10 Volt Spannungsversorgung

VDD und VSS sind die Spannungsversorgung für den Analogen Teil des 5781.
Das bedeutet das Du dort einfach mal die +-10V anlegst.

Etwas Spannender wird es mit den Referenzspannungen:
Diese definieren den Bereich welchen Du am Ausgang abbilden willst.
Damit sollten die dort eingestellten Spannungen innerhalb von VDD und 
VSS liegen.
Genauer VDD-2,5V bis VSS+2,5V sind die Grenzen.
Also in unserem Beispiel können wir Maximal -7,5V bis +7,5V abbilden.

Die -5 bis +5V liegen in diesem Bereich also ist alles bestens.

Was Du nicht übersehen solltest ist das die beide Referenzspannungen 
über je einen OpAmp als Impedanzwandler eingespeist werden. Schau dir 
Dazu bitte mal das Datenblatt noch einmal an. Das ist wichtig, weil der 
5781 über die Vrefns und vrefps pins die Referenzspannung korrigiert.

Auch der Impedanzwandler am Ausgang ist Pflicht, weil der 5781 keine 
STröme am Ausgang speisen kann.

Lass im Anfang die Finger von dem INV Pin und von dem RFB pin. Für den 
Anfang ist keine Verstärkung notwendig.

Ich hoffe ich konnte Dir ein bischen helfen?
Frag wenn noch etwas unklar ist ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hallo!

Ich möchte von 0-5V am Ausgang aussteuern. Vdd habe ich auf 7,5 V 
eingestellt und Vss auf -2,5 V. Das müsste nach deiner Erklärung korrekt 
sein. Nur jetzt raff ich das nicht ganz mit dem Vrefn und Vrefp? Muss 
ich diese nun auch noch einmal explizit einstellen bzw. zuführen, oder 
passt das nun so wie ich geschrieben habe?

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hi Jochen,

VDD und VSS sind schon mal OK!

Ja Du must die Vrefn und Vrefp Pärchen beschalten ;-)

0V an + EIngang von OpAmp_1
Vrefns an - Eingang von OpAmp_1
Vrefnf an Ausgnag von OpAmp_1

5V an + EIngang von OpAmp_2
Vrefps an - Eingang von OpAmp_2
Vrefpf an Ausgnag von OpAmp_2

Noch Fragen? Immer ran damit ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Das heißt also nach Datenblatt, dass ich den LK9 Jumper auf Position B 
bringen muss. Und das mit den 5V passt doch dann schon oder?

Datenblatt: 
http://www.analog.com/static/imported-files/user_guides/UG-184.pdf



Danke schon mal!



Gruß

von J. R. (cia_man)


Lesenswert?

Sind dann Vrefn und Vrefp als Grenzspannungen zu sehen?

Und deswegen mit 0 V und 5 V zu beschalten?

Ich verstehe den Sinn dieser Spannungen nicht ganz?

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Sinn der Referenzeingänge:
Damit werden Versorgungsspannung und Referenzspannung getrennt 
(entkoppelt)
Das hat 2 Gründe:
1. Die meisten Referenzen sind sehr hochohmig und können/dürfen deswegen 
nicht belastet werden.
2. Du kannst mit ein und der selben Versorgungsspannung viele Bereiche 
erzeugen.
Also mit einer Versogung -10 / +10V kannst Du 0 - 5V oder 1 - 3V oder -5 
- 0V oder -5 - 5V oder 0 - 7,5V oder oder oder bauen.

Nu zu deinem Testboard:
LK9 auf B kümmert sich um die untere Grenze auf 0V
LK8 kümmert sich um um die obere Grenze.
Den auf B und dann am Anschluss VREFP 5V anlegen und dann hast Du es ;-)

So sollte es klappen ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hallo!

Erstmal 1000fachen Dank an euch! V.a. an den Herrn Sander!!! ;)

Ich habe nun die Anschlüsse soweit dran! Auch die Jumper-Settings 
passen.

Doch nun wieder zu einer Verkabelungsfrage... Kann ich nicht die 
Jumper-Settings so abändern, dass Grundlegend CLR, RESET und LDAC 
passen? Geht das?

Weil im Handbuch lese ich zum Bsp bei LK5 at logic low oder at logic 
high!

Ist das dann nicht so, dass man den CLR, welcher bei LOW aktiv ist, 
einfach grundlegend auf high setzt?

Wenn das nämlich geht, müsste ich nur 3 Eingänge verkabeln! Und könnte 
auch den SPI-Standard voll durchziehen/einhalten!

Aber denke mal da steckt der Teufel wieder im Detail oder? :)

Danke !!!!

Gruß Jochen

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

das müssen wir glaube ich der Reihe nach durchgehen.
fangen wir mit den beiden an welche Du auf High halten kannst:

/RESET und /CLEAR.
Also die Brücken LK5 und LK6 dürfen NICHT stecken.
Für den Anfang ist das vollkommen ok.

/LDAC ist ein Thema für sich. Genauer das Zusammenspiel /LDAC und /SYNC
Du brauchst mindestens einen der beiden. Sinnvoll ist der /SYNC.
Wie Du vorher schon selber mal festgestellt hast kannst Du sehr gut den 
/SS vom SPI nutzen um den /SYNC zu bedienen.

Nun kannst Du dir aussuchen ob deine Daten welche Du in den DAC 
geschrieben hast automatisch übernommen werden sollen oder ob Du den 
Zeitpunkt der Übernahme (das Durchschalten auf den Ausgang) selber 
bestimmen willst.

Auch hier gilt eine alte Regel. Halte es im Anfang einfach:
Will sagen: Für den Anfang lass die Daten automatisch übernehmen. Um das 
zu erreichen must Du den /LDAC auf low ziehen. (Brücke LK4 gesteckt)

Wenn Du etwas länger bastelst und etwas mehr Erfahrung im Umgang mit dem 
uC und dem DAC hast wirst Du von alleine den Vorteil herausfinden den 
/LDAC zu bedienen ;-)

Habe ich alle Klarheiten beseitig?
Wenn nicht, fragen wollen gestellt werden um Antworten zu erhalten ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hey!

Okay dann habe ich das richtig verstanden, dass man mit den Jumpern den 
Zustand der jeweiligen Leitung/Kanal voreinstellen kann. D.h. bei LK4 
ein Jumper bedeutet LDAC beginnt mit Logic low und hält diese!

D.h. wenn ich alles so mache wie du sagst, muss ich für den Anfang nur 
die 3 Leitungen SCLK, SYNC und SDIN verbinden.

Sehr schön :)

Als nächstes kommt nun der für mich nicht so einfache Part als Anfänger. 
Das Programmieren.

Falls sich mir dort Fragen stellen, werde ich mich hier nochmal melden. 
Und ich denke es werden sich mir Fragen stellen =)

Aber bisher schon mal soweit DANKE!!!

Viele Grüße

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Es sind 4 Leitungen!!
SDO brauchste ja auch noch, sonst bekommste nix zurück ;-)

Also:


HC12    AD5781
  --------------
  SCK     SCLK
  MISO    SDO
  MOSI    SDIN
  /SS      /SYNC

an sonsten die Brücken wie ich Dir vorher schon geschrieben hatte ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

So... ich habe nun alles verkabelt!

Ich werde nun versuchen, den µC zu programmieren. Wenn hier mir jmd zu 
Tipps geben kann, wäre ich sehr dankbar. Habe damit nämlich noch gar 
keine Erfahrung was SPI betrifft.

Vielleicht weiß ja jmd von euch da bescheid. Ich möchte für den Anfang 
einfach am Ausgang des DAC eine Spannung haben. Es soll also ganz 
primitiv einfach funktionieren ohne großen Schnick-Schnack. ;)

Danke!

Wie weit kannst du mir da helfen Frank?

Gruß

von J. R. (cia_man)


Lesenswert?

So wie ich das sehe, muss ich nun die richtigen Werte in die Control 
Register des µC schreiben.

Dabei bereiten mir das Cotrol Register 1 + 2 Probleme, da ich mit vielen 
dort hinterlegten Funktionen trotz Datenblatt nichts anfangen kann!

Könnte mir vielleicht jmd die Funktionen erklären anhand von einem 
einfach Bsp? Ich will wie schon gesagt am Ausgang erstmal "nur" eine 
Spannung heraus bekommen. Mehr nicht.

Danke.

Jeder Anfang ist schwer... man kommt sich so vor als stehe man im Wald 
^^

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Du stehst im Wald ;-)
Wenn es Dich beruhigt: das ist angenehmer als in der Wüste :-)

Zu deinem Problem:

Leider kann ich Dir nicht sagen wie Du den SPI zum rennen bekommst, weil 
ich den Prozessor nicht kenne und auch hier nix zum testen habe.
Evtl. kann ich was Nachlesen wenn Du mir sagst welche 
Entwicklungsumgebung Du nutzt.

beim DAC kann ich Dir aber helfen ;-)

Wie Du ja schon weist müssen wir immer genau 24Bit schreiben bzw. lesen.
Lass uns für den Moment lesen ignorieren ;-)

das ganz linke DB23 (MSB) bit sagt wenn es null ist das wir in ein 
Register schreiben wollen.
Dieses setzen wir auf 0 (schreiben).

Zu aller erst, nachdem Du den DAC neu gestartet hast (entweder reset 
oder power on) sollten wir dem Ding sagen wie er funktionieren soll. Um 
das zu tun müssen wir das Control Register beschreiben. Dieses wählen 
wir aus in dem wir die bit DB22 = 0, DB21 = 1 und DB20 = 0 setzen

Die bit DB19 - DB10 dürfen wir nicht wirklich anfassen. deswegen setzen 
wir die auf 0.

DB9 - DB6 stellen die Lineare Kompensation ein. da wir nix zu 
verschieben und kompensieren haben setzen wir die auf 0

DB5 hat (im Moment) nix mit uns zu tun. Also default wert 0 einstellen.

DB4 sagt dem DAC ob er im 2er Komplement oder "einfach" binär arbeiten 
soll. Ich schlage for einfach binär für den Anfang. Also DB4 = 0

DB3 und DB2 legen fest wie sich der Ausgang elektrisch verhält. Da 
wollen wir normal operating Mode und damit beide auf 0

DB1 beschaltet den im DAC eingebauten OpAmp mit Widerstanden um die 
Verstärkung fest zu legen. Da hatten wir in den letzten Tagen gesagt wir 
wollen 1/1 also muss das bit 1 sein (unity gain)

DB0 dürfen wir wieder nix mit tun also setzen wir das auf 0

ergibt als binär:
001000000000000000000010

In Hex umrechnen musst Du selber ;-)

Wenn das ins Kontrollregister geschrieben ist, dann könne wir das 
Datenregister beschreiben. Die Anleitung kommt im nächsten Text ;-)

Grüße Frank

von J. R. (cia_man)


Lesenswert?

Hey Frank!

Das mit der Wüste glaube ich dir ;)

Ich verwende von Imagecraft ICCV7. Ich hoffe damit kannst du etwas 
anfangen.

Ansonsten dir schon einmal vielen DANK! Das mit dem DAC bringt mich auf 
jeden Fall schon ein gutes Stück weiter. ;)

DANKE!!

An alle anderen.... wenn sich jmd mit dem SPI Interface auf dem µC HC12 
auskennt bitte bei mir melden ;)

Danke.

Gruß

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen heir kommt der 2. Teil:

Das Datenregister:

wir fangen wieder links (DB23) mit 0 für schreiben an
Dann folgt in DB22-20 die Registeradresse 001
Gefolgt von DB19-DB2 der Wert XXXXXXXXXXXXXXXXXX (da sag ich gleich noch 
was zu)
zum schluss DB1 und DB0 da diese nicht ausgewertet werde ist es egal was 
Du da rein schreibst. Ich bin aber einer der egal = 0 definiert ;-)

Ergibt Binär:
0001XXXXXXXXXXXXXXXXXX00

die 18 Datenbit stellen den Bereich von Vrefn bis Vrefp dar.
Es ist also nicht unbedingt so das 0 = 0V !!!
(in unserem Fall schon aber das ist sozusagen Zufall)

Anders gesagt: bei Vrefn = -5V und Vrefp = +5V wären alle bit 0 = -5V 
und alle bit 1 = +5V

Alles klar?

Grüße Frank

von J. R. (cia_man)


Lesenswert?

Erst einmal schon! Danke dir!!!! ;)
Wünsche dir falls wir uns nix mehr sprechen, schon einmal einen schönen 
1. Mai in Saudi =)

Bis dann

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ich habe mal etwas gestöbert.
Dabei bin ich über das Datenbaltt von deinem Prozessor gestolpert und 
über einige Code Schnipsel im Freescale Forum.

Aus beidem zusammen habe ich dir weiter unten mal eine Initialisierung 
gebastelt und auch einen Funktion zum Daten senden.
Wie gesagt gesagt ich kann nix testen, aber ich denke mal Du kannst da 
ein par Ideen klauen ;-)

Ich vermute in deiner Entwicklungsumgebung gibt es ein Header welcher 
die Register der jeweiligen Adresse in deinem Chip zuordnet. Bitte 
überprüfe gegen diesen die Namen welche ich genutzt habe. Es kann sein 
das ich da falsch geraten haben ;-)

Grüße
Frank
1
void SPIinit(void)
2
{
3
  SPICR1 = 0b01011010
4
  //starting at MSB
5
  // 0 Interrupt disabled
6
  // 1 SPI Enabled
7
  // 0 Pins in Normal Mode (not Open Drain)
8
  // 1 Master Mode
9
  // 1 Clock Pol (data valid at falling edge)
10
  // 0 Clock Phase (clock change when data valid)
11
  // 1 Slave Select active (works together with DDS7) 
12
  // 0 MSB first (not LSBF)
13
14
  SPICR2 = 0b00000010
15
  //starting at MSB
16
  // 000000 not used
17
  // 1 Serial clock stops in wait 
18
  // 0 normal operation (not bidirectional via 1 core)
19
20
  SPIBR = 0b00000111
21
  //starting at MSB
22
  // 00000 not used
23
  // 111 slowest possible serial clock (divider 256)
24
25
  DDRS = DDRS | 0b11110000
26
  // enable SPI outputs but do not touch the other interface
27
}//SPI initialize subroutine
28
29
unsigned char SPI_trans( unsigned char val)
30
{
31
   while ((SPISR & SPTEF) == 0);  // Wait until buffer empty
32
   SPDR = val;                    // Send byte value
33
   while ((SPISR & SPIF) == 0);   // Wait until transfer complete
34
   return SPIDR;                  // Also clears flag
35
}//SPI_trans subroutine

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:

>
1
>   SPICR1 = 0b01011010
2
>   //starting at MSB
3
>   // 0 Interrupt disabled
4
>   // 1 SPI Enabled
5
>   // 0 Pins in Normal Mode (not Open Drain)
6
>   // 1 Master Mode
7
>   // 1 Clock Pol (data valid at falling edge)
8
>   // 0 Clock Phase (clock change when data valid)
9
>   // 1 Slave Select active (works together with DDS7)
10
>   // 0 MSB first (not LSBF)
11
>     .....................
12
>     .....................
13
> unsigned char SPI_trans( unsigned char val)
14
> {
15
>    while ((SPISR & SPTEF) == 0);  // Wait until buffer empty
16
>    SPDR = val;                    // Send byte value
17
>    while ((SPISR & SPIF) == 0);   // Wait until transfer complete
18
>    return SPIDR;                  // Also clears flag
19
> }//SPI_trans subroutine
20
>

Hallo!

Was bedeutet im ersten Absatz: 1 Clock Pol (data valid at falling edge)
& 0 Clock Phase (clock change when data valid)?

Das erste heißt vermutlich, dass bei fallender Flanke des Clocks die 
Daten stehen müssen.
Und wie muss man sich 2tens vorstellen?

Beim 2ten Abschnitt kann ich mit den Bezeichnungen: SPISR, SPTEF, SPIF & 
SPIDR nichts anfangen. Kannst du mir oder irgendjemand diese Abkürzungen 
in Langform einmal ausschreiben? Finde sie so auch nicht im Datenblatt.

DANKE!

Gruß.

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

sorry, da ist es wieder das ich was schreibe ohne es zu erklären :-(

Clock Polarisation: über dieses bit kannst du den Takt den der HC12 
generiert invertieren. dadurch legst Du fest ob eine stegende Flanke 
oder eine Fallende Flanke am Übernahmezeitpunkt der Daten liegt.

Clock Phase: Hiermit kannst Du das Takt signal um 90° verschieben. Damit 
ist die Flanke entweder zum Zeitpunkt wenn auch die Datenwechselflanke 
liegt oder in der Mitte des Datenpulses.

Die Einstellung ermöglicht es Dir das Verhalten des SPI an deinen DAC 
anzupassen. Genau das habe ich gemacht in dem ich das vom DAC erwartete 
Timing eingestellt habe.
Will sagen: der DAC will das die Daten fertig anstehen bevor er mit 
einer mit der fallenden Flanke die Daten übernimmt.

Dann zu den nicht definierten Abkürzungen.
Ok den Teil habe wie oben schon gesagt gefunden und kopiert. Das Dingen 
hätte ich besser kontrollieren sollen.

Zu allererst fällt mir auf das ich da nen Tippfehler drin habe:

SPDR = val muss sein SPIDR = val

dann sind das folgende Register:
SPIDR ist das Datenregister des SPI in das Du schreibst um daten zu 
senden und aus dem Du liest um Daten zu empfangen. Achtung!! Dein SPI 
hat nur 1 Register für beides!!

SPISR ist das Statusregister des SPI. Aus diesem erfahren wir ob das 
SPIDR bereit ist um Daten auf zu nehmen bzw ob eine Übertragung 
vollständig abgeschlossen wurde. Natürlich gibts da noch 6 weitere 
Informationen, aber die habe ich weg ignoriert ;-)
Damit wir eben genau die beiden o.g. Informationen auswerten verknüpfe 
ich die via UND mit dem entsprechenden Bit

SPTEF nennt sich im Datenblatt WCOL und überpfrüft einfach ob ein 
anderes gerät gerade Daten sendet, bzw. die Leitung zum senden bereit 
ist.
SPIF zeigt an ob eine Übertragung abgeschlossen ist.

Wichtig beim SPIF ist das der automatisch zurück gesetzt wird wenn das 
Statusregister und danach das Datenregister gelesen wird.

Ich hoffe Du bist net böse das ich da geschlampt habe !?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hey!

Ich habe nun einmal ein Programm angefertigt:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
main()
6
{
7
  DDRS = DDRS | 0xF0; /* outputs */
8
  
9
  PORTS = PORTS | 0x80; /* Bring SS high */
10
  
11
  SP0CR1 = 0x5A; /* 0b01011010 */
12
  
13
  SP0CR2 = 0; /* Normal mode */
14
  
15
  SP0BR = 0x00; /* 4 MHz SPI clock */
16
  
17
  PORTS = PORTS & ~0x80; /* Bring SS low to select slave */
18
  
19
  SP0DR = 0x200002;
20
  
21
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
22
  
23
  SP0DR = 0x1003FC;
24
  
25
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
26
  
27
  PORTS = PORTS | 0x80; /* Bring SS high to deselect slave */
28
  
29
  }

Jetzt wollte ich einmal die Profis fragen, ob das soweit korrekt ist?

Danke! ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Ich bin ja jetzt keiner der Spezialisten ;-)
Nach meinem Verständnis kümmert sich der SPI Port selber um den SS wenn 
Du die Config benutzt wie ich Sie Dir zusammen gestellt habe.

Dann fällt mir auf das Du nach dem Warten auf transfer ende das 
Datenregister nicht ausliest. Ich verstehe das Datenblatt so, das Du das 
Danteregister lesen must nachdem das Transmit ende bit im Status 
gekommen ist. Die Kombination Status lesen und Datum lesen setzt dann 
dieses Bit zurück.

Zu guter letzt:
Ich fürchte ein 24b Zugriff auf das Datenregister ist nicht möglich.
Da täte ich es aber auf einen Versuch ankommen lassen.
Hast Du mal mit den Programmschnipseln die ich Dir geschickt habe 
probiert?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hallo Frank!


Schau mal bitte hier:


http://www.ee.nmt.edu/~rison/ee308_spr02/supp/020320.pdf


Das ist die Quelle, die ich verwendet habe und mit deinem Programm 
kombiniert habe. Darum die Code-Änderungen.

Was sagst du zu dieser Quelle?


Gruß
Jochen

von Frank S. (franksanderdo)


Lesenswert?

Hi Jochen,

gut erklärt in dem pdf.

Das Problem ist das dein Programm nicht dazu passt ;-)
Du sagst im SP0CR1 bit 1 das der SPI den /SS verwalten soll und dann 
tust Du es doch selber über PORTS.

In dem pdf wird meine Befürchtung bestätigt, das deine 24b Zuweisungen 
zum SP0DR nicht funktionieren werden. Die Jungens haben auch nur mit 8b 
gearbeitet und im Text war auch ein Hinweis das man immer nur 8 bit am 
stück durch tickern kann.

Ich bin immer noch nicht überzeugt, was das Statusbit betrifft. Habe 
gerade noch mal nachgeschaut. das SPIF bit wird nur mit der Kombination 
Statusregister und Datenregister auslesen zurück gesetzt. Zumindest 
verstehe ich das so.
Hier täte ich sagen: Probieren geht manchmal über studieren ;-)

Noch ein kleiner Tip von einer faulen Socke wie mir:
Mach den SCLK so langsam wie möglich (zumindest im Anfang) damit hast Du 
die Möglichkeit genau zu verfolgen (z.B. mit Oscar) was auf dem Bus 
passiert ;-)

Also:
Stell deine 24b transfers um auf 8b und dann nix wie rin in den 
Controler und testen.
Ja ich will das Resultat wissen :-D

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hey!

Heißt das, dass ich den Strang:

001000000000000000000010

einfach in

00100000 00000000 00000010

aufteilen muss? ;)

Und dann SP0DR = 0x20;

         SP0DR = 0x0;

..... einlesen muss?

Also das mit den 24 Bit meine ich ;)

Danke!

von J. R. (cia_man)


Lesenswert?

Hier das nun abgeänderte Programm:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
main()
6
{
7
  DDRS = DDRS | 0xF0; /* outputs */
8
      
9
  SP0CR1 = 0x5A; /* 0b01011010 */
10
  
11
  SP0CR2 = 0; /* Normal mode */
12
  
13
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
14
     
15
  SP0DR = 0x20;
16
  
17
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
18
  
19
  return SP0DR; 
20
  
21
  SP0DR = 0x00;
22
  
23
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
24
  
25
  return SP0DR; 
26
  
27
  SP0DR = 0x02;
28
  
29
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
30
  
31
  return SP0DR; 
32
  
33
  SP0DR = 0x10;
34
  
35
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
36
  
37
  return SP0DR; 
38
  
39
  SP0DR = 0x03;
40
  
41
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
42
  
43
  return SP0DR; 
44
      
45
  SP0DR = 0xFC;  
46
  
47
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
48
  
49
  return SP0DR; 
50
  }

Hoffe ich habe dich richtig verstanden Frank?! ;)

Danke!

Ich messe den Ausgang momentan halt nur mit einem Voltmeter. 
Gleichspannung. Hoffe das ist für die 1. Prüfung okay. ;)

von Frank S. (franksanderdo)


Lesenswert?

Hi Jochen,

Voltmeter reicht mir ;-)

Nur so wird das nix mit dem Programm.

return ist gedacht um aus einer Funktion zurück zu kehren. Ist also 
quasi der Rücksprung.
Wenn Du in deinem main ein return aufrufst möchte ich lieber nicht 
wissen wo der hin "zurück" springt ;-)

leg Dir eine variable an (z.B. unsigned char muelleimer) und lese das 
Datenregister in diese aus, also:
muelleimer = SP0DR;

alles klar soweit?
Was kommt am DAC raus?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Kann ich es auch so abändern?

Weil ich verstehe deine Version nicht so recht... also des mit dem 
Mülleimer ^^
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
main()
6
{
7
  DDRS = DDRS | 0xF0; /* outputs */
8
      
9
  SP0CR1 = 0x5A; /* 0b01011010 */
10
  
11
  SP0CR2 = 0; /* Normal mode */
12
  
13
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
14
     
15
  SP0DR = 0x20;
16
  
17
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
18
  
19
  SP0DR = 0x00;
20
  
21
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
22
  
23
  SP0DR = 0x02;
24
  
25
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
26
  
27
  SP0DR = 0x10;
28
  
29
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
30
  
31
  SP0DR = 0x03;
32
  
33
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
34
      
35
  SP0DR = 0xFC;  
36
  
37
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
38
  }

Oder wie meinst du deins??? Falls das so nicht stimmt?

Am Ausgang meines DAC liegt immer noch 0,1 mV an :( mit obigem Programm.

von Frank S. (franksanderdo)


Lesenswert?

Ich hab da mal was angepasst ;-)

Jochen R. schrieb:
> Kann ich es auch so abändern?
>
> Weil ich verstehe deine Version nicht so recht... also des mit dem
> Mülleimer ^^
>
>
1
> 
2
> #include <stdio.h>
3
> 
4
> #include <mc912d128.h>
5
> 
6
> main()
7
> {
8
      unsigned char muelleimer; /* was zum Datenauslesen und verwerfen */
9
10
>   DDRS = DDRS | 0xF0; /* outputs */
11
> 
12
>   SP0CR1 = 0x5A; /* 0b01011010 */
13
> 
14
>   SP0CR2 = 0; /* Normal mode */
15
> 
16
>   SP0BR = 0x07; /* 31,25 kHz SPI clock */
17
> 
18
>   SP0DR = 0x20;
19
> 
20
>   while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
21
22
     muelleimer = SP0DR; /* Daten auslesen und verwerfen */
23
24
>   SP0DR = 0x00;
25
> 
26
>   while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
27
28
     muelleimer = SP0DR; /* Daten auslesen und verwerfen */
29
 
30
>   SP0DR = 0x02;
31
> 
32
>   while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
33
34
     muelleimer = SP0DR; /* Daten auslesen und verwerfen */
35
36
>   SP0DR = 0x10;
37
> 
38
>   while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
39
40
     muelleimer = SP0DR; /* Daten auslesen und verwerfen */
41
42
>   SP0DR = 0x03;
43
> 
44
>   while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
45
46
     muelleimer = SP0DR; /* Daten auslesen und verwerfen */
47
48
>   SP0DR = 0xFC;
49
> 
50
>   while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
51
52
     muelleimer = SP0DR; /* Daten auslesen und verwerfen */
53
>   }
54
> 
55
> 
56
>
>
> Oder wie meinst du deins??? Falls das so nicht stimmt?

Som meinte ich das ;-)

von J. R. (cia_man)


Lesenswert?

Hat leider bisher nicht den gewünschten Erfolg! :(

Woran könnte es nun noch liegen???

Gruß Jochen

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

so dann kommt jetzt der Moment wo wir debuggen müssen ;-)

Da gibt es verschiedene Ansätze, ich täte als erstes schauen ob 
überhaput irgendwas auf der Schnittstelle passiert.

Also Programm in eine endlosschleife ändern welche Daten zum DAC schickt 
und dann mal mit dem Oscar schauen ob der Takt kommt, ob der SS den 
Pegelwechselt und ob die Bits bitten.
Jetzt genau wird es handlich wenn Du den Takt der Seriellen runter 
setzt. Macht es etwas einfacher zu sehen was passiert ;-)

Willkommen in der Welt der Entwickler, ab jetzt kommt der Teil der 
wirklich Spass macht.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> so dann kommt jetzt der Moment wo wir debuggen müssen ;-)
>
> Da gibt es verschiedene Ansätze, ich täte als erstes schauen ob
> überhaput irgendwas auf der Schnittstelle passiert.
>
> Also Programm in eine endlosschleife ändern welche Daten zum DAC schickt
> und dann mal mit dem Oscar schauen ob der Takt kommt, ob der SS den
> Pegelwechselt und ob die Bits bitten.
> Jetzt genau wird es handlich wenn Du den Takt der Seriellen runter
> setzt. Macht es etwas einfacher zu sehen was passiert ;-)
>
> Willkommen in der Welt der Entwickler, ab jetzt kommt der Teil der
> wirklich Spass macht.
>
> Grüße
> Frank

Meine Ungeduld endlich in die "Welt der Entwickler" zu kommen ist fast 
nicht mehr zu bändigen ^^ ;)

Das heißt also nun ich packe das ganze in eine while-Schleife die nie 
endet oder? Und dann muss ich also das Oszilloskop direkt nach dem HC 12 
hängen oder?

Oder hänge ich es an den Ausgang VOUT??? Vom DAC?

Danke!

Gruß

von J. R. (cia_man)


Lesenswert?

Wie ist es eigentlich mit dem Masse-Bezug zwischen HC12 und DAC? Eine 
Ground-Leitung existiert ja so nicht! Ist das korrekt so?

Gruß

Jochen

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Endlosschleife: genau

Oscar: der reihe nach an die Ausgänge des HC12

und dann beschreib mal was Du gefunden hast ;-)

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

eine Masse Leitung ist extrem hilfreich ;-)

Also vo HC12 zur Prozessorseite des DAC

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Was für Anschlüsse muss ich dann für Ground verbinden? ;)

DGND gibt es ja 2mal... :(

von J. R. (cia_man)


Lesenswert?

Neuester Stand des Programms:

Mit while-Schleife!

1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
main()
6
{ 
7
  
8
  int i = 1;
9
  
10
  while (i>0)
11
  {
12
  unsigned char delete; /* was zum Datenauslesen und verwerfen */
13
14
  DDRS = DDRS | 0xF0; /* outputs */
15
      
16
  SP0CR1 = 0x5A; /* 0b01011010 */
17
  
18
  SP0CR2 = 0; /* Normal mode */
19
  
20
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
21
     
22
  SP0DR = 0x20;
23
  
24
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
25
  
26
  delete = SP0DR; /* Daten auslesen und verwerfen */
27
  
28
  SP0DR = 0x00;
29
  
30
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
31
  
32
  delete = SP0DR; /* Daten auslesen und verwerfen */
33
  
34
  SP0DR = 0x02;
35
  
36
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
37
  
38
  delete = SP0DR; /* Daten auslesen und verwerfen */
39
  
40
  SP0DR = 0x10;
41
  
42
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
43
  
44
  delete = SP0DR; /* Daten auslesen und verwerfen */
45
  
46
  SP0DR = 0x03;
47
  
48
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
49
      
50
  delete = SP0DR; /* Daten auslesen und verwerfen */
51
    
52
  SP0DR = 0xFC;  
53
  
54
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
55
  
56
  delete = SP0DR; /* Daten auslesen und verwerfen */
57
  }
58
59
}

Hoffe mal das Stimmt soweit! :>

von J. R. (cia_man)


Lesenswert?

Wo ich aber auf jeden Fall nochmals Hilfe benötige, ist der 
Masse-Anschluss! :) Da habe ich nämlich nicht so recht Ahnung, wie ich 
jetzt was verbinde, damit DAC und µC auch eine gemeinsame Masse haben!

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Programm kann ich auf anhieb keinen Fehler sehen.

Wegen der Masse: Ich hoffe und glaube das es sogar noch öfter DGND auf 
deinem Board gibt ;-)
Die sollten aber eigentlich miteinander verbunden sein.

Im Zweifel einfach mal (spannungsfrei gemacht) auf Durchgang prüfen ;-)

Auf die Gefahr das ich nur mecker:
delete ist als variablen name ein eingeschränkt gute wahl. Das könnte in 
dein Entwicklungsumgebung schon für was anderes genutzt worden sein.
nenn es im zweifel my_delete oder so ;-)
Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Also an meinem J6 Stecker auf dem DAC sind 2 DGND net mehr. Und wenn ich 
jetzt bei beiden auf Durchgang messe, ist der Widerstand gegen 0. Soll 
ich diese beiden stecker nun miteinander verbinden?

Was aber meine Frage ist bzw war: Wie kann ich jetzt den DAC und den µC 
auf Masse legen? Also welche Anschlüsse muss ich auf welche Masse legen? 
Bei beiden? Das ist mir jetzt echt noch total unklar? Weil momentan sind 
sie nur per Spannungsversorgung auf Masse gelegt -> AGND! Aber nicht für 
das Digitale! Vlt geht ja auch darum der DAC nicht??? ;)

Und das Programm habe ich so wie du gemeint hast abgeändert! Danke für 
den Tipp ;)

Gruß Jochen

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Du verwirrst mich gerade ;-)
Wenn ich in das Handbuch (was du weiter oben gepostet hast) zu deinem 
DAC Board Schaue, dann finde ich in der Schaltung keinen J6.
Leider habe ich auch nur den Schnipsel von Dir (ganz oben) zu HC12 
Board.

Macht aber nicht so viel aus.

Es muss eine Verbindung zwischen DGND vom DAC Board und Masse vom HC12 
board hergestellt werden. Wenn Du getrennte Spannungsversorgungen 
benutzt kannst Du einfach die Masse von dem VCC für das DAC board und 
die Masse vom VCC für das HC12 Board verbinden.
Der andere Weg ist von einem DGND pin an der Steckerleiste dein DAC 
boards zu einem Masse (GND) pin am HC12 board.

Auch wenn es mich freuen würde damit den Fehler zu beheben.... ich 
fürchte Du hast unbewusst eh schon die Verbindung über dein Netzteil ;-)

Also Masseverbindung herstellen und nochmal testen, wenn nicht geht wie 
oben gesagt:
Endlosschleife und messen.

Da ich jetzt Feierabend mache und ca. 1 1/2 Stunden weg nach Hause habe. 
Hoffe ich dann eine Erfolgsmeldung oder ein "Messprotokoll" zu sehen ;-)

Viel Erfolg
Frank

von Frank S. (franksanderdo)


Lesenswert?

Ok hab auch gerade den J6 gefunden :D
Sorry!!

von J. R. (cia_man)


Lesenswert?

Naja ob das heute noch mit der Erfolgsmeldung klappt? ;)

Eine Erfolgsmeldung gibt es doch für den heutigen Tag schon ;) Osama ist 
nicht mehr unter uns ;)

Bekommst du davon etwas in Saudi mit?

Gruß

Jochen

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Ich habe nun zusätzlich DGND vom DAC mit dem GND auf dem HC12 Board 
verbunden (ST5 Kontakt 50)! Keine Besserung :(

Angehängt habe ich nochmal einen Screenshot vom Card 12 Modul (HC12). Zu 
sehen sind dort die Anschlussleisten.

Danke!

Gruß Jochen

PS: Das mit dem Messen an den Anschlüssen wird sich auf Morgen 
verschieben, nehme ich schwer an. Sorry ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

da ich zu faul zum lesen bin:
Läuft der HC12 mit 5V oder mit 3V?

Weiter sollten wir uns dann mal einen Pan machen wie wir dem Kind zu 
Leibe rücken.
Ich vermute ja mal das Du irgendwann fertig sein willst ;-)
Gib doch bitte mal ne grobe Idee was Du Dir für welche Zeiträume gedacht 
hast.
Damit können wir uns dann überlegen wie ich Dir am besten und 
effektivsten helfen kann.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> da ich zu faul zum lesen bin:
> Läuft der HC12 mit 5V oder mit 3V?
>
> Weiter sollten wir uns dann mal einen Pan machen wie wir dem Kind zu
> Leibe rücken.
> Ich vermute ja mal das Du irgendwann fertig sein willst ;-)
> Gib doch bitte mal ne grobe Idee was Du Dir für welche Zeiträume gedacht
> hast.
> Damit können wir uns dann überlegen wie ich Dir am besten und
> effektivsten helfen kann.
>
> Grüße
> Frank
Morgen!

Er läuft definitiv mit einer Versorgungsspannung von 5V.

Bis später!

von Frank S. (franksanderdo)


Lesenswert?

Moin Jochen,

das ist gut ;-)

Also können wir anfangen zu Messen wo der Hund begraben liegt ;-)
Ein Oscar ist jetzt hilfreich.

!. Info die uns inetressiert ist ob die SIgnale /SS SCLK MOSI etwas 
sinnvoles von sich geben.

Kannst DU das Programm änder das Du nach der Initialisierenung Daten in 
einer Endlosschleife zu DAC schickst?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hab ich doch schon... siehe While-Schleife oben ;)

von APW^ (Gast)


Lesenswert?

Ich habe jetzt nur mal kurz die Datenblätter überflogen.
Mir ist dabei folgendes aufgefallen:

1)Wenn /Sync mit /SS verbunden ist:
Der DAC will doch, dass /Sync 24 Bit lang low bleibt, bei euch wird aber
nach jedem Byte /SS automatisch vom HC12 SPI High gesetzt.
D.h. letztendlich müsst Ihr /SS manuell ansteuern.

2)Kein Fehler, aber unnötig:
SPI Datenregister müsst Ihr nicht in eine dummy-Variable auslesen, um
das SPI-Flag rückzusetzen (höchstens nach der letzten Aussendung,
und dann auch nur, falls man wirklich Interrups verwendet)

Die Sequenz ist:
a)"reading the SP0SR register (with SPIF set)", was mit
>  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
  erledigt wird, und dann
b)"followed by an access (read or write) to the SPI data register.",
   was ja durch das Schreiben des nächsten SPI Datenbytes geschieht

von Frank S. (franksanderdo)


Lesenswert?

Hi Jochen,

sorry habe ich nicht genau genug hein geschaut.
Folgendes Beispiel hänge ich damit Du eine Idee bekommst wie man so 
etwas vereinfachen kann.

Für die Messung ist dein Beispiel OK, allerdings ist es ungeschickt die 
Initialisierung in der Endlosschleife mit laufen zu lassen.
Ich habe das in meine Muster mal etwas angepasst ;-)

Wo ich Dich allerdings drum bitten möchte ist das Du peinlich genau 
darauf achtest das die Einrückung stimmt. Im Moment ist es noch einfach 
die Ebenen zu trennen. Du suchst Dich aber tot wenn das Programm größer 
wird und die Klammerebene nimmer passt.

So ich hoffe mal ich habe keine Tippfehler mehr drin ;-)
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
  return = 0;
13
}
14
15
main()
16
{ 
17
  
18
  int i = 1;
19
  
20
  /* Init for SPI Interface */
21
  DDRS = DDRS | 0xF0; /* outputs */
22
  SP0CR1 = 0x5A; /* 0b01011010 */
23
  SP0CR2 = 0; /* Normal mode */
24
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
25
26
  while (i>0) /* Endles Data sending for testing only */
27
  {
28
    mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
29
    mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
30
    mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
31
32
    mySPITrans(0x10); /* Analog Value Byte1 MSB first        */
33
    mySPITrans(0x03); /* Analog Value Byte2 24 bit total    */
34
    mySPITrans(0xFC); /* Analog Value Byte3 LSB last         */
35
  }
36
}

von Frank S. (franksanderdo)


Lesenswert?

@APW

super danke für den Hinweis!!
Vor allem weil Jochen der Lümmel das Setup im SP0CR2 geändert hat und 
ich das nicht gesehen habe.

Eigentlich wollte ich das Clockwait aktivieren. dadurch umgehe ich ds 
ich den /SS selber verwalten muss und bin mir sicher das die Anzahl der 
Clockimpulse stimmt.

Wegen des überflüssigen auslesen des SP0DR gebe ich zu ich bin 
mittlerweile verwirrt.
Da ich nicht 100% sicher war aufgrund des Datenblatts habe ich etwas 
herum gewühlt 2 Meinungen gefunden. Deine und die mit dem Lesen drin. Da 
ich mir sicher bin das es nicht schadet ist meine Idee im Moment das 
Lesen zu machen bis wir eine funktionierende Basis haben. Dann einfach 
die Zeile auskommentieren. Dann wissen wir es genau ;-)

Sei so lieb und behalte ein Auge auf den unfug den wir hier treiben, 
jeder Hinweis hilft uns weiter!!

@Jochen
Ich glaube das APW eine Mögliche Fehlerquelle aufgedeckt hat.
Der Wert wo in das SP0CR2 geht hätte 0x02 sein sollen.

Grüße
Frank

von APW (Gast)


Lesenswert?

> Der Wert wo in das SP0CR2 geht hätte 0x02 sein sollen.

Achtung: Da bist du total auf dem Holzweg.
Das SSWAI-Bit macht nicht das was du denkst !

Das sollte dafür gedacht sein, dass die Übertragung zu Ende
geführt wird, wenn du z.B. noch eine SPI-Übertragung am
Laufen hast und den Prozessor währenddessen in den WAIT-Status
versetzt.

Hat also nichts mit dem zu tun was Jochen macht.

Ich denke, Ihr solltet SSOE in SP0CR1 nicht setzen, sondern den /SS
manuell ansteuern, also wie ein GPIO verwenden.

Also etwa so:

...
PORTS |= 0x80;   //manual preset of /SS output
DDRS   = 0xF0;
SP0CR1 = 0x58;
...
PORTS &= ~0x80;  // /SS output low
...
(24 Bit Übertragung)
...
PORTS |= 0x80;  // /SS output high

Übrigens: Was ich hier wiedergebe ist ohne Gewähr.
Ich sage mir immer, alles, was nicht real getestet,
bzw am Oszi verifiziert wurde, funktioniert nicht.

von J. R. (cia_man)


Lesenswert?

Hallo!

Mein Programm habe ich nun so abgeändert:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
main()
6
{ 
7
  
8
  int i = 1;
9
  
10
  while (i>0)
11
  {
12
  unsigned char my_delete; /* was zum Datenauslesen und verwerfen */
13
14
  DDRS = DDRS | 0xF0; /* outputs */
15
      
16
  PORTS |= 0x80; /*Bring SS high to deselect slave */    
17
    
18
  SP0CR1 = 0x58; /* 0b01011000 */
19
  
20
  SP0CR2 = 0; /* Normal mode */
21
  
22
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
23
     
24
  PORTS &= ~0x80; /* Bring SS low to select slave */   
25
   
26
  SP0DR = 0x20;
27
  
28
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
29
  
30
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
31
  
32
  SP0DR = 0x00;
33
  
34
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
35
  
36
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
37
  
38
  SP0DR = 0x02;
39
  
40
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
41
  
42
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
43
  
44
  SP0DR = 0x10;
45
  
46
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
47
  
48
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
49
  
50
  SP0DR = 0x03;
51
  
52
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
53
      
54
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
55
    
56
  SP0DR = 0xFC;  
57
  
58
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
59
  
60
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
61
  
62
  PORTS |= 0x80; /* Bring SS high to deselect slave */
63
  }
64
65
}

Ist das so okay?

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW,

ich sehe unsere Grundsätze sind die gleichen was das testen betrifft ;-)
Auch ich liebe meinen Oscar, weil der sagt immer die Wahrheit :-D

Schreck lass nach, da habe ich dann SSWAI tatsächlich komplett falsch 
verstanden.
Ich schäme mich vorsichtshalber und lese noch mal nach ;-)

Im Moment fürchte ich aber sind wir beide schneller als Jochen :-O
Von dem hätte ich gerne gewusst was an der Schnittstelle passiert ;-)
Weil dann hätten wir es gemessen! :-D

Danke noch mal und wenn ich ich Blödsinn erzähle bitte sag bescheid. Ich 
sitze in der Wüste (kein Scherz) und habe im Moment NIX hier um selber 
testen zu können. Jochen und ich versuchen mit 5000 km Distanz die 
Nummer zum laufen zu bekommen. Leider sind die Prüfstrippen vom Oscar 
nicht so lang ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hallo!

Sorry Leute, dass ich euch nicht mehr helfen kann! Aber ich muss mir 
erst Prüfkabel für mein Oszi bauen und dafür fehlen hier bei uns 
BNC-Stecker für :(
Sorry nochmals!! Denke, dass es bis moin dauert, bis ich euch Resultate 
posten kann! Dann kommt nämlich die Lieferung! Wir können nur per Code 
momentan probieren sorry!

THX!

von APW (Gast)


Lesenswert?

Immerhin kann man ja statisch messen, ob der DAC das ausgibt,
was man erwartet.

von J. R. (cia_man)


Lesenswert?

APW schrieb:
> Immerhin kann man ja statisch messen, ob der DAC das ausgibt,
> was man erwartet.

Wie meinst du das?

von J. R. (cia_man)


Lesenswert?

Wenn ich mit meinem Multimeter am µC messe, liegt auf jeden Fall an 
allen von uns verwendeten Anschlüssen etwas an!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

nicht ganz, weil da fehlt jetzt einmal toggeln (wechseln) des /SS nach 
dem
  SP0DR = 0x02;

  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */

  my_delete = SP0DR; /* Daten auslesen und verwerfen */

Weil da sind ja die ersten 24 bit zu ende.
Ergo muss das /SS auf 1 gehen (damit der DAC die Daten übernimmt) und 
wieder auf 0 für die nächasten 24 Bit.

alles klar soweit?
Schon eine Messung gemacht?  ;-)

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

So ich bastel derweil parallel mal an meiine Programm weiter.
Der Hinweis von APW war vollkommen berechtigt und ich bin ein Depp :-(

Also ändert sich das ganze jetzt ein wenig:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
  return = 0;
13
}
14
15
main()
16
{ 
17
  
18
  int i = 1;
19
  
20
  /* Init for SPI Interface */
21
  PORTS |= 0x80;
22
  DDRS = DDRS | 0xF0; /* outputs */
23
  SP0CR1 = 0x58; /* 0b01011010 */
24
  SP0CR2 = 0; /* Normal mode */
25
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
26
27
  while (i>0) /* Endles Data sending for testing only */
28
  {
29
    PORTS &= ~0x80;  /* /SS output low */
30
    mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
31
    mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
32
    mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
33
    PORTS |= 0x80;    /* /SS output high */
34
35
/* Die Frage ist brauche ich hier eine kurze Pause? Wir werden das messen */
36
37
    PORTS &= ~0x80;  /* /SS output low */
38
    mySPITrans(0x10); /* Analog Value Byte1 MSB first        */
39
    mySPITrans(0x03); /* Analog Value Byte2 24 bit total    */
40
    mySPITrans(0xFC); /* Analog Value Byte3 LSB last         */
41
    PORTS |= 0x80;    /* /SS output high */
42
  }
43
}

von J. R. (cia_man)


Lesenswert?

Hallo!

Neueste Fassung geht:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
main()
6
{ 
7
  
8
  int i = 1;
9
  
10
  while (i>0)
11
  {
12
  unsigned char my_delete; /* was zum Datenauslesen und verwerfen */
13
14
  DDRS = DDRS | 0xF0; /* outputs */
15
      
16
  PORTS |= 0x80; /*Bring SS high to deselect slave */    
17
    
18
  SP0CR1 = 0x58; /* 0b01011000 */
19
  
20
  SP0CR2 = 0; /* Normal mode */
21
  
22
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
23
     
24
  PORTS &= ~0x80; /* Bring SS low to select slave */   
25
   
26
  SP0DR = 0x20;
27
  
28
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
29
  
30
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
31
  
32
  SP0DR = 0x00;
33
  
34
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
35
  
36
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
37
  
38
  SP0DR = 0x02;
39
  
40
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
41
  
42
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
43
  
44
  PORTS |= 0x80; /* Bring SS high to deselect slave */
45
  
46
  PORTS &= ~0x80; /* Bring SS low to select slave */   
47
  
48
  SP0DR = 0x10;
49
  
50
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
51
  
52
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
53
  
54
  SP0DR = 0x03;
55
  
56
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
57
      
58
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
59
    
60
  SP0DR = 0xFC;  
61
  
62
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */
63
  
64
  my_delete = SP0DR; /* Daten auslesen und verwerfen */
65
  
66
  PORTS |= 0x80; /* Bring SS high to deselect slave */
67
  }
68
69
}


Juhuuuu!!!! Ich messe 2,53V an VOUT vom DAC!!! Danke schon einmal 
1000-fach ;)

Der Anfang ist gemacht ;)

Später folgen Oszi-Aufnahmen vom VOUT! ;)

THX!

von Frank S. (franksanderdo)


Lesenswert?

Super!!

Da haben wir ja ein bischen was geschaft ;-)

Hast DU noch Lust das Programm etwas zu säubern das Du das dann 
hinterher weiter verwenden kannst?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Ja klaro!

Vorher mache ich mal vom Oszi nen Screen! ;)

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hier mal die Oszi Bilder vom VOUT des DAC!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

das ist besser als ich erwartet habe!
Sehr schön!

Kannst Du mir einen Gefallen tun?
Meine letzte Programm version, kannst Du die mal testen?
Ich würde DIch gerne in diese Richtung schubsen, damit wir Überblick im 
Programm behalten ;-)

Wenn die funktioniert würde ich gerne austesten ob das Datenlesen und 
wegwerfen wirklich notwendig ist.

Zum guten Schluss bauen wir dir einen ganz einfachen "Sinusgenerator".

Sind ein par Fingerübungen für Dich um etwas mehr in deine 
Entwicklungsumgebung rein zu wachsen. Gleichzeitig erhalten wir am ende 
eine einfach zu nutzende Routine um den DAC mit Daten zu versorgen ;-)

Ach ja, wie immer gilt:
Solltest Du Fragen haben immer her damit ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Geht auch!
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
main()
15
{ 
16
  
17
  int i = 1;
18
  
19
  /* Init for SPI Interface */
20
  PORTS |= 0x80;
21
  DDRS = DDRS | 0xF0; /* outputs */
22
  SP0CR1 = 0x58; /* 0b01011000 */
23
  SP0CR2 = 0; /* Normal mode */
24
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
25
26
  while (i>0) /* Endles Data sending for testing only */
27
  {
28
    PORTS &= ~0x80;  /* /SS output low */
29
    mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
30
    mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
31
    mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
32
    PORTS |= 0x80;    /* /SS output high */
33
34
/* Die Frage ist brauche ich hier eine kurze Pause? Wir werden das messen */
35
36
    PORTS &= ~0x80;  /* /SS output low */
37
    mySPITrans(0x10); /* Analog Value Byte1 MSB first        */
38
    mySPITrans(0x03); /* Analog Value Byte2 24 bit total    */
39
    mySPITrans(0xFC); /* Analog Value Byte3 LSB last         */
40
    PORTS |= 0x80;    /* /SS output high */
41
  }
42
}


Ich habe diese Zeile zu deinem Exemplar verbessert ;)

SP0CR1 = 0x58; /* 0b01011000 */ im Kommentar war ein Fehler ;)

Thx!

von J. R. (cia_man)


Lesenswert?

Kann es sein, dass die Spannung die ausgegeben wir zu hoch ist?

Ich gebe ja diesen Wert als 18 Bit Wort ein: 000000000011111111

???

Am Ausgang sind es dann 2,51 V...

von Frank S. (franksanderdo)


Lesenswert?

Mist, ich wusste das ich vergessen habe was zu flicken ;-)

Ok dann nimm bitte mal die Zeilen
mydelete = SP0DR;
raus. und probiere nochmal.

Du siehst jetzt den Unterschied zwischen deinem und meinem Programm, die 
Änderung betrifft wesentlich weniger Zeilen ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hab ich gemacht! Programm funktioniert wie immer mit 2,51V ;)

Stimmt die Spannung zu unserer Eingabe?

von J. R. (cia_man)


Lesenswert?

Bereinigte Version:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{ 
7
  SP0DR = myValue; /* Data goes to SPI data register*/
8
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
9
}
10
11
main()
12
{ 
13
  
14
  int i = 1;
15
  
16
  /* Init for SPI Interface */
17
  PORTS |= 0x80;
18
  DDRS = DDRS | 0xF0; /* outputs */
19
  SP0CR1 = 0x58; /* 0b01011000 */
20
  SP0CR2 = 0; /* Normal mode */
21
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
22
23
  while (i>0) /* Endles Data sending for testing only */
24
  {
25
    PORTS &= ~0x80;  /* /SS output low */
26
    mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
27
    mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
28
    mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
29
    PORTS |= 0x80;    /* /SS output high */
30
31
/* Die Frage ist brauche ich hier eine kurze Pause? Wir werden das messen */
32
33
    PORTS &= ~0x80;  /* /SS output low */
34
    mySPITrans(0x10); /* Analog Value Byte1 MSB first        */
35
    mySPITrans(0x03); /* Analog Value Byte2 24 bit total    */
36
    mySPITrans(0xFC); /* Analog Value Byte3 LSB last         */
37
    PORTS |= 0x80;    /* /SS output high */
38
  }
39
}


Geht ;) freu

2,51V!

von Frank S. (franksanderdo)


Lesenswert?

Spannung zu hoch?

kleinen Moment muss ich Rechnen:

Du hast Recht!

Wo haben wir den Denkfehler?
Kannst Du mal den Wert auf 0 setzen und schauen was da raus kommt?
Danach das ganz linke Bit (MSB) setzen und schauen was dann kommt?

Bis gleich mal ;-)

Frank

von J. R. (cia_man)


Lesenswert?

1
    PORTS &= ~0x80;  /* /SS output low */
2
    mySPITrans(0x10); /* Analog Value Byte1 MSB first        */
3
    mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
4
    mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
5
    PORTS |= 0x80;    /* /SS output high */
6
  }
7
}

trotzdem 2,51 V :(

ohoh!

von Frank S. (franksanderdo)


Lesenswert?

Hast Du noch den Oscar am Vout?
Geht der beim Neustart des uC kurz auf 0?

von J. R. (cia_man)


Lesenswert?

Ne... wenn ich den µC resette und das Programm noch nicht gestartet ist, 
bleibt er oben. Auch wenn ich dann das Programm neu lade bleibt er oben, 
ohne Schwankung!

Ist das okay?

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Mein Verdacht ist, das wir im Moment mit unseren Tests nicht wirklich 
den DAC neu setzen.
Das müssen wir jetzt raus finden.

Ergo gehen wir jetzt die Testschritte wieder rückwärts bis das er was 
sagt zu uns ;-)

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Ok das ist genau mein Verdacht!

Ergo gehen wir zurück zu deinem Programm und versuchen mal dort den Wert 
zu ändern ;-)

Mal sehen was er sagt

von J. R. (cia_man)


Lesenswert?

Hätte jetzt gedacht die Initialisierung des DAC ist falsch:
1
while (i>0) /* Endles Data sending for testing only */
2
  {
3
    PORTS &= ~0x80;  /* /SS output low */
4
    mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
5
    mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
6
    mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
7
    PORTS |= 0x80;    /* /SS output high */

Stimmt aber nach dem Datenblatt :)

Shit^^

von J. R. (cia_man)


Lesenswert?

Vlt ist unten wo du meinst eine Pause von Nöten? ;) Im Programm!

von Frank S. (franksanderdo)


Lesenswert?

Um zu verhinder das der DAC sich an der Endlos initialisierung stört 
habe ich die mal aus der Schleife raus genommen.
Zusätzlich habe ich sichergestellt das sich der Analogwert ständig 
andert ;-)

Damit sollten wir auf dem Oscar was Sägezahnähnliches bekommen
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
  return = 0;
13
}
14
15
main()
16
{ 
17
  
18
  int i = 1;
19
  unsigned char myvalue = 0;
20
  
21
  /* Init for SPI Interface */
22
  PORTS |= 0x80;
23
  DDRS = DDRS | 0xF0; /* outputs */
24
  SP0CR1 = 0x58; /* 0b01011000 */
25
  SP0CR2 = 0; /* Normal mode */
26
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
27
28
  /* Init to the DAC */
29
  PORTS &= ~0x80;  /* /SS output low */
30
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
31
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
32
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
33
  PORTS |= 0x80;    /* /SS output high */
34
35
  while (i>0) /* Endles Data sending for testing only */
36
  {
37
    PORTS &= ~0x80;  /* /SS output low */
38
    mySPITrans(0x10); /* Analog Value Byte1 MSB first        */
39
//    mySPITrans(0x03); /* Analog Value Byte2 24 bit total    */
40
    mySPITrans(myvalue); /* Analog Value Byte2 24 bit total    */
41
    myvalue += 1;
42
    mySPITrans(0xFC); /* Analog Value Byte3 LSB last         */
43
    PORTS |= 0x80;    /* /SS output high */
44
  }
45
}

von J. R. (cia_man)


Lesenswert?

40-48 ns ist Minimum SYNC high time!

Haben wir das hier?

von J. R. (cia_man)


Lesenswert?

Musste übrigens return = 0; entfernen sonst geht es nicht ;)

von Frank S. (franksanderdo)


Lesenswert?

Das ist eben die Frage.

Sei mal so lieb und setz das Programm wo ich gerade gepostet habe ein 
und schau was passiert.
Du kannst am /SS mit dem oscar nachmessen ob der Puls lang genug ist
sollte das nicht der Fall sein setzen wir in die Schleife gleich als 
erstes einen Wait 1ms

Grüße Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hier der Sägezahn ;)

von Frank S. (franksanderdo)


Lesenswert?

GEIL!!!

von J. R. (cia_man)


Lesenswert?

Der geht ja nie auf 0 V :D

von Frank S. (franksanderdo)


Lesenswert?

Ok das ist doch mal ein echtes Ergebnis!!

Jetzt müssen wir raus finden was wir falsch machen wegen den 2,5V
Bleib bei dem Programm was Ich da geschickt habe und kommentier die 
Zeile
myvalue +=1 aus.

Setze alle 18 bit auf 0 und schau was als Ergebnis kommt.
Danach setze das MSB auf 1 und schau was dann als Ergebnis kommt.
zuletzt alle 18 bit auf 1 und wieder das Ergebnis festhalten.

Ich muss mich jetzt auf die Socken nach Hause machen.
Ich bin dann in ca. 1 1/2 STunden wieder erreichbar ;-)

Sei so lieb und poste die Ergebnisse das ich grübeln kann wo der Offset 
her kommt.

Grüße
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Ich habe die 3 Bilder angehängt.

1. 18 Bit auf 0
2. 18 Bit auf 0 + MSB auf 1
3. 18 Bit auf 1 + MSB auf 1

Die letzten beiden Ergebnisse erscheinen mir als falsch, da das MSB doch 
falsch gesetzt ist.

Langsam wird es echt delikat ;)

MSB = 1 bedeutet ja nach Datenblatt read ;)

Wir wollen doch aber schreiben...

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Zu guter letzt noch eine Aufnahme mit:

18 Bit auf 1 + MSB auf 0


Konnte ich vorher nicht mehr posten, da Diskette für das Oszi voll war 
;=)
Also entschuldigt den Doppelpost ;)

Ich hoffe das hilft dir für die Fehlersuche.

Jumper auf dem Board habe ich auch nochmals gecheckt, die passen.

THX!

von J. R. (cia_man)


Lesenswert?

Code den ich verwendet habe:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
main()
15
{ 
16
  
17
  int i = 1;
18
  unsigned char myvalue = 0;
19
  
20
  /* Init for SPI Interface */
21
  PORTS |= 0x80;
22
  DDRS = DDRS | 0xF0; /* outputs */
23
  SP0CR1 = 0x58; /* 0b01011000 */
24
  SP0CR2 = 0; /* Normal mode */
25
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
26
27
  /* Init to the DAC */
28
  PORTS &= ~0x80;  /* /SS output low */
29
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
30
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
31
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
32
  PORTS |= 0x80;    /* /SS output high */
33
34
  while (i>0) /* Endles Data sending for testing only */
35
  {
36
    PORTS &= ~0x80;  /* /SS output low */
37
    mySPITrans(0x1F); /* Analog Value Byte1 MSB first        */
38
    mySPITrans(0xFF); /* Analog Value Byte2 24 bit total    */
39
    //mySPITrans(myvalue); /* Analog Value Byte2 24 bit total    */
40
    //myvalue += 1;
41
    mySPITrans(0xFC); /* Analog Value Byte3 LSB last         */
42
    PORTS |= 0x80;    /* /SS output high */
43
  }
44
}

Hoffe hier habe ich nichts verhauen ;)

Danke für die Hilfe.

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Hat es einen bestimmten Grund das Du den return aus der Funktion 
genommen hast?

offen gestanden verstehe ich das Ergebnis nicht auf Anhieb.

Alles 0 gibt 2,5V was die Hälfte von 5V ist ;-)
Daraus täte ich schliessen das MSB gibt das Vorzeichen.
Das wird durch alles inclusive MSB 1 = 0V bestätigt.

Blöd ist nur das dann Alles ausser MSB 1 = 5V hätte sein sollen :-(

Moment mal.....
18Bit + MSB????? Jochen? was meinst Du damit? Hast DU etwa versucht 
einen 19 Bit DAC daraus zu machen?

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Da ich etwas verwirrt bin würde ich gerne eine weitere Messung 
durchführen.
Dafür müsstest Du mal das angehängte Programm laufen lassen und den 
Oscar ein Bild machen lassen.

Das gibt wieder einen Sägezahn, aber diesmal will ich die gesammten 18 
Bit ausnutzen. Bin gespannt was dabei raus kommt :-D

Das sieht etwas komisch aus im Programm weil ich einfach nicht weis 
welche Typen mir in deine Entwicklungsumgebung zur Verfügung stehen. 
Dazu kommt das mein C offensichtlich auch etwas eingerostet ist ;-)
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
main()
15
{ 
16
  
17
  int i = 1;
18
  unsigned char mylowbyte = 0x00;
19
  unsigned char mymidbyte = 0x00;
20
  unsigned char myhighbyte = 0x10;
21
  
22
  /* Init for SPI Interface */
23
  PORTS |= 0x80;
24
  DDRS = DDRS | 0xF0; /* outputs */
25
  SP0CR1 = 0x58; /* 0b01011000 */
26
  SP0CR2 = 0; /* Normal mode */
27
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
28
29
  /* Init to the DAC */
30
  PORTS &= ~0x80;  /* /SS output low */
31
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
32
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
33
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
34
  PORTS |= 0x80;    /* /SS output high */
35
36
  while (i>0) /* Endles Data sending for testing only */
37
  {
38
    PORTS &= ~0x80;  /* /SS output low */
39
    mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
40
    mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
41
    mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
42
    PORTS |= 0x80;    /* /SS output high */
43
    mylowbyte +=1;  /* we are raising the voltage by 1 step */
44
    if (mylowbyte == 0xFF) /* if byte is full we increase the next one */
45
      mymidbyte +=1;
46
    if (mymidbyte == 0xFF) /* if byte is full we increase the next one */
47
      myhighbyte +=1
48
    myhighbyte &= 0x1F  /*we make sure the left nibble of byte is not changed*/
49
    myhighbyte |= 0x10 /*Important that the register address is still there*/
50
  }
51
}

von Frank S. (franksanderdo)


Lesenswert?

Und noch mal ich, sorry ich habe einen Teil deines textes überlesen und 
jetzt ist mir klar das wir beide uns missverstanden haben :-)

Ich meinte das MSB des 18bit Werts. Nicht das MSB der 24bit.
Sorry hätte ich anders sagen sollen. So konnte das nix werden :-(

Probier mal meinen Hypersägezahn von 1 Post vorher. Ich gehe mal davon 
aus das der tut ;-)



Gruß
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Das Ergebnis des Programms ist oben zu sehen -.-

2 Fragen: 1. Geht bei Hex das: myhighbyte +=1? ;)

2. Was bedeuten diese Zeilen genau?

myhighbyte &= 0x1F  /*we make sure the left nibble of byte is not 
changed*/
    myhighbyte |= 0x10 /*Important that the register address is still 
there*/

damit kann ich jetzt nichts richtiges anfangen trotz Kommentar ;)

Danke.

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Nach einer gewissen Zeit kommt nun dieser Screen! ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

1. Frage: Ja das ist kein Problem, weil Hex ist ja nur eine 
Darstellungsform der Zahl.

2. Frage:

myhighbyte &= 0x1F
ist eine undverknüpfung welche ich zum maskieren benutzte. Einfach 
gesagt durch das UND stelle ich sicher das die linken 3 bit auf 0 sind.

Jetzt habe ich aber noch das Problem das ich ja nicht sagen kann ob das 
4. bit von links eins ist (meine Zählerei erzeugt da auch schon mal eine 
0) deswegen die Zeile
myhighbyte |= 0x10

über das ODER stelle ich sicher das eben dieses eine bit sicher 1 ist.

Das war zumindest der Plan :-(

Ich grübel mal noch einen Moment über dem Programm wo ich da den 
Denkfehler habe.
Kannst DU derweil unseren Test noch mla machen mit 0x000000, 0x800000 
und 0x8FFFFF als daten? Das sollte uns sagen wie das linke bit in den 
Daten funktioniert.

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ok der 2. Screen ist zwar nicht was ich erwartet habe, aber immerhin 
schon mal was mehr als vorher. Ich bin allerdings immer noch verwirrt 
über das Ergebnis.

Danach haben wir einen Fehler in der Referenzbeschaltung. :-(

Wie gesagt gib mir bitte mal die 3 o.g. tests und wir schauen von Da 
weiter ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Du meinst aber damit, dass ich in das vorherige Programm diese Werte für 
das 18 Bit Wort einpflege oder? Nicht das wir schon wieder an einander 
vorbei reden ;)

Mit vorheriges Programm meine ich nicht das Jetzige sondern das zuvor!

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hallo!

Hier das Programm, das ich verwendet habe, mit den letzten von dir 
geforderten Werten:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
main()
15
{ 
16
  
17
  int i = 1;
18
  unsigned char myvalue = 0;
19
  
20
  /* Init for SPI Interface */
21
  PORTS |= 0x80;
22
  DDRS = DDRS | 0xF0; /* outputs */
23
  SP0CR1 = 0x58; /* 0b01011000 */
24
  SP0CR2 = 0; /* Normal mode */
25
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
26
27
  /* Init to the DAC */
28
  PORTS &= ~0x80;  /* /SS output low */
29
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
30
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
31
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
32
  PORTS |= 0x80;    /* /SS output high */
33
34
  while (i>0) /* Endles Data sending for testing only */
35
  {
36
    PORTS &= ~0x80;  /* /SS output low */
37
    mySPITrans(0x8F); /* Analog Value Byte1 MSB first        */
38
    mySPITrans(0xFF); /* Analog Value Byte2 24 bit total    */
39
    //mySPITrans(myvalue); /* Analog Value Byte2 24 bit total    */
40
    //myvalue += 1;
41
    mySPITrans(0xFF); /* Analog Value Byte3 LSB last         */
42
    PORTS |= 0x80;    /* /SS output high */
43
  }
44
}


Die Bilder gehen der Reihe nach: 0x000000, 0x800000
und 0x8FFFFF.

Ich hoffe das hilft! ;)

Gruß Jochen

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

das erschüttert mich eher als es hilft :-(

Liegt aber daran das ich DIr die falschen Werte gegeben habe.
Wir haben gerade den Fehler von gestern wiederholt :-(

Laso nochmal weil es so schön war mit diesen Werten:

0x100000 (entspricht 0 in den 18bit)
0x17FFFC (entspricht nur MSB der 18bit nicht gestezt)
0x180000 (enspricht MSB der 18bit gesetzt)
0x1FFFFC (alle 18 bit gesetzt)

Sorry war mein Fehler. Heute ist offensichtlich nicht mein Tag. Hab hier 
auch schon was zerlegt heute ;-)

Grüße Frank

von J. R. (cia_man)


Lesenswert?

Alles roger! Hab ich mir auch schon fast gedacht ;) Weil das ganze hat 
wirklich keinen Sinn ergeben :P

Also dann mache ich mich ans Werk! Bis dann!

Ne andere Frage: Welche Uhrzeit ist eigentlich bei dir? Ne andere wie 
bei uns in Ger oder?

Grüßle

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Jep, wir sind hier im Sommer eine Stunde voraus und im Winter 2.
Also hier ist jetzt 12:00 ;-)

Der heutige Morgen war ein graus deswegen bin ich auch etwas langsam im 
Antworten.
Das nächste mal wenn DU siehst das ich Unfug schicke, hau mir auf die 
Finger ;-)
Spart uns beiden Zeit wenn wir da einen Unfugfilter einbauen :-D

Grüße
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> Jep, wir sind hier im Sommer eine Stunde voraus und im Winter 2.
> Also hier ist jetzt 12:00 ;-)
>
> Der heutige Morgen war ein graus deswegen bin ich auch etwas langsam im
> Antworten.
> Das nächste mal wenn DU siehst das ich Unfug schicke, hau mir auf die
> Finger ;-)
> Spart uns beiden Zeit wenn wir da einen Unfugfilter einbauen :-D
>
> Grüße
> Frank

Owe... naja beruhige dich! Du bist da mit so grausamen Morgen nicht 
alleine ;) die hab ich manchmal auch ;)

Das nächste mal mach ich das mit dem "auf die Finger klopfen" :P :)

So nun zu den Bildchen... ich bin der Reihe nach vorgegangen wie du oben 
gesagt hast! 5 beginnend 8 endend ;)

Diese sehen jetzt schon viel versprechender aus ;)

Beachte bitte die Einteilung der y-Achse (wurde ab und an geändert von 
mir!) :)

Danke & Gruß

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen, das sieht schon viel besser aus.

das linke bit ist wie ich "befürchtet" habe das Vorzeichenbit.
Ok, wieder was gelernt ;-)

Jetzt kommt die alles entscheidende Frage:
Ist Dir klar was die Bilder (Werte) sagen?

Ich nutze Die Zeit bist DU antwortest und denke noch malüber den 
hypersägezahn nach, weil der kann so nicht funktionieren ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Naja ich sage mal so: wenn jetzt also das MSB 0 ist dann kommen wir mit 
allen anderen 1 auf 5 V. Dagegen muss das MSB =1 sein und der Rest Null 
damit wir auf 0 kommen :)

Nur das mit dem Vorzeichen ist mir jetzt nicht ganz klar... also das mit 
dem MSB. Teilt das das ganze in 2 Hälften? :)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

wenn Du die Schleife unten mal in unseren Hypersägezahn einsetzt. (die 
alte ersetzt)
Bitte tausche auch die definition von myhighbyte gegen die neue.

und den Oscar auf 1V Teilung einstellst sollten wir was zu sehen 
bekommen ;-)
Wenn ich nicht ganz falsch denke wird das etwas wüst aussehen, weil ich 
nicht ganz ordentlich beim überlauf arbeite, aber lassen wir uns 
überraschen ;-)
1
  unsigned char myhighbyte = 0x18;
2
3
  while (i>0) /* Endles Data sending for testing only */
4
  {
5
    PORTS &= ~0x80;  /* /SS output low */
6
    mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
7
    mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
8
    mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
9
    PORTS |= 0x80;    /* /SS output high */
10
    mylowbyte +=1;  /* we are raising the voltage by 1 step */
11
    if (mylowbyte == 0xFF) /* if byte is full we increase the next one */
12
      mymidbyte +=1;
13
    if (mymidbyte == 0xFF) /* if byte is full we increase the next one */
14
    {
15
      myhighbyte +=1;
16
      if (myhighbyte == 0x1F)
17
      {
18
        myhighbyte = 0x10;
19
        mylowbiyte = 0x00;
20
        mymidbyte = 0x00;
21
      }
22
    }
23
    myhighbyte &= 0x1F  /*we make sure the left nibble of byte is not changed*/
24
    myhighbyte |= 0x10 /*Important that the register address is still there*/
25
  }

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Du bist schon sehr gut!!

Du kannst sagen:

das MSB (der 18bit ;-) ) schaltet zwischen von der Mitte (2,5V) auf den 
unteren Grenzwert (0V).

Die folgenden Bits addieren dann den eingestellten wert dazu.
sprich wenn du z.B. 1,234V einstellst kannst Du mit dem linken bit 
entscheiden ob da entweder 1,234V (linkes bit an) oder 2,734V (linkes 
bit aus) rauskommen ;-)

Bedeutet du hast insgesammt 262143 Schritte a 0,000019074 V zur 
Verfügung um deine 5 Volt darzustellen.

Wir werden in kürze eine kleine Funktion schreiben die Dir aus einem 
gewünschten Wert in V den passenden DAC Datensatz baut ;-)

Aber das kommt nach dem Sägezahn ;-)

Grüße Frank

von J. R. (cia_man)


Lesenswert?

Genau so habe ich mir das gerade auf dem "stillen Örtchen" ausgedacht ;)

Danke für die Blumen X)

Wie lange dauert das auf dem Oszi bis der Sägezahn kommen soll? :)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

was Du mir aber verraten kannst:
welche variablen Typen (mit welcher bitbreite) stehen uns denn in deiner 
Entwicklungsumgebung zu Verfügung?

Das sollten wir wissen und uns darauf einigen, um die 
Umrechnungsfunktion entsprechend definieren zu können ;-)

Grüße
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Dein Programm erscheint mir als schlüssig ;) Jedoch ist oben das 
Ergebnis ;(
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
main()
15
{ 
16
  
17
  int i = 1;
18
  unsigned char mylowbyte = 0x00;
19
  unsigned char mymidbyte = 0x00;
20
  unsigned char myhighbyte = 0x18;
21
  
22
  /* Init for SPI Interface */
23
  PORTS |= 0x80;
24
  DDRS = DDRS | 0xF0; /* outputs */
25
  SP0CR1 = 0x58; /* 0b01011000 */
26
  SP0CR2 = 0; /* Normal mode */
27
  SP0BR = 0x07; /* 31,25 kHz SPI clock */
28
29
  /* Init to the DAC */
30
  PORTS &= ~0x80;  /* /SS output low */
31
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
32
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
33
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
34
  PORTS |= 0x80;    /* /SS output high */
35
36
  while (i>0) /* Endles Data sending for testing only */
37
  {
38
    PORTS &= ~0x80;  /* /SS output low */
39
    mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
40
    mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
41
    mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
42
    PORTS |= 0x80;    /* /SS output high */
43
    mylowbyte +=1;  /* we are raising the voltage by 1 step */
44
    if (mylowbyte == 0xFF) /* if byte is full we increase the next one */
45
      mymidbyte +=1;
46
    if (mymidbyte == 0xFF) /* if byte is full we increase the next one */
47
    {
48
      myhighbyte +=1;
49
      if (myhighbyte == 0x1F)
50
      {
51
        myhighbyte = 0x10;
52
        mylowbyte = 0x00;
53
        mymidbyte = 0x00;
54
      }
55
    }
56
    myhighbyte &= 0x1F;  /*we make sure the left nibble of byte is not changed*/
57
    myhighbyte |= 0x10; /*Important that the register address is still there*/
58
  }
59
}

Das Programm! Bin erst mal was essen ;)

von Frank S. (franksanderdo)


Lesenswert?

Der Sägezahn sollte eigentlich sofort kommen, wobei der sehr lang wird 
vermute ich.
Und wie gesagt die Teilung sollte 1V sein das wir eine Chance haben den 
Anfang auch zu sehen.

Wenn das zu lange dauert, dann kannst Du versuchen den Takt zu erhöhen 
mit dem DBR0 Register ;-)

Grüße Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Nach einer gewissen Zeit! Ist jetzt folgendes zu sehen :(

von APW (Gast)


Lesenswert?

Sofern ich nichts verpasst habe, programmiert Jochen in stinknormlem C.
Soviel zu den Datentypen.

Habt Ihr euch mal Gedanken gemacht über die Laufzeit von eurem Sägezahn 
Testprogramm ?

Mal abgesehen davon, dass in dem Sägezahn Fehler drin sind, sollte eine 
Periode so grob ca. 200 sec. dauern, wenn ich mich nicht verrechnet 
habe.

Aber rechnet das mal selber nach.

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

guten Appetit ;-)

Wenn ich mich nicht täüsche, dann steigt der Wert langsam an. Das ist ja 
mal nicht so schlecht.

Ich Rechne mal schnell:

bei 31,25khz Takt brauchen wir 0,000768 Sekunden für 1 mal DAC laden.
Für den ganzen Durchlauf von 0 - 5V sollten wir also ca. 202 Sekunden 
brauchen ;-)
Das sind 3min 21 Sekunden....

OK ich gebe es zu. Da sollten wir was am Takt drehen ;-)
Ich glaube das Du den ohne Sorgen erhöhen kannst. :-D

Grüße
Frank

von APW (Gast)


Lesenswert?

APW schrieb:
> Mal abgesehen davon, dass in dem Sägezahn Fehler drin sind, sollte eine
> Periode so grob ca. 200 sec. dauern, wenn ich mich nicht verrechnet
> habe.

Muss mich korrigieren

Ihr macht nicht die vollen 18 Bit durch, oder?

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Datentypen ;)

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW,

Ich bin froh das Du uns noch verfolgst ;-)

jep braucht so lange.
Ich gebe auch zu das ich über den Takt nicht nachgedacht hatte.
Im Anfang hatte ich Jochen gebeten nicht zu schnell zu takten das er 
einfacher was messen kann. ;-)

Jochen programmiert in C, wobei ich mir nicht sicher bin welche Typen in 
seiner Umgebung ( hab nicht mehr im Kopf welche er da hat) abgebildet 
sind. Ich gebe auch zu das ich wegen mangelnder Übung nicht mehr im Kopf 
habe welcher Typ wie breit ist.

Nicht zu letzt möchte ich Jochen dazu bringen sich diese Dinge 
anzuschauen. Er hat noch weniger Erfahrung als ich mit C und ich glaube 
und hoffe ihn mit solchen Fragen im lernen zu unterstützen ;-)

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW.


wenn ich mich nicht vertan habe machen wir ein bischen weniger, weil ich 
die Abfragen der Bytewechsel nicht sauber gelöst habe.
Für unsere Zeitberechnung glaube ich können wir aber einfach mal von den 
18 bit ausgehen :-)

Ja ich gebe es zu. Ich bin zu faul das genau auszurechnen ;-)

Grüße
Frank

von APW (Gast)


Lesenswert?

Frank Sander schrieb:
> Ich bin froh das Du uns noch verfolgst ;-)

Sagen wir mal so - ich leide mit euch.

Wenn sich am DAC-Ausgang was tut, aber das, was sich tut nicht ganz 
plausibel ist, würde ich mal folgendes vorschlagen:
Nicht mit einem Sägezahn testen, sondern mit festen DAC-Werten,
diese am Ausgang mit Multimeter messen+protokollieren.

Im Prinzip so z.B.:

...
Init
...
SendDACValue(0)          // 0%   =0x00000000
Wait_10sec               //DAC Ausgang messen + aufschreiben
SendDACValue(0x00010000) // 25%  =0x00010000
Wait_10sec               //DAC Ausgang messen + aufschreiben
SendDACValue(0x0001FFFF) // 50%-1=0x0001FFFF
Wait_10sec               //DAC Ausgang messen + aufschreiben
SendDACValue(0x00020000) // 50%  =0x00020000
Wait_10sec               //DAC Ausgang messen + aufschreiben
SendDACValue(0x00030000) // 75%  =0x00030000
Wait_10sec               //DAC Ausgang messen + aufschreiben
SendDACValue(0x0003FFFF) // 100% =0x0003FFFF (ist genaugenommen 100%-1)
Wait_10sec               //DAC Ausgang messen + aufschreiben

Das ganze in ner Endlosschleife

von J. R. (cia_man)


Lesenswert?

Neuer Takt:

SP0BR = 0x03; /* 500,0 kHz SPI clock */

Bild folgt bzw Bericht!

von J. R. (cia_man)


Lesenswert?

Der Sägezahn läuft von der Y-Ablenkung in einem falschen und viel zu 
kleinen Bereich ab! Siehe Bild oben... die Frage ist nur Warum?

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW,

oje, aber eigentlich wollten wir Dich net leiden lassen.
Danke für den Tip. Den werden wir sicher noch umsetzen (müssen).

Das mit dem Sägezahn hatte ich eigentlich mehr als Jux gedacht nur 
leider eben die Laufzeit nicht beachtet.

Darf ich Dich um einen Gefallen bitten?
Kannst Du uns bei der Funktion 5Vin18bit helfen?

Meine Idee war die gewünschte Spannung in einem double durch 0,00019074 
zu teilen. damit habe ich dann die Anzahl Schritte. diese dann in den 
18bit ablegen und das Verschicken haben wir ja schon.

Haste etwas Zeit und Lust?

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

naja, weil ich den nicht sauber umgesetzt habe.
der Bereich den Du da siehst sind das Lowbyte und Midbyte.

Es war mir bewust das da kein ordentlicher Sägezahn rauskommt. Was ich 
aber komplett übersehen hatte war der Takt und damit die Zeit. ;-)

Geh bitte mal hin und teste wie APW vorgeschlagen hat ein par Werte aus.
Nach dem gelernten solltest Du ja jetzt in der Lage sein Werte 
einzustellen ;-)

Ich grübel derweil (hoffentlich mit APW) mal über die Umrechnung V in 
Schritte.

Kannst Du uns verraten wie DU dann weiter vorgehen willst?
Ist das mehr eine 0 - 5V Anwendung oder mehr eine 0-100% Anwendung?

Grüße
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Es geht!

Hier der Code:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
main()
15
{ 
16
  
17
  int i = 1;
18
  unsigned char mylowbyte = 0x00;
19
  unsigned char mymidbyte = 0x00;
20
  unsigned char myhighbyte = 0x18;
21
  
22
  /* Init for SPI Interface */
23
  PORTS |= 0x80;
24
  DDRS = DDRS | 0xF0; /* outputs */
25
  SP0CR1 = 0x58; /* 0b01011000 */
26
  SP0CR2 = 0; /* Normal mode */
27
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
28
29
  /* Init to the DAC */
30
  PORTS &= ~0x80;  /* /SS output low */
31
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
32
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
33
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
34
  PORTS |= 0x80;    /* /SS output high */
35
36
  while (i>0) /* Endles Data sending for testing only */
37
  {
38
    PORTS &= ~0x80;  /* /SS output low */
39
    mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
40
    mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
41
    mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
42
    PORTS |= 0x80;    /* /SS output high */
43
    mylowbyte +=1;  /* we are raising the voltage by 1 step */
44
    if (mylowbyte == 0xFF) /* if byte is full we increase the next one */
45
  {
46
      mymidbyte +=1;
47
    if (mymidbyte == 0xFF) /* if byte is full we increase the next one */
48
    {
49
      myhighbyte +=1;
50
      if (myhighbyte == 0x1F)
51
      {
52
        myhighbyte = 0x10;
53
        mylowbyte = 0x00;
54
        mymidbyte = 0x00;
55
      }
56
    }
57
  }
58
    myhighbyte &= 0x1F;  /*we make sure the left nibble of byte is not changed*/
59
    myhighbyte |= 0x10; /*Important that the register address is still there*/
60
  }
61
}


Du hattest einfach ne Klammer vergessen ;) bei der ersten If-Anweisung.

Jetzt geht es.... ich versuche mal den Takt so schnell zu machen, dass 
wir ihn auf dem Oszi zu Gesicht bekommen ;)

Bei meiner Anwendung geht es schon um Spannungswerte! Nicht 0% 100% 
wobei das natürlich eine Definitionssache ist ;)

Ich werde dann auch einmal wie APW gesagt hat feste Werte testen! ;)


Jetzt ist das Bild vom Sägezahn schön.... im Anhang ist es... Takt: 1 
MHz.

Danke bis hierher viel mals!!!!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

sorry für den Fehler, bin eben doch aus der Übung.

Die Kanten in dem Ding sind meiner unsauberen Programmierung and den 
Bytegrenzen geschuldet. Alles in Allem sieht das aber ganz nett aus ;-)

Grüße
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Das ganze nochmal mit 4 MHz Takt!  Weil es gerade so schön ist g

von Frank S. (franksanderdo)


Lesenswert?

Ich sehe es fängt an Dir Spass zu machen :-D

von J. R. (cia_man)


Lesenswert?

Grundsätzlich gilt also: bei meinem 18 Bit Wert ist das ganz Linke Bit 
(MSB) das Bit, welches das Vorzeichen, von dem wir oben gesprochen haben 
festlegt oder?

Ich kann also dann de Fakto den Bereich nur mit 17 Bit einteilen... 
damit meine ich den oberen oder unteren Bereich (die 2 Hälften). Und 
dort dann 17 Bit Einteilung oder?

von APW (Gast)


Lesenswert?

Das was ich oben vorgeschlagen habe, also Festwerte auszugeben, war nur 
für den Fall gedacht, dass der Sägenzahn nicht klappt.
Das sieht aber jetzt eigentlich recht gut aus.

Die Frage ist, was Jochen letztendlich vorhat.
Braucht er eine Ausgabefunktion, der er einen Spannungswert übergibt,
oder reicht die Übergabe des 18-Bit DAC Wertes?

Wenn man mit Fliesspunkt anfängt, bekommt man es event. mit compiler-
spezifischen Sachen zu tun, ausserdem explodiert die Codegröße.

von J. R. (cia_man)


Lesenswert?

Ich sag mal so: ich möchte eine Spannung respektive Strom durch den 
Benutzer vorgeben lassen und diese soll dann der DAC ausgeben. Mehr erst 
mal nicht ;)

Und das soll sehr oft wechseln können... vlt auch mit einer Datenbank :)

von APW (Gast)


Lesenswert?

Hab auch schon länger nicht mehr in C programmiert.
Event. funktioniert diese Version vom Sägezahn:


if ((mylowbyte +=0x04) == 0)
{ if (++mymidbyte == 0)
  { if (++myhighbyte == 0x14)
    { myhighbyte = 0x10;
    }
  }
}

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ich bin nicht sicher ob Du dich gerade verrennst.
Die Auflösung ist immer noch 18 Bit.

Wir betrachten einen Bereich von 0V - 5V.
Diesen Bereich kannst Du mit den 18 Bit einteilen.
Wo wir gerade drüber stolpern ist die Tatsache das unser linkes Bit 
invertiert funktioniert.

Dazu solltest Du Dir noch mal die Grundschaltung des DAC anschauen.
Das Dingen ist dafür ausgelegt das es -xV - +xV darstellen kann.
Wir haben durch die Art wie wir der Referenzen beschaltet haben die 
"Mitte" auf 2,5V gelegt. Quasi die DAC interne Masse auf 2,5V angehoben 
(Bitte das ist ein Vergleich der ganz böse hinkt, aber das führt jetzt 
zu weit)

Kurz:
Du hast die vollen 18 Bit Auflösung zur Verfügung!!
Ob Du die wirklich benötigst? Ich habe meine Zweifel!

Bei einem Bereich 0-5V stellt das eine Schrittweite von 0,00019074V
Wenn Du mal auf die Bilder Die Du gemacht hast schaust (nimm z.B. eines 
wo wir bei 2,5V gehangen haben) dann siehst Du dort das Signal um die 
80mV (0,08V) rauschen.
Das bedeutet das ca, 400 Schritte unseres DAC im Rauschen unter gehen.
Brutal gesagt (ist etwas übertrieben) können wir also getrost die 
RECHTEN 9 Bit unseres DAC ignorieren.

Daher auch meine Reaktion als Du das im Anfang mit den 18 Bit um die 
Ecke gekommen bist. Um die wirklich zu nutzen ist etwas Arbeit an der 
analogen Technik ausserhalb des DAC notwendig ;-)

So ich mache mich jetzt auf den Weg nach Hause.
Wie immer, in ca. 1 1/2 Stunden bin ich wieder erreichbar :D

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW

Auf alle Fälle schon mal besser als meines.
Da ist schon mal die Reihenfolge von increment und Abfrage korrigiert.

Eine kleine Übung für Jochen wenn er noch Lust hat das aus zu probieren 
;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hallo!

Ich wollte das mit den festen Werten probieren!

Jedoch kommt bei diesem Programm nicht der Sprung zustande den ich gerne 
hätte von 0% auf 25% usw... er bleibt einfach bei der 0 kleben.

Hier das verwendete Programm:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
void delay1ms(void) {
15
  asm("ldy #2666"); //2666 in Y-Register laden
16
  asm("dbne y,.");  // Decrement, bis Y=0 ist /
17
          //3cyc x 125ns x 2666 = 0,99975ms
18
}
19
20
21
void wait(int duration)
22
{
23
  while(duration--)
24
  delay1ms();
25
}
26
27
28
29
main()
30
{ 
31
  
32
  int i = 1;
33
  
34
  /* Init for SPI Interface */
35
  PORTS |= 0x80;
36
  DDRS = DDRS | 0xF0; /* outputs */
37
  SP0CR1 = 0x58; /* 0b01011000 */
38
  SP0CR2 = 0; /* Normal mode */
39
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
40
41
  /* Init to the DAC */
42
  PORTS &= ~0x80;  /* /SS output low */
43
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
44
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
45
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
46
  PORTS |= 0x80;    /* /SS output high */
47
48
  while (i>0) /* Endles Data sending for testing only */
49
  {
50
    PORTS &= ~0x80;  /* /SS output low */
51
    mySPITrans(0x18); /* Analog Value Byte1 MSB first        */
52
    mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
53
    mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
54
    PORTS |= 0x80;    /* /SS output high */
55
       
56
    wait(1000);
57
  
58
  PORTS &= ~0x80;  /* /SS output low */
59
  mySPITrans(0x01); /* Analog Value Byte1 MSB first        */
60
    mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
61
    mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
62
    PORTS |= 0x80;    /* /SS output high */
63
  
64
    wait(1000);
65
  
66
  PORTS &= ~0x80;  /* /SS output low */
67
  mySPITrans(0x01); /* Analog Value Byte1 MSB first        */
68
    mySPITrans(0xFF); /* Analog Value Byte2 24 bit total    */
69
    mySPITrans(0xFF); /* Analog Value Byte3 LSB last         */
70
    PORTS |= 0x80;    /* /SS output high */
71
  
72
    wait(1000);
73
   
74
  }
75
}

Danke euch!

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> ich bin nicht sicher ob Du dich gerade verrennst.
> Die Auflösung ist immer noch 18 Bit.
>
> Wir betrachten einen Bereich von 0V - 5V.
> Diesen Bereich kannst Du mit den 18 Bit einteilen.
> Wo wir gerade drüber stolpern ist die Tatsache das unser linkes Bit
> invertiert funktioniert.
>
> Dazu solltest Du Dir noch mal die Grundschaltung des DAC anschauen.
> Das Dingen ist dafür ausgelegt das es -xV - +xV darstellen kann.
> Wir haben durch die Art wie wir der Referenzen beschaltet haben die
> "Mitte" auf 2,5V gelegt. Quasi die DAC interne Masse auf 2,5V angehoben
> (Bitte das ist ein Vergleich der ganz böse hinkt, aber das führt jetzt
> zu weit)
>
> Kurz:
> Du hast die vollen 18 Bit Auflösung zur Verfügung!!
> Ob Du die wirklich benötigst? Ich habe meine Zweifel!
>
> Bei einem Bereich 0-5V stellt das eine Schrittweite von 0,00019074V
> Wenn Du mal auf die Bilder Die Du gemacht hast schaust (nimm z.B. eines
> wo wir bei 2,5V gehangen haben) dann siehst Du dort das Signal um die
> 80mV (0,08V) rauschen.
> Das bedeutet das ca, 400 Schritte unseres DAC im Rauschen unter gehen.
> Brutal gesagt (ist etwas übertrieben) können wir also getrost die
> RECHTEN 9 Bit unseres DAC ignorieren.
>
> Daher auch meine Reaktion als Du das im Anfang mit den 18 Bit um die
> Ecke gekommen bist. Um die wirklich zu nutzen ist etwas Arbeit an der
> analogen Technik ausserhalb des DAC notwendig ;-)
>
> So ich mache mich jetzt auf den Weg nach Hause.
> Wie immer, in ca. 1 1/2 Stunden bin ich wieder erreichbar :D
>
> Grüße
> Frank


Frage vorher nicht übersehen!!! ;)

Ja die Sache mit der Einteilung ist mir nun klar.... normalerweise ist 
ja unser Mittelwert 0 V darum auch das oben und unten ;)

Ja und die Sache mit den 18 Bit Auflösung und dem Rauschen.... ich muss 
mal schauen wo ich noch ein besseres Netzteil herbekomme ;)
Weil momentan hängt ein stink normales dran aber ma sehen.... X)

Gute Heimfahrt Frank!

von APW (Gast)


Lesenswert?

Frank Sander schrieb:
> Wenn Du mal auf die Bilder Die Du gemacht hast schaust (nimm z.B. eines
> wo wir bei 2,5V gehangen haben) dann siehst Du dort das Signal um die
> 80mV (0,08V) rauschen.

Das sind Oszilloskopbilder. Die haben bez. des Rauschens eher wenig 
Aussagekraft.
(Überleg dir mal: 80mV Rauschen ....!?!?)

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hallo!

Das Programm von oben geht nun:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
void delay1ms(void) {
15
  asm("ldy #2666"); //2666 in Y-Register laden
16
  asm("dbne y,.");  // Decrement, bis Y=0 ist /
17
          //3cyc x 125ns x 2666 = 0,99975ms
18
}
19
20
21
void wait(int duration)
22
{
23
  while(duration--)
24
  delay1ms();
25
}
26
27
28
29
main()
30
{ 
31
  
32
  int i = 1;
33
  
34
  /* Init for SPI Interface */
35
  PORTS |= 0x80;
36
  DDRS = DDRS | 0xF0; /* outputs */
37
  SP0CR1 = 0x58; /* 0b01011000 */
38
  SP0CR2 = 0; /* Normal mode */
39
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
40
41
  /* Init to the DAC */
42
  PORTS &= ~0x80;  /* /SS output low */
43
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
44
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
45
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
46
  PORTS |= 0x80;    /* /SS output high */
47
48
  while (i>0) /* Endles Data sending for testing only */
49
  {
50
    PORTS &= ~0x80;  /* /SS output low */
51
    mySPITrans(0x18); /* Analog Value Byte1 MSB first        */
52
    mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
53
    mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
54
    PORTS |= 0x80;    /* /SS output high */
55
       
56
    wait(4000);
57
  
58
  PORTS &= ~0x80;  /* /SS output low */
59
  mySPITrans(0x1C); /* Analog Value Byte1 MSB first        */
60
    mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
61
    mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
62
    PORTS |= 0x80;    /* /SS output high */
63
  
64
    wait(4000);
65
  
66
  PORTS &= ~0x80;  /* /SS output low */
67
  mySPITrans(0x1F); /* Analog Value Byte1 MSB first        */
68
    mySPITrans(0xFF); /* Analog Value Byte2 24 bit total    */
69
    mySPITrans(0xFC); /* Analog Value Byte3 LSB last         */
70
    PORTS |= 0x80;    /* /SS output high */
71
  
72
    wait(4000);
73
  
74
  PORTS &= ~0x80;  /* /SS output low */
75
  mySPITrans(0x14); /* Analog Value Byte1 MSB first        */
76
    mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
77
    mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
78
    PORTS |= 0x80;    /* /SS output high */
79
  
80
    wait(4000);
81
   
82
   PORTS &= ~0x80;  /* /SS output low */
83
  mySPITrans(0x17); /* Analog Value Byte1 MSB first        */
84
    mySPITrans(0xFF); /* Analog Value Byte2 24 bit total    */
85
    mySPITrans(0xFC); /* Analog Value Byte3 LSB last         */
86
    PORTS |= 0x80;    /* /SS output high */
87
  
88
    wait(4000);
89
   
90
   
91
  }
92
}

Zu sehen ist das Ergebnis in den angehängten Bildern.

Die Treppenkurve hier ist für das, was ich dann auch später vorhabe 
beispielhaft!

Danke für alles bisher! ;)

Moin gehts weiter mit dem anderen Sägezahn :)

Bis dann

von Frank S. (franksanderdo)


Lesenswert?

Hallo zusammen,

Tja APW, da glaube ich fast das der Jochen uns bald nimmer braucht ;-)

Wegen der 80mV. Ich gebe DIr recht das ist noch nicht wirklich 
ausgemessen.
Immerhin hat aber der Oscar selber die 80mV gemessen (war bei den 
Bildern wo wir die Grenzwerte und das Vorzeichen getestet haben) ;-)

Leider habe ich zu oft erleben müssen das relativ viel Geld in den DAC 
investiert wurde und dann die analoge Technik drum herum derartig 
vernachlässigt wurde, das auch > 100 mV Rauschen auftraten.

Aber da verlasse ich mich auf Jochen das so etwas nicht passiert!

Ich freu mich erst mal das es rennt und sage auch APW noch mal nen ganz 
lieben Dank für die Hilfe. Bitte nicht aufhöhren, wir werden wohl noch 
was davon brauchen ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Dooooch ich glaube schon, dass der Jochen euch noch etwas braucht :P ;)

Werde mich nun mal an den neuen Sägezahn machen! Ergebnis folgt sobald 
fertig.

Gruß

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich habe jetzt einmal den neuen Sägezahn umgesetzt... das Grundmuster 
wie es APW vorschlägt passt vom Bereich her nicht.... selbes Problem 
hatten ja wir Frank ;)

Jetzt habe ich das ganze etwas modifiziert und schaut mal was für ein 
lustiges Ergebnis rauß kommt.... man beachte die Zeitachse! :)
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
main()
15
{ 
16
  
17
  int i = 1;
18
  unsigned char mylowbyte = 0x00;
19
  unsigned char mymidbyte = 0x00;
20
  unsigned char myhighbyte = 0x18;
21
  
22
  /* Init for SPI Interface */
23
  PORTS |= 0x80;
24
  DDRS = DDRS | 0xF0; /* outputs */
25
  SP0CR1 = 0x58; /* 0b01011000 */
26
  SP0CR2 = 0; /* Normal mode */
27
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
28
29
  /* Init to the DAC */
30
  PORTS &= ~0x80;  /* /SS output low */
31
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
32
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
33
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
34
  PORTS |= 0x80;    /* /SS output high */
35
36
  while (i>0) /* Endles Data sending for testing only */
37
  {
38
    PORTS &= ~0x80;  /* /SS output low */
39
    mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
40
    mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
41
    mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
42
    PORTS |= 0x80;    /* /SS output high */
43
    
44
  if ((mylowbyte +=0x00) == 0)
45
  { if (++mymidbyte == 0)
46
      { if (++myhighbyte == 0x17)
47
        { myhighbyte = 0x10;
48
      }
49
      }
50
  }
51
  
52
  
53
    myhighbyte &= 0x1F;  /*we make sure the left nibble of byte is not changed*/
54
    myhighbyte |= 0x10; /*Important that the register address is still there*/
55
  }
56
}

Verwendeter Code.

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hey!

Der andere Sägezahn-Code, hat so nicht funktioniert wie von APW 
vorgeschlagen. Die modifizierte Version mit dem Ergebnis folgt hier:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
main()
15
{ 
16
  
17
  int i = 1;
18
  unsigned char mylowbyte = 0x00;
19
  unsigned char mymidbyte = 0x00;
20
  unsigned char myhighbyte = 0x18;
21
  
22
  
23
  /* Init for SPI Interface */
24
  PORTS |= 0x80;
25
  DDRS = DDRS | 0xF0; /* outputs */
26
  SP0CR1 = 0x58; /* 0b01011000 */
27
  SP0CR2 = 0; /* Normal mode */
28
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
29
30
  /* Init to the DAC */
31
  PORTS &= ~0x80;  /* /SS output low */
32
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
33
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
34
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
35
  PORTS |= 0x80;    /* /SS output high */
36
37
  while (i>0) /* Endles Data sending for testing only */
38
  { 
39
    PORTS &= ~0x80;  /* /SS output low */
40
    mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
41
    mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
42
    mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
43
    PORTS |= 0x80;    /* /SS output high */
44
    
45
  if ((mylowbyte +=0x04) == 0)
46
  { 
47
    if (++mymidbyte == 0)
48
      { 
49
      if (++myhighbyte == 0x1F)
50
        { 
51
      myhighbyte = 0x10;
52
      
53
      if (myhighbyte == 0x17)
54
      {
55
      mylowbyte = 0x00;
56
      mymidbyte = 0x00;
57
      myhighbyte = 0x18;
58
      }
59
      }
60
      }
61
  }
62
    
63
    myhighbyte &= 0x1F;  /*we make sure the left nibble of byte is not changed*/
64
    myhighbyte |= 0x10; /*Important that the register address is still there*/
65
  }
66
}

Dieser Code geht nun, wie man am Ergebnis erkennt! Jedoch ist meiner 
Ansicht nach der Sägezahn nicht viel besser geworden... was meint ihr 
dazu?
Die eine senkrechte Ecke gefällt mir ganz und gar nicht! Jedoch muss ich 
ja wegen des doofen Vorzeichens dort einen Sprung machen :( Kann man das 
auch noch anders lösen?


Gruß und Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Dir ist klar warum das so aussieht?

Es freut mich das Du ein wenig damit spielst und versuchst.

Parallel dazu mal die Frage zu den (späteren) Nutzereingaben.
Wie kommen diese Daten in den HC12?
Bekommt der eine eigene Tastatur oder ein Rädchen zum drehen oder von 
einem angeschlossenen Rechner?

Ich frage weil ich gerade erste Ideen für den nächsten Arbeitsschritt 
durchgehe ;-)

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen

Ok ich ziehe die Frage zurück ;-)

Ich bin gerade eine Funktion am stricken die dieses Problem umgeht.
Hier schon mal die Grundidee, Ich würde gerne mal ein kleines 
"Wettrennen" mit DIr starten. Mal sehen wer von uns beiden die Funktion 
als erstes am laufen hat :-P

Wir zählen in einer variable einen wert 0V-5V hoch.
Dieser wir an eine Funtion übergeben welche dann schaut ob der Wert <= 
2,5V und damit das Vorzeichenbit einstellt. Als nächstes werden die 
restlichen 17 Bit berechnet und in die 3 "Datenbytes" eingetragen und 
zum DAC übertragen.

Was meinste sollen wir das probieren?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Per PC nehme ich mal an... weil dadurch die Möglichkeiten am größten 
sind ;)

Ja die Senkrechte ist wegen dem MSB-Wechsel oder? ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Die Senkrechte entsteht weil der MSB wechsel zu früh stattfindet.
Ist aber kein Problem, weil mit dem nächsten Schritt können wir das 
beheben ;-)

Ich bin schon am stricken ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Das mit der Funktion können wir gerne einmal machen... ;)

von Frank S. (franksanderdo)


Lesenswert?

:-D Halt Dich an :-D

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

So ich habe mal etwas gebastelt.
Bin mal gespannt wieviele Tipfehler Du findest und wo ich 
Typumwandlungen hätte setzen müssen ;-)

Sag was Du dazu denkst.

Grüße
Frank
1
#include <stdio.h>
2
#include <mc912d128.h>
3
4
const double HalfRange = 2,5;
5
const double DACStepWidth = 5 / 0x03ffff;
6
7
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
8
{
9
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
10
  
11
  SP0DR = myValue; /* Data goes to SPI data register*/
12
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
13
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
14
}
15
16
void VValueTo18BitDAC(double VoltValue)
17
{
18
  unsigned long DACValue = 0;
19
  unsigned char mylowbyte = 0x00;
20
  unsigned char mymidbyte = 0x00;
21
  unsigned char myhighbyte = 0x00;
22
23
  DACValue = abs(VoltValue / DACStepWidth); /* Here is a typeconversion missing?? */
24
  if (VoltValue <= HalfRange) /* Check for Halfrange */
25
  {
26
    DACValue |= 0x020000;   /* to be able to set the MSB */
27
  }
28
  else
29
  {
30
    DACValue &= 0xFDFFFF;    /* or reset the MSB */
31
  }
32
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
33
  DACValue |= 0x100000;  /* The Data Register Address Bit */
34
35
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
36
  DACValue = DACValue >> 8 /* shift the next Byte into position */
37
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
38
  DACValue = DACValue >> 8 /* shift the next Byte into position */
39
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
40
41
  PORTS &= ~0x80;  /* /SS output low */
42
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
43
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
44
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
45
  PORTS |= 0x80;    /* /SS output high */
46
}
47
48
main()
49
{ 
50
  int i = 1;
51
  double myVValue = 0;  
52
  
53
  /* Init for SPI Interface */
54
  PORTS |= 0x80;
55
  DDRS = DDRS | 0xF0; /* outputs */
56
  SP0CR1 = 0x58; /* 0b01011000 */
57
  SP0CR2 = 0; /* Normal mode */
58
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
59
60
  /* Init to the DAC */
61
  PORTS &= ~0x80;  /* /SS output low */
62
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
63
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
64
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
65
  PORTS |= 0x80;    /* /SS output high */
66
67
  while (i>0) /* Endles Data sending for testing only */
68
  { 
69
    VValueTo18BitDAC(myVValue);
70
    myVValue += DACStepWidth;
71
    if (myVValue > 5)
72
      myVValue = 0;
73
  }    
74
}

von J. R. (cia_man)


Lesenswert?

Hey Frank!

Schau dir bitte auch mal mein Programm an ;)
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
unsigned char myVorzeichenFunktion(int zaehlen)
15
{
16
  unsigned char myhighbyte;
17
  int MSB = 0;
18
19
  if(zaehlen < 2,5)
20
  {
21
    MSB = 1;
22
  }
23
  else
24
  {
25
    MSB = 2;
26
  }
27
  
28
  if(MSB = 1)
29
  {
30
     myhighbyte = 0x18;
31
  }
32
  else
33
  {
34
    myhighbyte = 0x10;
35
  }
36
  
37
  return myhighbyte;
38
  
39
}
40
41
42
43
main()
44
{ 
45
  unsigned char myhighbyte;
46
  int i = 1,zaehlen = 0;
47
  
48
  /* Init for SPI Interface */
49
  PORTS |= 0x80;
50
  DDRS = DDRS | 0xF0; /* outputs */
51
  SP0CR1 = 0x58; /* 0b01011000 */
52
  SP0CR2 = 0; /* Normal mode */
53
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
54
55
  /* Init to the DAC */
56
  PORTS &= ~0x80;  /* /SS output low */
57
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
58
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
59
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
60
  PORTS |= 0x80;    /* /SS output high */
61
62
  while (i>0) /* Endles Data sending for testing only */
63
  {
64
  
65
    while (zaehlen <= 5)
66
  {
67
   myVorzeichenFunktion(zaehlen);
68
   
69
   
70
  
71
  
72
     PORTS &= ~0x80;  /* /SS output low */
73
     mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
74
     mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
75
     mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
76
     PORTS |= 0x80;    /* /SS output high */
77
   zaehlen++;
78
    }   
79
  }
80
}


Die Frage ist: Wie gebe ich aus einer Unterfunktion einen Wert zurück?
hier myhighbyte!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

was mir auffällt ist das Du eine absolute Zahl (int) mit einer realen 
(2,5) vergleichst.
Das gibt im besten Fall einen Sprung zwischn 2 und 3 V.

Dann hat dein Wert nur noch 5 Schritte!?

Das Highbyte direkt mit 0x18 zuweisen für zum verlust der bits 16,15 und 
14 des 18 bit wertes.

Alles in allem:
An o.g. punkten müssen wir noch ein wenig feilen. Dann wird das gut!!

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

So müsste es doch jetzt auf dem Oszi zwischen 2,5 und 0 hin- und 
her-springen? Oder?
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
unsigned char myVorzeichenFunktion(double zaehlen)
15
{
16
  unsigned char myhighbyte;
17
  int MSB = 0;
18
19
  if(zaehlen < 2,5)
20
  {
21
    MSB = 1;
22
  }
23
  else
24
  {
25
    MSB = 2;
26
  }
27
  
28
  if(MSB = 1)
29
  {
30
     myhighbyte = 0x18;
31
  }
32
  else
33
  {
34
    myhighbyte = 0x10;
35
  }
36
  
37
  return myhighbyte;
38
  
39
}
40
41
42
43
main()
44
{ 
45
  unsigned char myhighbyte;
46
  int i = 1;
47
  double zaehlen = 0;
48
  
49
  /* Init for SPI Interface */
50
  PORTS |= 0x80;
51
  DDRS = DDRS | 0xF0; /* outputs */
52
  SP0CR1 = 0x58; /* 0b01011000 */
53
  SP0CR2 = 0; /* Normal mode */
54
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
55
56
  /* Init to the DAC */
57
  PORTS &= ~0x80;  /* /SS output low */
58
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
59
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
60
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
61
  PORTS |= 0x80;    /* /SS output high */
62
63
  while (i>0) /* Endles Data sending for testing only */
64
  {
65
  
66
    while (zaehlen <= 5)
67
  {
68
   myVorzeichenFunktion(zaehlen);
69
   
70
   
71
  
72
  
73
     PORTS &= ~0x80;  /* /SS output low */
74
     mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
75
     mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
76
     mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
77
     PORTS |= 0x80;    /* /SS output high */
78
   zaehlen++;
79
    }   
80
  }
81
}


Das will ich erst mal so schaffen ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

probieren und messen ;-)

Ich würde (wie Du) erwarten das er zwischen 0 und 2,5V hüpft.
Das aber ziehmlich schnell, weil DU ja mittlerweile den Takt relativ 
hoch hast ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Ich sehe auf dem Oszi gar nix :(

Gehe jetzt aber estmal was essen ;)

Bis später dann geht's hier weiter :)

von Frank S. (franksanderdo)


Lesenswert?

Nen guten ;-)

von J. R. (cia_man)


Lesenswert?

Wieder da :)

Hast du noch ne Idee warum das mit dem Umschalten bei mir nicht läuft? 
:)

Machen wir das mit dem return richtig?

Danke.

von Frank S. (franksanderdo)


Lesenswert?

oha, das hatte ich gar nicht gesehen :-D

Du weist den wert in main nirgends zu. der geht also ins nirvana ;-)

Änder das mal in:

myhighbyte = myVorzeichenFunktion(zaehlen);

dann sollte da auch was bei raus kommen.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Ich habe jetzt das Programm so angepasst!

- Statt 2,5 habe ich 2.5 geschrieben.

- Im Unterprogramm habe ich myhighbyte in myhighbytetemp geändert

- Zusätzlich deinen Vorschlag... weiß jetzt nicht ob die Stelle, wo er 
steht stimmt?

- Wait ist auch eingebaut.

1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
}
13
14
void delay1ms(void) 
15
{
16
  asm("ldy #2666"); //2666 in Y-Register laden
17
  asm("dbne y,.");  // Decrement, bis Y=0 ist /
18
          //3cyc x 125ns x 2666 = 0,99975ms
19
}
20
21
22
void wait(int duration)
23
{
24
  while(duration--)
25
  delay1ms();
26
}
27
28
29
30
unsigned char myVorzeichenFunktion(double zaehlen)
31
{
32
  unsigned char myhighbytetemp;
33
  int MSB = 0;
34
35
  if(zaehlen < 2.5)
36
  {
37
    MSB = 1;
38
  }
39
  else
40
  {
41
    MSB = 2;
42
  }
43
  
44
  if(MSB = 1)
45
  {
46
     myhighbytetemp = 0x18;
47
  }
48
  else
49
  {
50
    myhighbytetemp = 0x10;
51
  }
52
  
53
  return myhighbytetemp;
54
  
55
}
56
57
58
59
main()
60
{ 
61
  unsigned char myhighbyte;
62
  int i = 1;
63
  double zaehlen = 0;
64
  
65
  /* Init for SPI Interface */
66
  PORTS |= 0x80;
67
  DDRS = DDRS | 0xF0; /* outputs */
68
  SP0CR1 = 0x58; /* 0b01011000 */
69
  SP0CR2 = 0; /* Normal mode */
70
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
71
72
  /* Init to the DAC */
73
  PORTS &= ~0x80;  /* /SS output low */
74
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
75
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
76
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
77
  PORTS |= 0x80;    /* /SS output high */
78
79
  while (i>0) /* Endles Data sending for testing only */
80
  {
81
  
82
    while (zaehlen <= 5)
83
  {
84
  
85
   myhighbyte = myVorzeichenFunktion(zaehlen);
86
   
87
   
88
  
89
  
90
     PORTS &= ~0x80;  /* /SS output low */
91
     mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
92
     mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
93
     mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
94
     PORTS |= 0x80;    /* /SS output high */
95
   zaehlen++;
96
   
97
   wait(1000);
98
    }   
99
  }
100
}

Geht trotzdem nicht :(

von J. R. (cia_man)


Lesenswert?

Nochmal was im main-Programm ausgebessert, damit das Hochzählen nicht 
nach dem 5ten mal endet...

1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
6
{
7
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
8
  
9
  SP0DR = myValue; /* Data goes to SPI data register*/
10
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
11
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
12
  
13
  return 0;
14
}
15
16
void delay1ms(void) 
17
{
18
  asm("ldy #2666"); //2666 in Y-Register laden
19
  asm("dbne y,.");  // Decrement, bis Y=0 ist /
20
          //3cyc x 125ns x 2666 = 0,99975ms
21
}
22
23
24
void wait(int duration)
25
{
26
  while(duration--)
27
  delay1ms();
28
}
29
30
31
32
unsigned char myVorzeichenFunktion(double zaehlen)
33
{
34
  unsigned char myhighbytetemp;
35
  int MSB = 0;
36
37
  if(zaehlen < 2.5)
38
  {
39
    MSB = 1;
40
  }
41
  else
42
  {
43
    MSB = 2;
44
  }
45
  
46
  if(MSB = 1)
47
  {
48
     myhighbytetemp = 0x18;
49
  }
50
  else
51
  {
52
    myhighbytetemp = 0x10;
53
  }
54
  
55
  return myhighbytetemp;
56
  
57
}
58
59
60
61
main()
62
{ 
63
  unsigned char myhighbyte;
64
  int i = 1;
65
  double zaehlen = 0;
66
  
67
  /* Init for SPI Interface */
68
  PORTS |= 0x80;
69
  DDRS = DDRS | 0xF0; /* outputs */
70
  SP0CR1 = 0x58; /* 0b01011000 */
71
  SP0CR2 = 0; /* Normal mode */
72
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
73
74
  /* Init to the DAC */
75
  PORTS &= ~0x80;  /* /SS output low */
76
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
77
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
78
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
79
  PORTS |= 0x80;    /* /SS output high */
80
81
  while (i>0) /* Endles Data sending for testing only */
82
  {
83
  
84
    while (zaehlen <= 5)
85
  {
86
  
87
    myhighbyte = myVorzeichenFunktion(zaehlen);
88
   
89
   
90
  
91
  
92
      PORTS &= ~0x80;  /* /SS output low */
93
      mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
94
      mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
95
      mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
96
      PORTS |= 0x80;    /* /SS output high */
97
    zaehlen++;
98
   
99
    wait(5000);
100
    }   
101
  
102
   zaehlen = 0;
103
  
104
  }
105
}

Oszi = Fehlanzeige???

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

sorry war heute Nachmittag diverse Behörden abklappern.
Ich schau mir das morgen nochmal in Ruhe an.

Im Moment sehe ich auf Anhieb nicht warum der nix zeigt.

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ich habe keine Ahnung was das sein könnte.
Aber ich habe eine Idee wo wir mal Probieren sollten:

zaehlen++;

Ich bin nicht sicher ob der ++ so bei einer realen Zahl genutzt werden 
kann.

Änder das bitte mal in zaehlen = zaehlen + 1.0;

Wie gesagt, ist nur ein Verdacht.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Ich habe das Programm jetzt nochmal in eine for-Schleife abgeändert...

Trotzdem kein Erfolg!
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
#include <mc912d128.h>
5
6
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
7
{
8
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
9
  
10
  SP0DR = myValue; /* Data goes to SPI data register*/
11
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
12
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
13
  
14
  return 0;
15
}
16
17
void delay1ms(void) 
18
{
19
  asm("ldy #2666"); //2666 in Y-Register laden
20
  asm("dbne y,.");  // Decrement, bis Y=0 ist /
21
          //3cyc x 125ns x 2666 = 0,99975ms
22
}
23
24
25
void wait(int duration)
26
{
27
  while(duration--)
28
  delay1ms();
29
}
30
31
32
33
unsigned char myVorzeichenFunktion(double zaehlen)
34
{
35
  unsigned char myhighbytetemp;
36
  int MSB = 0;
37
38
  if(zaehlen < 2.5)
39
  {
40
    MSB = 1;
41
  }
42
  else
43
  {
44
    MSB = 2;
45
  }
46
  
47
  if(MSB = 1)
48
  {
49
     myhighbytetemp = 0x18;
50
  }
51
  else
52
  {
53
    myhighbytetemp = 0x10;
54
  }
55
  
56
  return myhighbytetemp;
57
  
58
}
59
60
61
62
main()
63
{ 
64
  unsigned char myhighbyte;
65
  int i = 1;
66
  double zaehlen = 0;
67
  
68
  /* Init for SPI Interface */
69
  PORTS |= 0x80;
70
  DDRS = DDRS | 0xF0; /* outputs */
71
  SP0CR1 = 0x58; /* 0b01011000 */
72
  SP0CR2 = 0; /* Normal mode */
73
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
74
75
  /* Init to the DAC */
76
  PORTS &= ~0x80;  /* /SS output low */
77
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
78
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
79
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
80
  PORTS |= 0x80;    /* /SS output high */
81
82
  while (i>0) /* Endles Data sending for testing only */
83
  {
84
  
85
    for (zaehlen=0; zaehlen <=5; zaehlen++)
86
  {
87
  
88
    myhighbyte = myVorzeichenFunktion(zaehlen);
89
   
90
   
91
  
92
  
93
      PORTS &= ~0x80;  /* /SS output low */
94
      mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
95
      mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
96
      mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
97
      PORTS |= 0x80;    /* /SS output high */
98
   
99
    wait(5000);
100
    }   
101
  
102
   zaehlen = 0;
103
  
104
  }
105
  
106
}

Hat denn niemand noch ein Ideechen ;=)

Danke

PS: das mit dem +1.0 hat auch nichts gebracht Frank :(

von J. R. (cia_man)


Lesenswert?

Ich hab den Fehler endlich gefunden ...lach...

If(==) 2 x == ;)


Das wars.... lol
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
#include <mc912d128.h>
5
6
unsigned char mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
7
{
8
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
9
  
10
  SP0DR = myValue; /* Data goes to SPI data register*/
11
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
12
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
13
  
14
  return 0;
15
}
16
17
void delay1ms(void) 
18
{
19
  asm("ldy #2666"); //2666 in Y-Register laden
20
  asm("dbne y,.");  // Decrement, bis Y=0 ist /
21
          //3cyc x 125ns x 2666 = 0,99975ms
22
}
23
24
25
void wait(int duration)
26
{
27
  while(duration--)
28
  delay1ms();
29
}
30
31
32
33
unsigned char myVorzeichenFunktion(double zaehlen)
34
{
35
  unsigned char myhighbytetemp;
36
  int MSB = 0;
37
38
  if(zaehlen < 2.5)
39
  {
40
    MSB = 1;
41
  }
42
  else
43
  {
44
    MSB = 2;
45
  }
46
  
47
  if(MSB == 1)
48
  {
49
     myhighbytetemp = 0x18;
50
  }
51
  else
52
  {
53
    myhighbytetemp = 0x10;
54
  }
55
  
56
  return myhighbytetemp;
57
  
58
}
59
60
61
62
main()
63
{ 
64
  unsigned char myhighbyte;
65
  int i = 1;
66
  double zaehlen = 0;
67
  
68
  /* Init for SPI Interface */
69
  PORTS |= 0x80;
70
  DDRS = DDRS | 0xF0; /* outputs */
71
  SP0CR1 = 0x58; /* 0b01011000 */
72
  SP0CR2 = 0; /* Normal mode */
73
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
74
75
  /* Init to the DAC */
76
  PORTS &= ~0x80;  /* /SS output low */
77
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
78
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
79
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
80
  PORTS |= 0x80;    /* /SS output high */
81
82
  while (i>0) /* Endles Data sending for testing only */
83
  {
84
  
85
    for (zaehlen=0; zaehlen <=5; zaehlen++)
86
  {
87
  
88
    myhighbyte = myVorzeichenFunktion(zaehlen);
89
   
90
   
91
  
92
  
93
      PORTS &= ~0x80;  /* /SS output low */
94
      mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
95
      mySPITrans(0x00); /* Analog Value Byte2 24 bit total    */
96
      mySPITrans(0x00); /* Analog Value Byte3 LSB last         */
97
      PORTS |= 0x80;    /* /SS output high */
98
   
99
    wait(5000);
100
    }   
101
  
102
    zaehlen = 0;
103
  
104
  }
105
  
106
}

Danke für die Hilfe an alle! ;)

von J. R. (cia_man)


Lesenswert?

So... nun komme ich zu dem Teil, bei dem ich die 0 - 2,5 V in Bits 
darstellen muss. Ich habe ja mit den 17 Bits 131072 Stufen. Wenn ich 
jetzt ausrechne, wie viel Volt eine Stufe hat, dann komme ich auf das 
Ergebnis: 1,9073*10 ^-5 Volt. Diese Zahl würde mir ja jetzt dafür 
nützen, immer auszurechnen, wie viele Stufen ein bestimmter 
Spannungswert hat.

Bloß wie bekomme ich das ganze dann von den Stufen in Binäre Darstellung 
in C?

Gibt es da einen Befehl der Dezimal vlt in Binär rechnet oder so? Oder 
wie mache ich das??? :)

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Schreibe es bitte meinem hohe Alter zu, ich habe das falsche == einfach 
nicht gesehen.

zu deiner Frage:
Hast Du Dir mal meine Routine angeschaut? da mache ich (fast) genau das 
;-)

ok ich habe mi den ganzen 18 bit gerechnet und danach das MSB bestimmt.
Hier mal etwas erläutert wie es funktionieren soll:

Als erstes habe ich mir 2 Werte als Konstante definiert. HalfRange wird 
später für die Bestimmung des MSB genutzt. DACSTepWidth ist eben die 
Schrittweite.

...
1
const double HalfRange = 2,5;
2
const double DACStepWidth = 5 / 0x03ffff;
...

Der eigentliche Wert (VoltValue) kommt als Reale Zahl an.

...
1
void VValueTo18BitDAC(double VoltValue)
...
Berechnet wird die Anzahl der Schritte einfach mit Spannung / 
Schrittbreite. Dann noch die Nachkommastellen abschneiden.
Was ich nicht sicher weis: Brauchen wir hier eine Typwandlung oder 
passiert die automatisch
...
1
  DACValue = abs(VoltValue / DACStepWidth); /* Here is a typeconversion missing?? */
...
Dann nur noch schauen ob der Wert < 2,5V ist, weil dann muss das MSB 1 
sein, sonst 0
...
1
  if (VoltValue <= HalfRange) /* Check for Halfrange */
2
  {
3
    DACValue |= 0x020000;   /* to be able to set the MSB */
4
  }
5
  else
6
  {
7
    DACValue &= 0xFDFFFF;    /* or reset the MSB */
8
  }
...
Der folgende Teil könnte auch in einer gesonderten Funktion stehen, ich 
war aber zu faul ;-)
Da im DAC Datenregister die 18bit 2 stellen nach links verschoben sind 
mach ich das halt auch.
Danach noch schnell das Addressbit für das Datenregister einstellen
...
1
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
2
  DACValue |= 0x100000;  /* The Data Register Address Bit */
...
Jetzt nur noch das rechte Byte maskieren und merken. Dann schieben wir 
den ganzen Wert 8 bit nach rechts und wieder maskiert gemerkt. Das 
machen wir insgesammt 3 mal.
...
1
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
2
  DACValue = DACValue >> 8 /* shift the next Byte into position */
3
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
4
  DACValue = DACValue >> 8 /* shift the next Byte into position */
5
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
...

hilft Dir das weiter?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Wie meinst du folgendes: Berechnet wird die Anzahl der Schritte einfach 
mit Spannung /Schrittbreite.  ???

Ich verstehe das mit der Schrittbreite nicht? Da verstehe ich die 5 
nicht und überhaupt ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

es gibt 2 Denkansätze:
Deinen: "Ich habe 2 mal 2,5V Darstellungsbereich die durch das MSB 
unterschieden werden"

Meinen "Ich habe einen 5V Darstellungsbereich wo die Deppen das von AD 
das MSB verdreht haben."

Meine Behauptung:
Beide Ansätze funktionieren ;-)

Bei einem Darstellungsbereich von 5V kann ich die Schrittweite bestimmen 
in dem ich 5V / 0x3ffff teile rausfinden. Da kommt übrigens 1,9073*10 
^-5V raus ;-)

Bei deinem Denkansatz.... naja das hast Du ja selber schon gerechnet.

Sobald ich die Schrittweite habe kann ich jeden beliebigen Wert, der 
innerhalb des Darstellungsbereichs liegt, in den entsprechenden 18 bit 
Wert umrechnen.
Ja ich liebe den guten alten Dreisatz ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Ich hätte gedacht das ist ein Kommentar: 5 / 0x03ffff; Sorry ;)

Und nicht geteilt .... darum meine Frage! Jetzt ist es mir klar ;)

Danke!

von J. R. (cia_man)


Lesenswert?

mylowbyte = DACValue & 0xff; /* Low Byte preparation */
  DACValue = DACValue >> 8 /* shift the next Byte into position */
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
  DACValue = DACValue >> 8 /* shift the next Byte into position */
  myhighbyte = DACValue & 0xff; /* High Byte preparation */

Das mit dem maskieren und schieben verstehe ich noch nicht :)

Und den letzten Teil in der letzten While-Schleife...

VValueTo18BitDAC(myVValue);
    myVValue += DACStepWidth;

Kannst du mir das noch einmal etwas genauer erklären? Wäre gut! ;)

Danke.

von J. R. (cia_man)


Lesenswert?

!E C:\Programme\iccv712\EIGENE~1\DACfktFS.c(5): missing identifier
!E C:\Programme\iccv712\EIGENE~1\DACfktFS.c(5): syntax error; found `5' 
expecting `;'
!E C:\Programme\iccv712\EIGENE~1\DACfktFS.c(5): unrecognized declaration
!W C:\Programme\iccv712\EIGENE~1\DACfktFS.c(5):[warning] empty 
declaration
!W C:\Programme\iccv712\EIGENE~1\DACfktFS.c(25):[warning] calling a 
function without prototype may cause runtime errors if the function
does not return int or unsigned int
!E C:\Programme\iccv712\EIGENE~1\DACfktFS.c(39): syntax error; found 
`mymidbyte' expecting `;'
!E C:\Programme\iccv712\EIGENE~1\DACfktFS.c(41): syntax error; found 
`myhighbyte' expecting `;'
!W C:\Programme\iccv712\EIGENE~1\DACfktFS.c(51):[warning] old-style 
function definition for `main'
!W C:\Programme\iccv712\EIGENE~1\DACfktFS.c(76):[warning] missing return 
value
C:\Programme\iccv712\bin\imakew.exe: Error code 1
Done: there are error(s). Exit code: 1. Fri May 06 15:16:26 2011

Diese Fehler kommen raus, wenn ich dein Programm eingebe ;)

von J. R. (cia_man)


Lesenswert?

Nach Behebung einiger Fehler:

C:\Programme\iccv712\bin\imakew -f DACFKTFS.mak
    icc12w -c -e -D__ICC_VERSION=708 -D__BUILD=0 -DMC912Dx128A  -l 
..\EIGENE~1\DACfktFS.c
!E C:\Programme\iccv712\EIGENE~1\DACfktFS.c(5): missing identifier
!E C:\Programme\iccv712\EIGENE~1\DACfktFS.c(5): syntax error; found `5' 
expecting `;'
!E C:\Programme\iccv712\EIGENE~1\DACfktFS.c(5): unrecognized declaration
!W C:\Programme\iccv712\EIGENE~1\DACfktFS.c(5):[warning] empty 
declaration
!W C:\Programme\iccv712\EIGENE~1\DACfktFS.c(25):[warning] calling a 
function without prototype may cause runtime errors if the function
does not return int or unsigned int
!W C:\Programme\iccv712\EIGENE~1\DACfktFS.c(51):[warning] old-style 
function definition for `main'
C:\Programme\iccv712\bin\imakew.exe: Error code 1
Done: there are error(s). Exit code: 1. Fri May 06 15:35:51 2011

:(

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

klar kann ich ;-)
Ähh also... hoffentlich kann ich :-D

Ich fange aber eine Zeile drüber an:
DACValue ist ja ein 32bit breiter integer ohne Vorzeichen.
In dem Dingen steht unser Wert für den DAC, das einzige Problem das wir 
haben:
wir brauchen nur 24 bit von den 32. die am liebsten auf 3 byte 
aufgeteilt.

Um es noch schlimmer zu machen steht unser Wert in den 24 bit um 2 bit 
nach links verschoben. Genau das mache ich mit der folgenden Zeile
1
...
2
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
3
...

Im linken byte der 24 bit steht im linken nibble das wir schreiben 
wollen in das Datenregister. das schreiben wir mit dieser Zeile:
1
...  
2
  DACValue |= 0x100000;  /* The Data Register Address Bit */
3
...

So jetzt zu deiner eigentlichen Frage. Es gibt evtl. elegantere Wege ;-)
ich will hier das rechte byte des 32bit wertes in unsere 
Transfervariable schreiben.
Meckert dein Compiler hier? dann müssen wir Typen Wandeln ;-)
1
...  
2
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
3
...
das maskieren mit 0xff ist eigentlich nur aus Angst (Hosenträger zum 
Gürtel)
Danach muss ich irgendwie an das 2. byte im 32bit wert kommen.
Am einfachsten schiebe ich also den ganzen 32bit wert um 8 nach rechts.
Das dann in unsere mittlere Transfervariable gesichert und nach mal das 
ganze für die 3. Transfervariable.
Schon haben wir die 24bit so wie benötigt zum verschicken vorbereitet 
;-)
1
...  
2
  DACValue = DACValue >> 8 /* shift the next Byte into position */
3
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
4
  DACValue = DACValue >> 8 /* shift the next Byte into position */
5
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
6
...

Jetzt etwas klarer?
Was sagt den dein Compiler zu meinem Entwurf?

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

kannst Du mir sagen welches Zeile 5 ist?

Danke

von Frank S. (franksanderdo)


Lesenswert?

Ich Rindvieh!!

const double HalfRange = 2,5;

muss sein


const double HalfRange = 2.5;

über den Punkt sind wir doch schon mal gestolpert oder?

von Frank S. (franksanderdo)


Lesenswert?

Kann es diese Zeile sein?

const double DACStepWidth = 5 / 0x03ffff;

dann kommt er nicht damit zurecht das ich in einer Konstatendefinition 
rechnen will. Versuch es mal mit

const double DACStepWidth = (5 / 0x03ffff);

welche Zeile ist Zeile 25? Welche ist Zeile 51?

Ich Frage so dumm weil ich das hier nicht 100%ig zuordnen kann.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Fehler sind weg... mit dem . ;) aber mal sehen was der Oszi zu sagt ;)

von J. R. (cia_man)


Lesenswert?

Oszi sagt 0 V :(

Aber soweit so gut ;)

Was bedeutet das im Programm noch:

VValueTo18BitDAC(myVValue);
    myVValue += DACStepWidth;

Das hast du vergessen zu erklären ;)

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

da fällt mir ein ich habe vergessen die 2 Zeilen zu erläutern:
die 1. ruft die Wandelfunktion auf mit einem Wert der 0V <= myVValue <= 
5V sein soll.
die 2. Zeile addiert zu myVValue eine Schrittweite ;-)
Sollte alse einen sauberen Sägezahn ergeben ;-)
1
...
2
    VValueTo18BitDAC(myVValue);
3
    myVValue += DACStepWidth;
4
...

von J. R. (cia_man)


Lesenswert?

Der kommt nicht :(

von Frank S. (franksanderdo)


Lesenswert?

oha!!!

Jochen, der Takt.. auf was haben wir den Takt stehen?
Bauen wir gerade wieder eine 3 Minuten schleife?

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ich kann mir im Moment 2 mögliche Fehler vorstellen:

1. Takt zu langsam dadurch laaaaangsamer Sägezanh. Schließlich addieren 
wir immer nur 1,9irgendwas * 10^-5 V

2. ich habe mich in meiner Schieberei verhaspelt. Ich versuch mal die 
Funktion auf mögliche Fehler zu untersuchen ;-)

von J. R. (cia_man)


Lesenswert?

Takt ist 1 MHz... das müsste doch reichen oder??? ;)

von J. R. (cia_man)


Lesenswert?

So WE ruft ;) Dann geht es am Montag weiter.... ich kann jetzt leider 
die nächsten beiden Tage nichts ausprobieren, da ich das ganze Zeugs 
nicht bei mir Daheim habe...

Danke!

Vlt fällt dir ja der Fehler noch auf bis Montag ;)

Ich wünsche dir jedenfalls schon einmal ein schönes WE!!!

Gruß

Jochen

von Frank S. (franksanderdo)


Lesenswert?

Also da habe ich einigen Unsinn drin stehen :-(
Tausch bitte mal die VValueTo18BitDAC Funktion gegen die angehängte 
Version
1
...
2
void VValueTo18BitDAC(double VoltValue)
3
{
4
  unsigned long DACValue = 0;
5
  unsigned char mylowbyte = 0x00;
6
  unsigned char mymidbyte = 0x00;
7
  unsigned char myhighbyte = 0x00;
8
9
  DACValue = (int)(VoltValue / DACStepWidth); /* typeconversion added */
10
11
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
12
13
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
14
  DACValue = DACValue >> 8 /* shift the next Byte into position */
15
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
16
  DACValue = DACValue >> 8 /* shift the next Byte into position */
17
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
18
19
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
20
21
  if (VoltValue <= HalfRange) /* Check for Halfrange */
22
  {
23
    myhighbyte |= 0x08;   /* to be able to set the MSB */
24
  }
25
26
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
27
28
  PORTS &= ~0x80;  /* /SS output low */
29
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
30
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
31
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
32
  PORTS |= 0x80;    /* /SS output high */
33
}
34
...

von J. R. (cia_man)


Lesenswert?

Ich habe den Text ausgetauscht... leider immer noch kein Signal auf dem 
Oszi zu sehen... jedenfalls kein Sägezahn ;)

Hast du übers WE noch einen Geistesblitz gehabt?

Gruß & THX

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

was kommt den raus 0V oder 2,5?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

0V! Wieder einmal :( ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

kannst Du über printf Werte zurück zum Rechner ausgeben?

Das täte jetzt das suchen vereinfachen ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Kann es sein, dass hier der Wurm drinnen ist?
1
DACValue = (int)(VoltValue / DACStepWidth); /* typeconversion added */

Weil wir ja int mit unsigned long = setzen!

Gruß

von J. R. (cia_man)


Lesenswert?

Hier habe ich eine Funktion die festen Text ausgeben kann....
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7
8
9
  void sci0_init(void){
10
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
11
    SC0BDL=26; // MCLK/(16*BaudRate)
12
    SC0CR1=0;
13
    SC0CR2=0x0C; //TE+RE enable
14
}
15
16
void sci0_putc(char data){
17
   while ((SC0SR1 & TDRE) == 0){};
18
   SC0DRL = data;
19
}
20
21
void sci0_puts(char* data){
22
   while (*data)
23
       sci0_putc(*data++);
24
}
25
26
void main(void){
27
  sci0_init();
28
  sci0_puts("\n\nHallo ich bin ein String");
29
  sci0_putc(' ');sci0_putc('1');sci0_putc(' ');sci0_putc('2');sci0_putc(' ');sci0_putc('3');
30
31
  while(1);
32
}

Ich müsste aber auch noch eine haben, die eine Variable ausgeben kann... 
da muss ich aber erst suchen...

Du siehst aber schon hier, der Aufwand ist ziemlich groß an Code, der 
für ein einfaches printf nötig ist ;) bei meinem µC!

Gruß

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

das ist gelinde gesagt M...!

Ich würde gerne sehen welche Werte bei unseren Berechnungen rauskommen.
Ich mach mir Sorgen das ich mit den Type Castings nen Bock geschossen 
habe ;-)

Irgend eine Idee wie wir da an eine Rückmeldung vom uC kommen können?
Ich vermute das wir auch keinen online debugger haben?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

1
//Zeichen ausgeben
2
3
void sci0_putc(char data){
4
   while ((SC0SR1 & TDRE) == 0){};
5
   SC0DRL = data;
6
}
7
8
void sci0_puts(char* data){
9
   while (*data)
10
       sci0_putc(*data++);
11
}
12
13
14
15
//Eingabe
16
sci0_puts("\nBitte Kommando eingeben (muss Doppelpunkt enthalten):");
17
sci0_gets(command);
18
19
20
//Kommando finden hier anhand des ":"
21
while (commandsub != ':'){
22
23
commandsub = command[y];
24
y++;
25
26
}
27
28
29
//Kommando zur Kontrolle nochmals ausgeben
30
sci0_puts("\n\nGefundenes Kommando: ");
31
32
33
x=y-2;
34
35
while(x>=0){
36
37
commandid[z] = command[z];
38
x--;
39
z++;
40
41
}
42
43
sci0_puts(commandid); //Kommandoausgabe

Das würde schon ehr helfen oder? ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

so da werden wir wohl ein kleines Testprogramm stricken müssen um eine 
Textausgabe hin zu bekommen.
Mein Problem is jetzt das ich nicht sicher bin wie arrays definiert 
werden.
Das musst Du bitte mal nachschauen und auch ob es eine Bibliothek mit 
einem printf gibt. Das sollte eigentlich in deinen Handbüchern zum 
compiler drin stehen ;-)

Weil wenn, dann können wir so etwas bauen:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7
8
const double HalfRange = 2.5;
9
const double DACStepWidth = 5 / 0x03ffff;
10
11
12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18
19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23
24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28
29
void main(void){
30
  char mycharacterarray[128] /* This should be a 128 characters long array, how to do this properly? */
31
32
  sci0_init();
33
  mycharacterarray = printf("\n Here kommt die 1. Zahl: %f",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  mycharacterarray = printf("\n Here kommt die 2. Zahl: %f",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37
38
  while(1);
39
}

DAS IST SO SICHER NICHT LAUFFÄHIG!!
Jetzt brauche ich deine Hilfe. Schau bitte das DU das array und den 
printf sauber bekommst. Evtl. gibt es auch einen Ersatz für den printf 
;-)

Grüße
Frank

von APW (Gast)


Lesenswert?

J. R. schrieb:
> Kann es sein, dass hier der Wurm drinnen ist?
> DACValue = (int)(VoltValue / DACStepWidth); /* typeconversion added */

DACValue = (VoltValue / DACStepWidth);

Der Compiler macht die entsprechenden Konvertierungen.
[unsigned long] = ([Float]/[Float]) bzw
[  signed long] = ([Float]/[Float])

Sieh mal ins List-File, da wird das auf einen Blick klar.

Wenn du keine Umgebung hast, online zu debuggen,
dann schau wenigstens ab und zu ins list-File rein, was der
Compiler aus den C-Konstruktionen macht.

Du brauchst die 20-fache Zeit (gerade als Anfänger) wenn du keine
Möglichkeit hast, ein Programm zu debuggen, und am besten
mit Single-Stepping durchzutesten. Die Erfahrungen, die man dabei macht,
sind unbezahlbar.

Das mit
(int)..
ist hier total falsch. Das kopiert letztendlich einfach einen
(normalerweise 16Bit-) Teil aus dem Floatergebnis, konvertiert/erweitert
ihn dann erst (automatisch) auf den Typ von DACValue.

von APW (Gast)


Lesenswert?

Vergesst meinen letztes Posting. Ich glaube das war total kacke.
Aber das kommt davon, wenn man ungetestet Quellcode absondert.

von Frank S. (franksanderdo)


Lesenswert?

@APW

Du bist irgendwie immer da wenn ich nimmer weiter weis!!
Dank Dir, das hilft mir schon ein Stück weiter!

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

@APW

nene so ganz falsch liegst Du nicht.
Das mit dem ungetestet tut mir ja auch leid, ich hab halt nix hier zum 
testen ;-)

@ Jochen
Da klauen wir mal die Idee vom APW und ändern die Zeile in:

DACValue = (VoltValue / DACStepWidth);

also das (int) raus. Ist wie ihr beide festgestellt habt aus mehreren 
Gründen Unsinn :-(

Ja ich werde doch langsam alt!


Was macht unser printf Testprogramm?

Grüße
Frank

von APW (Gast)


Lesenswert?

Das Problem ist, dass ich jetzt einige Jahre nicht mehr in C
programmiert habe. Da ist einiges angerostet.

Vielleicht hole ich am WE mal wieder mein Zeug raus.
Bis auf den 18Bit DAC hab ich eigentlich alles hier.

von Frank S. (franksanderdo)


Lesenswert?

@APW

hehe, so ähnlich habe ich auch gedacht und habe mir die Woche was zum 
Basteln bestellt ;-)

Wenn ich Anfang Juni für ein par Tage in D bin hoffe ich alles zusammen 
zu haben das ich das Zeugs mitnehmen kann. Wird spannend nach fast 20 
Jahren mal wieder zu basteln ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Sorry war gerade anderweitig beschäftigt!

Diese Änderung hat nichts gebracht:

DACValue = (VoltValue / DACStepWidth);

leider :(

Kannst du mir nochmal sagen was ich jetzt genau nachschauen soll? Das 
mit dem printf meine ich!

Danke

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

so nachdem ich mich durch diverse Meetings gequält habe gehen wir wieder 
auf was sinnvolles über ;-)

printf ist eigentlich ein standard C Befehl mit dem texte formatiert in 
ein character array geschrieben werden können.
Ich will jetzt nicht lügen, aber ich meine das printf in der Bibliothek 
"stdio" definiert ist.
Wenn Du da die Definition findest täte mir das schon helfen.

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ich war dann gestern Abend ein bischen fleißig und habe mal nachgelesen 
was ich finden konnte. Dem zufolge sollte unser Testprogramm für die 
Ausgabe so aussehen:

Was hängt an SCI0 um den Text anzuzeigen?
Kannst DU das bitte mal testen ob wir so eine Anzeige bauen können?
Damit hätten wir dann wenigsten ein wenig debugging zur Verfügung.
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7
8
const double HalfRange = 2.5;
9
const double DACStepWidth = 5 / 0x03ffff;
10
11
12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18
19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23
24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28
29
void main(void){
30
  char mycharacterarray[128]; /* This is a 128 characters long array */
31
32
  sci0_init();
33
  sprintf(mycharacterarray,"\n Here kommt die 1. Zahl: %f",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  sprintf(mycharacterarray,"\n Here kommt die 2. Zahl: %f",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37
38
  while(1);
39
}

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

1
            
2
Here kommt die 1. Zahl: 2.5                                           
3
Here kommt die 2. Zahl: 0

Bis auf Here passt es :) ;)

Gruß

von J. R. (cia_man)


Lesenswert?

Wie gehen wir jetzt weiter vor? Was soll ich bei dem anderen Programm 
ausgeben? ;)

Danke

von Frank S. (franksanderdo)


Lesenswert?

COOOOOL!!!

Ok das mit dem Here ist meinem Job geschuldet.
Programmschnipsel basteln und gleichzeitig hier mit den Jungens englisch 
reden gibt dann so ein Misch Masch :-D

So die 2. Zahl schockiert mich.
Da hätte ich was anderes erwartet ;-)

Ich denke damit haben wir den Fehler schon eingefangen.
Ändere bitte mal in unserem Ausgabe Testprogramm:

const double DACStepWidth = 5 / 0x03ffff;

zu

const double DACStepWidth = 0.00001907;

und noch mal rennen lassen ;-)

von J. R. (cia_man)


Lesenswert?

So....

Hier jetzt die Ausgabe:
1
                                                                                      
2
Hier kommt die 1. Zahl: 2.5                               
3
Hier kommt die 2. Zahl: 0.000019

2. Zahl? Zu kurz! ;)

Here ist zu Hier ausgebessert ;)

Gruß

von J. R. (cia_man)


Lesenswert?

1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7
8
const double HalfRange = 2.5;
9
const double DACStepWidth = 0.00001907;
10
11
12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18
19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23
24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28
29
void main(void){
30
  char mycharacterarray[128]; /* This is a 128 characters long array */
31
32
  sci0_init();
33
  sprintf(mycharacterarray,"\n Hier kommt die 1. Zahl: %lf",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %lf",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37
38
  while(1);
39
}

Ich habe %f zu %lf noch ausgebessert ;) Aber an der Ausgabe ändert sich 
nichts :(

Leider :(

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

das ist um klassen besser als das Ergebnis vorher!!

So ich grübel mal ne runde warum die Zahl zu kurz wird!
Auch wie wir das Problem umgehen können muss ich noch rausfinden ;-)

Du baust bitte die geänderte const Zeile in das DAC Programm und machst 
auf verdacht mal einen Test.

Dann schauen wir weiter

Grüße
Frank

von APW (Gast)


Lesenswert?

Bei dem const müsste es event. so gemacht werden:
1
const double DACStepWidth = 5.0 / 0x03ffff;
sonst rechnet der Compiler auf der rechten Seite erst ganzzahlig,
wobei 0 rauskommt und wandelt dann erst in float/double um.
5.0 zwingt die rechte Seite als double zu rechnen


und die Ausgabe:
1
sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.10f",DACStepWidth);
oder so ähnlich

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hallo!

Tataaaaa! Wir haben den Sägezahn!!!! Ich werde nun einmal die Taktrate 
erhöhen. ;)

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Na das ist doch mal ein Wort ;-)

und APW war mal wieder schneller als ich mit der Lösung.
APW ich werde langsam ein wenig neidisch ;-)

Jochen, kannst Du bitte mal APWs Lösungsvorschlag für die const Zeile 
testen?

Grüße Frank
P.S. APW, Jochen, danke für die Geduld die ihr habt. Hab ja nu doch 
einige Böcke geschossen in den letzten Tagen ;-)

von J. R. (cia_man)


Lesenswert?

Hey!
1
#include <stdio.h>
2
#include <mc912d128.h>
3
4
5
const double HalfRange = 2.5;
6
const double DACStepWidth = 5.0 / 0x03ffff;
7
8
9
10
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
11
{
12
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
13
  
14
  SP0DR = myValue; /* Data goes to SPI data register*/
15
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
16
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
17
}
18
19
void VValueTo18BitDAC(double VoltValue)
20
{
21
  unsigned long DACValue = 0;
22
  unsigned char mylowbyte = 0x00;
23
  unsigned char mymidbyte = 0x00;
24
  unsigned char myhighbyte = 0x00;
25
26
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
27
28
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
29
30
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
31
  DACValue = DACValue >> 8; /* shift the next Byte into position */
32
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
33
  DACValue = DACValue >> 8; /* shift the next Byte into position */
34
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
35
36
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
37
38
  if (VoltValue <= HalfRange) /* Check for Halfrange */
39
  {
40
    myhighbyte |= 0x08;   /* to be able to set the MSB */
41
  }
42
43
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
44
45
  PORTS &= ~0x80;  /* /SS output low */
46
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
47
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
48
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
49
  PORTS |= 0x80;    /* /SS output high */
50
}
51
52
main()
53
{ 
54
  int i = 1;
55
  double myVValue = 0;  
56
  
57
  /* Init for SPI Interface */
58
  PORTS |= 0x80;
59
  DDRS = DDRS | 0xF0; /* outputs */
60
  SP0CR1 = 0x58; /* 0b01011000 */
61
  SP0CR2 = 0; /* Normal mode */
62
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
63
64
  /* Init to the DAC */
65
  PORTS &= ~0x80;  /* /SS output low */
66
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
67
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
68
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
69
  PORTS |= 0x80;    /* /SS output high */
70
71
  while (i>0) /* Endles Data sending for testing only */
72
  { 
73
    VValueTo18BitDAC(myVValue);
74
    myVValue += DACStepWidth;
75
    if (myVValue > 5)
76
      myVValue = 0;
77
  }
78
  
79
  return 0;    
80
}

Das Programm sieht nun folgendermaßen aus. Es läuft schon! Also Danke 
APW ;)

Und Frank was heißt da Danke für die Geduld... ich habe bisher Danke zu 
sagen ;)

Nun werde ich noch den Takt erhöhen :)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

kannst DU noch mal die von APW kommende Ausgabezeile testen?

sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: 
%2.10f",DACStepWidth);

nur das wir sicher gehen das wir keine "genauigkeit" verlieren ;-)

Tja und danach musste uns sagen was wir als nächstes machen. Weil dann 
rennt der DAC wie gewünscht ;-)

Grüße
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Ich habe nun den SPI-Clock auf 4 Mhz erhöht.... jedoch ist die Ausgabe 
mir dann etwas spanisch^^

Wisst ihr woran das liegt?
Das: sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl:
%2.10f",DACStepWidth); werde ich anschließend einmal testen ;)

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Du meinst weil der nicht schneller geworden ist?
Ich bin mir nicht sicher welche Takt der Prozessor selber hat, aber das 
sind jetzt einige Schritte wo er durchrechnen muss um durch zu kommen.
Kann es sein das der SPI mit 4Mhz nicht mehr das begrenzende Element 
ist?

Ist jetzt nur mal ein Verdacht.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> Du meinst weil der nicht schneller geworden ist?
> Ich bin mir nicht sicher welche Takt der Prozessor selber hat, aber das
> sind jetzt einige Schritte wo er durchrechnen muss um durch zu kommen.
> Kann es sein das der SPI mit 4Mhz nicht mehr das begrenzende Element
> ist?
>
> Ist jetzt nur mal ein Verdacht.
>
> Grüße
> Frank

Du meinst also, dass es der DAC ist? Weil der µC kann es ja net mit 8 
Mhz sein ;) oder?? :)

von J. R. (cia_man)


Lesenswert?

1
Hier kommt die 1. Zahl: 2.5                                                  
2
Hier kommt die 2. Zahl: 0.000019

Programm dazu:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7
8
const double HalfRange = 2.5;
9
const double DACStepWidth = 5.0 / 0x03ffff;
10
11
12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18
19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23
24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28
29
void main(void){
30
  char mycharacterarray[128]; /* This is a 128 characters long array */
31
32
  sci0_init();
33
  sprintf(mycharacterarray,"\n Hier kommt die 1. Zahl: %lf",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %lf",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37
38
  while(1);
39
}

nicht, dass wir wieder aneinander vorbei reden ;) :)

Danke!

Scheint aber zu stimmen was APW da macht!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

8Mhz hat der HC12?
Dann haben wir seine Grenze erreicht.

Ich stelle mal ein par Behauptungen auf:
der HC12 braucht 2 Taktzyklen / Befehl (das erscheint mir optimistisch)
damit kann der HC12 effektiv nur 4 Mhz umsetzen.
Jetzt brauchen wir aber schon 3 Befehle um nur 1 byte von 3 an den DAC 
zu schicken.
Gibt (wieder optimistisch) 9 Befehle. Dann boste schon bei ca. 0,5 Mhz 
oder 500kHz.

Das bedeutet:
Ohne das wir auch nur einen Wert berechnet haben und ohne die reine 
Übertragungszeit des SPI braucht der Prozessor schon 0,5s für einen 
Zyklus.

Wenn Du jetzt noch das ganze grechne da drauf packst und die 
Übertragungszeiten....


Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Hmmm okay! Das stimmt. Dann muss ich mal sehen, ob das für unsere Zwecke 
reicht... also brauche ich faktisch für jeden Wert an den DAC 0,5 s 
mindestens?!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ne bei dem Test der Ausgabe meinte ich das wir mal
1
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.10f",DACStepWidth);

testen sollten. nur um zu sehen ob da was vom Wert abgeschnitten wird

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

nein nicht für jeden Wert. Das sind dann die ca 262000 werte welche 
Dufür einen Sägezahnzyklus brauchst

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Aber du hast doch gesagt die 9 Befehle brauchen schon 0,5 s ??? Oder?? 
Wobei??? Dann kann des Oszi Bild nicht stimmen ^^ Aber alle Werte des 
Sägezahns brauchen auch mehr wie 0,5 s! :)

von Frank S. (franksanderdo)


Lesenswert?

Du kannst die Maximale Rate mit dem Oscar genau ausmessen.
Änder unser Sägezahn Programm dahingehend, das Du zwischen 0 und 5V 
springst.
Damit bekommst DU am Oscar die Maximal mögliche Änderungsfrequnz 
dargestellt ;-)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ok dann die Erkläsrung noch mal anders und ein wenig genauer:

Wir führen (dieses mal habe ich nachgezählt) 22 C Zeilen aus um einen 
Wert zu schreiben.

Wenn wir behaupten das jede Zeile 2 Taktzyklen im HC12 sind (viel zu 
optimistisch) dann sind wir bei einer Bearbeitungszeit von 8Mhz / 44 
Zyklen = 0,18 Mhz
Das sind also ca. 0,000005 s pro Wert.

Wir verschicken pro Sägezahnzyklus 262143. Das ergibt dann schon 1,5 
sec.

Das deckt sich nicht mit deinem Bild, weil meine angenommen 2 Taktzyklen 
VIEEEEEEL zu optimistisch sind.

Mach ruhig mal den o.g. Versuch mit den Wertsprüngen zwischen 0 und 5 
Volt, damit wissen wir dann genau was bestenfalls möglich ist ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

1
Hier kommt die 1. Zahl: 2.5                                              Hier kommt die 2. Zahl: 0.000019

Dies gibt das Programm aus:
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7
8
const double HalfRange = 2.5;
9
const double DACStepWidth = 5.0 / 0x03ffff;
10
11
12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18
19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23
24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28
29
void main(void){
30
  char mycharacterarray[128]; /* This is a 128 characters long array */
31
32
  sci0_init();
33
  sprintf(mycharacterarray,"\n Hier kommt die 1. Zahl: %lf",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.10f",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37
38
  while(1);
39
}


Das Ergebnis ist aber zu oben identisch.... Bringt es also dann jetzt 
den von dir gewünschten Erfolg?

Gruß

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

das bestätigt ein wenig meine Sorge.
Ich werde da noch mal lesen müssen ;-)

Generell haben wir aber jetzt ein funktionierendes Programm.
Die "Ungenauigkeit" werden ich noch mal genauer studieren, soll uns aber 
nicht davon abhalten das wir erst mal weiter basteln.

Kannst Du den Test zur maximal darstellbaren Frequenz durchführen?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Nach dem Mittag-Essen ;)

Bis dann

Cu

von APW (Gast)


Lesenswert?

1) SPI läuft auf max Frequenz = F_Bus/2 = 4MHz
   3 Bytes pro Wertausgabe an den DAC zu übertragen:
   -> 24Bit * 250ns => 6us
   Wenn man den vollen Sägezahn mit 18Bits macht braucht man
   also für die SPI-Transfers alleine ca. 1,6s

   Sollte also momentan nicht der limitierende Faktor sein.

2) Das hier ist der limitierende Faktor:

   DACValue = (VoltValue / DACStepWidth);

   Pro Ausgabe eine double-Division sowie eine Double zu
   Longint Konvertierung. Wenn man auf Speed optimiert, muss man
   Fliesspunktrechnungen vermeiden. Ganz hardcoremässig event.
   sogar auf Assembler umsetzen.

3) Beim HC12 kann man nicht pauschal von 2 Clks/Maschinenbefehl 
ausgehen.
   Es gibt Befehle, die dauern 1 Clk, andere dauern so 12 Clks.
   Ich schätze den Durchschnitt so auf 3 Clks/Befehl
   Ausserdem wisst ihr ja nicht, was der C-Compiler aus euren
   Konstruktionen macht.

4) Kannst du mal sowas probieren:
1
...
2
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.10f",DACStepWidth);
3
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.10f",10000*DACStepWidth);
4
5
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.12f",DACStepWidth);
6
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %12.12f",DACStepWidth);
7
8
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %e",DACStepWidth);
9
...

Einfach mal ein bischen experimentieren. Vielleicht sinds 
Rundungseffekte

von Frank S. (franksanderdo)


Lesenswert?

APW du rettest meinen Tag!!

den %e habe ich gesucht und nicht gefunden!!
Ich gehe derzeit davon aus das wir einem Rundungsfehler zum Opfer 
fallen.

Da ich aber gerade an eben der Vermeidung der double Berechnungen 
arbeite (jep mir ist bewusst das die Dinger richtig Zeit kosten) werde 
ich auf dem Weg auch den Rundungsfehler los.

Ich stimme Dir übrigens zu was die 2 Zyklen betrifft. Habe derweil mal 
ein wenig im Netz gestöbert. Da sprach sogar jemand von 4 Zyklen im 
Mittel (bei Assembler code).
Ob ob Jochen aber wirklich viel schneller werden muss wird er uns noch 
verraten müssen ;-)

Dank Dir erst mal.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Geschwindigkeit ist für mich ziemlich wichtig! Aber ich werde als erstes 
jetzt mal den Test vom Frank programmieren ;)

Und mal messen wie schnell wir momentan sind!

von J. R. (cia_man)


Lesenswert?

Hier die Messungen. Als Takt habe ich 4,0 Mhz am SPI.

Das Programm:
1
 while (i>0) /* Endles Data sending for testing only */
2
  { 
3
    VValueTo18BitDAC(myVValue);
4
    myVValue = 5;
5
    VValueTo18BitDAC(myVValue);
6
      myVValue = 0;
7
  }

Um Missverständnisse zu beseitigen ;)

:)

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Jetzt ^^

Sorry... die Arbeit ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

lese ich das richtig?
Von der fallenden Flanke zur fallenden Flanke ca. 450us?

Kannst Du mir sagen wie schnell Du es brauchst?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Ist das jetzt schnell? Also ihr habt ja da mehr Erfahrung wie ich... was 
µC betrifft! ;)

von J. R. (cia_man)


Lesenswert?

Für meine Zwecke reicht es :) **freu**

von J. R. (cia_man)


Lesenswert?

Nächste Schritte sollen dann sein, mehrere DACs an einem µC zu 
betreiben. SPI-BUS soll dazu verwendet werden. Hardware habe ich aber 
noch nicht :)

Die Frage die ich deswegen habe ist, was passiert wenn der µC sein 
Signal vom DAC abzieht... das heißt hält der DAC dann seinen Wert? Soll 
nämlich so werden, damit mehrere DACs gleichzeitig laufen können.

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

leider hast Du die Frage nicht ganz beantwortet ;-)
Wie schnell (je DAC) brauchst Du es denn??

Über wie viele DACs reden wir?

Ich fange gerade an mir Sorgen zu machen ;-)

Grüße
Frank

von APW (Gast)


Lesenswert?

J. R. schrieb:
> Die Frage die ich deswegen habe ist, was passiert wenn der µC sein
> Signal vom DAC abzieht... das heißt hält der DAC dann seinen Wert?

Hä??

Ich hab keinerlei Durchblick, was du genau vorhast.
Wir brauchen ja nicht die DAC Wandlerrate von 1000/s auf 20000/s
hochtreiben, wenn 10/s ausreichen.

Also
-Was soll das Ganze eigentlich
-Wo kommen welche Daten in welchem Format / bzw. Protokoll
 wie schnell rein
-Was sind die Ausgabekanäle
-Was muss der uC wie verarbeiten
-Wie schnell soll das laufen
-Reichen 30 DAC Wandlungen/s oder sollens 10000/s sein
-Sollen die DACs gleichzeitig ihre Analogausgänge updaten ?
-Wenn du mehrere DACs bedienen musst, kannst du dir es überhaupt
 noch leisten, die ganze Ausgabe über zu warten ?
 (während z.B. serielle Daten reinkommen)

.....usw...

Langsam gehts event. mit Interruptprogrammierung los.
Das kann noch viel lustiger werden als bisher.

Wenn das auf die 10000 Beiträge zustrebt,
bekomme ich echte Probleme mit meinem Browser.

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW,

wie viele Beiträge haben wir denn bis jetzt?
evtl. sollten wir dann demnächst einen neuen Fred aufmachen.
Die eigentliche Aufgabe (siehe Überschrift) haben wir ja gelöst ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Ich kann darüber auch noch keine genaueren Angaben machen... ist bei mir 
auch alles noch im Aufbau und muss ich erst einmal selber abklären.... 
;)

Aber nochmal zu dem was ich meinte... wenn ich jetzt über den BUS sagen 
wir 4 DACs ansteuere... dann kann ich ja immer nur eine mit den 
entsprechenden Infos versorgen... wegen dem BUS... und wie ist das dann 
mit den übrigen DACs die nicht SS mäßig gerade angesprochen werden? 
Schalten die sich dann einfach auf 0 V oder halten die ihren vorher 
übermittelten Wert? Das meine ich! Klar? :) ;)

Thx!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

heute wird die Session etwas holperig, weil wir hier auf der Baustelle 
versuchen einen 35KV Traffo scharf zu schalten.
Genauer der Kunde versucht das ;-)

Zu deiner Frage:
der DAC hält die Spannung am Ausgang.
Das kannst Du auch schon an unseren Sägezahnversuchen sehen. Weil wir ja 
immer nach dem Übertragen den SS wegnehmen ;-)

So ich hol mir schnell nen Kaffee und dann kommt die Antwort zu den 
Geschwindigkeiten ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

35 kV nicht schlecht ;) Bin zwar kein Energietechniker aber hört sich 
doch beachtlich an... was fließen da für Ströme? ;)

Gruß

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

jetzt mal zu den Geschwindigkeiten oder "sample rates".

Es gibt da kein schnell oder langsam. Es gibt nur eine Anforderung die 
mit der gewählten Plattform erfüllt werden kann oder eben nicht.

Einfaches Beispiel:
wenn Du einen 2 Mhz Rechteck mit deiner gewählten Plattform darstellen 
willst, wirst du feststellen das geht nicht. egal wie Du es 
programmierst. Da ist dann der SPI Takt = 4Mhz zusammen mit dem 24 bit 
Kontrollwort eine Physikalische Grenze ;-)

Um also sagen zu können ob und wie deine Idee umsetzbar ist, müssen wir 
erst mal wissen welche Voraussetzungen wir erfüllen müssen.

Wir kennen aber schon ein par Werte die wir schaffen können.

1. Die reine Übertragung eines Wertes dauert 6us (dank an APW)
2. Derzeit verbraten wir durch Rechnereien ca. 220us pro Wert.

Diese 220us können (und müssen??) wir optimieren, nur dafür müssen wir 
wissen auf was wir optimieren. Da kommen dann wieder die schon mal 
gestellten Fragen zum tragen.

Ein einfaches Beispiel:
Ich glaube das wir locker 100us sparen können wenn der "Bediener" die 
Spannung nicht in V sonder in uV angibt.
Dadurch können wir die doubles weg optimieren und die kosten richtig 
Zeit!!

Wie APW schon sagte: Wenn Du nur eine Wertänderung alle 0,5s brauchst 
dann brauchen wir gar nix optimieren und sind (fast) fertig ;-)

Alles klar soweit?

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ich hoffe heute fließen keine Ströme :-D
Aber wenn es mal rennt sind es einige Megawatt die da verbrannt werden 
;-)
Das alles nur um irgendwelche dusseligen Steine durch die Gegend zu 
kutschieren.

Grüße
Frank

von APW (Gast)


Lesenswert?

Solange man nicht weiß, wieviele Wandlungen/s er braucht, ist
optimieren überflüssige Arbeit. Vielleicht braucht er ja nur 50/s.

Ich denke Jochen hat 2 Möglichkeiten, mehrere DAC an den uC anzukoppeln:

Seriell:
So etwa, wie in Figure 47 und Figure 4 des AD5781 Datasheets.
Ist dort auch erklärt wiesowas funktioniert.
Nachteil ist, dass man jedesmal N*24Bit senden muss.
Wenn man weiß, dass man meistens alle DACs gleichzeitig mit neuen Werten
versorgen wird, ist das ok. Wenn man mal einen DAC in der Reihe nicht 
neu
mit Daten versorgen will, sendet man einfach ein NOP-Befehl
an der richtigen Position innerhalb der N*24Bit.

Parallel:
Da muss man nur die 24Bit des betreffenden DAC senden. Man braucht halt
individuelle Select-Leitungen. Alle DAC-SDI sind an einer Leitung und
alle DAC-SDO sind an einer Leitung. Aufpassen, dass nicht mehrere
Selects gleichzeitig aktiv sind.

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

so da ich gerade mal eine kurze Verschnaufoasue habe kommt hier ein 
Programm wo ich mal versuche auf Leufzeit zu optimieren:
Ich habe die doubles durch unsigned long ersetzt. damit wir trotzdem 
noch ausreichend genau rechnen musste ich dafür die Basiswert mit 
1000000 mutliplizieren.

ACHTUNG der SPI Takt steht noch auf 1 MHz ;-)
(glaube ich)
1
#include <stdio.h>
2
#include <mc912d128.h>
3
4
const unsigned long HalfRange = 2500000;
5
const unsigned long DACStepWidth = 5000000 / 0x03ffff;
6
7
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
8
{
9
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
10
  
11
  SP0DR = myValue; /* Data goes to SPI data register*/
12
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
13
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
14
}
15
16
void VValueTo18BitDAC(unsigned long VoltValue)
17
{
18
  unsigned long DACValue = 0;
19
  unsigned char mylowbyte = 0x00;
20
  unsigned char mymidbyte = 0x00;
21
  unsigned char myhighbyte = 0x00;
22
23
  DACValue = VoltValue / DACStepWidth; 
24
25
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
26
27
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
28
  DACValue = DACValue >> 8; /* shift the next Byte into position */
29
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
30
  DACValue = DACValue >> 8; /* shift the next Byte into position */
31
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
32
33
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
34
35
  if (VoltValue <= HalfRange) /* Check for Halfrange */
36
  {
37
    myhighbyte |= 0x08;   /* to be able to set the MSB */
38
  }
39
40
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
41
42
  PORTS &= ~0x80;  /* /SS output low */
43
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
44
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
45
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
46
  PORTS |= 0x80;    /* /SS output high */
47
}
48
49
main()
50
{ 
51
  int i = 1;
52
  unsigned long myVValue = 0; /* changed to float as we do not need 64bit from double */  
53
  
54
  /* Init for SPI Interface */
55
  PORTS |= 0x80;
56
  DDRS = DDRS | 0xF0; /* outputs */
57
  SP0CR1 = 0x58; /* 0b01011000 */
58
  SP0CR2 = 0; /* Normal mode */
59
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
60
61
  /* Init to the DAC */
62
  PORTS &= ~0x80;  /* /SS output low */
63
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
64
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
65
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
66
  PORTS |= 0x80;    /* /SS output high */
67
68
  while (i>0) /* Endles Data sending for testing only */
69
  { 
70
    VValueTo18BitDAC(myVValue);
71
    myVValue += DACStepWidth;
72
    if (myVValue > 5000000)
73
      myVValue = 0;
74
  }
75
  
76
  return 0;    
77
}

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW,

habe aus "Langeweile" trotzdem mal nen Versuch der Optimierung 
gestartet.
Habe mit Schrecken gelernt das double ja 8 byte lang ist.
Schau mal was Du von meiner Optimierungsidee denkst bitte.

Interrupts möchte ich wenn es eben geht vermeiden, weil damit 
überfordern wir Jochen fürchte ich. Dazu kommt das er ja offensichtlich 
nix ordentliches zum debuggen hat.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Ich habe nun ein neues Problem:

Ich möchte auf jeden Wert des Sägezahns einen Sinus geben, bei dem ich 
Ampl + Frequenz und Anzahl der Perioden einstellen kann.

Das wird das neue Problem ;)

Ich bin für jede Hilfe dankbar :)

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen.

schick mal mein Programm durch den geschwindigkeits test ;)
Das will ich jetzt wissen :D

Wie meinst DU auf jeden wert des Sägezahn?
Ich vermute Du willst auf den Sägezahn einen Sinus modulieren?

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Genau... und auf jeder Stufe soll dann einer sein ;)

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:

> schick mal mein Programm durch den geschwindigkeits test ;)
> Das will ich jetzt wissen :D

Läuft schon ;)

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hat nicht den gewünschten Erfolg ;) Und noch so ein hässlicher Peak nach 
unten :(

von Frank S. (franksanderdo)


Lesenswert?

Hattest Du den Takt auf 4 MHz geändert?
Wenn nicht bitte machen ;-)

Der PEak muss ich mal suchen warum ich da nen Überlauf rein bekomme ;-)

von J. R. (cia_man)


Lesenswert?

4 MHz liegen an:
1
 SP0BR = 0x00; /* 4,0 MHz SPI clock */

;)

von J. R. (cia_man)


Lesenswert?

Zum Thema Sinus habe ich mir überlegt, dass man ja die Amplitude, die 
der Sinus haben soll, einfach so umsetzen könnte, dass man zu dem DC 
Wert die Werte die man vorher errechnet hat hinzu addiert. Bloß wie man 
jetzt die Frequenz umsetzt? Die Sache mit einer oder 2 Perioden könnte 
man ja mit einer while-Schleife lösen oder?

Danke.

von Frank S. (franksanderdo)


Lesenswert?

ok dann haben wir gelernt:

Es waren nicht unbedingt die Fließkommazahlen ;)
(hat der HC12 ne eingebaute FPU??)

das ist schön das hilft und wir können mit dem alten Programm weiter 
arbeiten.

Jochen dir muss klar sein: schneller wird es durch den Sinus nicht ;-)

Also Sinus aufmodulieren:

Was ist die maximale amplitude?
Was ist die maximal frequenz?

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

das mit den 2 while Schleifen ist so eine Sache:
Du hast ja schon gelernt, das wir das Zeitverhalten des uC nicht 100% 
vorhersagen können. Wenn Du jetzt die Frequenz des Sinus über eine 
verschachtelte Schleife (im schlimmsten fall mit Wait) erzeugst, dann 
gibt das alles nur keinen Sinus mehr.

Um die position im Sinus (und damit den zugehörigen Wert) zu bestimmen 
brauchen wir dann doch einen Timer. Alles andere ist halbherzig.

Grüße Frank

von J. R. (cia_man)


Lesenswert?

Frequenz max: 100 kHz
Ampl max: 19 mA... in Volt... ?? Sagen wir 0,5 V!

Ja das ist schon klar, dass es langsamer wird... es dürfte dann bis zu 
0,5s brauchen ein Sinus... bzw 2 Perioden also 2 Sinuse ;)

Danke

von J. R. (cia_man)


Lesenswert?

Okay... owe ich sehe die Interrupts kommen ohoh! :)

von Frank S. (franksanderdo)


Lesenswert?

Jochen das passt jetzt net zusammen:

100kHz und 0,5s 2 perioden

;)

von J. R. (cia_man)


Lesenswert?

Die 0,5 s war nur ein Wert den der Guru bei uns in den Raum gestellt 
hat... sie wollen wissen wie lange es dauert so was zu modulieren ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

so kommen wir nicht weiter.
Kannst Du mir mal ein Bild skizzieren wie das Signal was ihr am ende 
braucht aussehen soll?

Ich muss verstehen was ich Dir erklären soll ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Wollen wir es nicht trotzdem für den Anfang mit einer while-Schleife 
probieren? Oder könnt ihr das mit dem Timer schnell umsetzen, bzw mir 
dabei helfen? Weil es soll schon nächste Woche laufen :(

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hier mal eine Skizze wie der Sinus an sich aussieht... und dieser kommt 
dann auf den Sägezahn bei jeder Stufe die wir haben... dadurch wird der 
Sägezahn sehr langsam...

von J. R. (cia_man)


Lesenswert?

Sorry für die schlechte Paint-Skizze ;)

von J. R. (cia_man)


Lesenswert?

Alles soweit verständlich?

Habe hier noch was zum Thema gefunden:

http://www.mikrocontroller.net/articles/Digitaler_Funktionsgenerator

Irgendwie macht mir die Sache gerade Bauchweh... :(

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ok war jetzt nicht ganz was ich erwartet habe aber macht nix.
Ich hab mir hier parallel auch mal ein wenig nen Kopf gemacht:

Ich würde gerne 360 Punkte pro Zyklus setzen (darfst raten warum)
Dann täte ich gerne erst mal nur den Sinus bauen. Das aufmodulieren 
machen wir dann im 2. Schritt ;-)

Das Problem das ich jetzt habe:
Ich habe keinen blassen Schimmer über die Timer im HC12.
Da musst Du mal die passenden Passagen im Handbuch suchen und wenn es 
geht ein oder 2 Beispiele.

Dann hoffe ich das es eine sin Funktion in deinen Bibliotheken gibt!?
Kannst Du das bitte rausfinden? Wenn es die nicht gibt, dann werden wir 
uns ein Tabelle mit den entsprechenden Werten basteln müssen.

Alles klar?
Dann los ans Werk ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Floating-Point Math Functions

ICCV7 for CPU12 generates reentrant code including floating-point 
mathematics (at V6, ICC12 floating-point code is non-reentrant due to 
the use of static variables).

The following floating-point math routines are supported. You must 
#include <math.h> before using these functions.

    float asinf(float x)

returns the arcsine of x for x in radians.

    float acosf(float x)

returns the arccosine of x for x in radians.

    float atanf(float x)

returns the arctangent of x for x in radians.

    float atan2f(float y, float x)

returns the angle whose tangent is y/x, in the range [-pi, +pi] radians.

    float ceilf(float x)

returns the smallest integer not less than x.

    float cosf(float x) )

returns the cosine of x for x in radians.

    float coshf(float x)

returns the hyperbolic cosine of x for x in radians.

    float expf(float x)

returns e to the x power.

    float exp10f(float x)

returns 10 to the x power.

    float fabsf(float x)

returns the absolute value of x.

    float floorf(float x)

returns the largest integer not greater than x.

    float fmodf(float x, float y)

returns the remainder of x/y.

    float frexpf(float x, int *pexp)

returns a fraction f and stores a base-2 integer into *pexp that 
represents the value of the input x. The return value is in the interval 
of [1/2, 1) and x equals f * 2**(*pexp).

    float froundf(float x)

rounds x to the nearest integer.

    float ldexpf(float x, int exp)

returns x * 2**exp.

    float logf(float x)

returns the natural logarithm of x.

    float log10f(float x)

returns the base-10 logarithm of x.

    float modff(float x, float *pint)

returns a fraction f and stores an integer into *pint that represents x. 
f + (*pint) equal x. abs(f) is in the interval [0, 1) and both f and 
*pint have the same sign as x.

    float powf(float x, float y) )

returns x raised to the power y.

    float sqrtf(float x) )

returns the square root of x.

    float sinf(float x)

returns the sine of x for x in radians.

    float sinhf(float x)

returns the hyperbolic sine of x for x in radians.

    float tanf(float x) )

returns the tangent of x for x in radians.

    float tanhf(float x)

returns the hyperbolic tangent of x for x in radians.

Since, by default, float and double have the same size (32 bits), math.h 
also contains a set of macros that map the function names to be without 
the f suffix form. For example, pow is the same as powf, sin is the same 
as sinf, etc.




Daraus haben wir hier die Fkt:

    float sinf(float x)

returns the sine of x for x in radians.

Schonmal einwas ;)

von Frank S. (franksanderdo)


Lesenswert?

bin schon am basteln ;-)

von J. R. (cia_man)


Lesenswert?

Der Timer heißt beim HC12 Enhanced Capture Timer... soweit ich weiß... 
nur ich habe auch damit so gut wie noch nie gearbeitet...

Außer dieses Blink-Programm:
1
//--------------------------------------------------------------
2
#include <stdio.h>
3
#include "mc912d128.h"
4
//--------------------------------------------------------------
5
void _HC12Setup(void) {
6
  COPCTL = 0x08;        // disable Watchdog
7
  }
8
//--------------------------------------------------------------
9
#pragma interrupt_handler isrOC2
10
void isrOC2(void) {
11
TFLG1 = 0x04; // clear OC2 Intr Flag
12
TC2 += 31250u; // 1 interrupt every 31250 timer ticks (0.5s)
13
PORTH ^= 0x80; // toggle LED
14
}
15
//--------------------------------------------------------------
16
void main(void) {
17
// install OC2 pseudo vector in RAM
18
// (if running with TwinPEEKs monitor)
19
*((unsigned char *)0x3FE2) = 0x06; // JMP opcode
20
*((void (**)(void))0x3FE3) = isrOC2;
21
// make PTH[7] an Output to drive the LED
22
DDRH |= 0x80;
23
// Timer Setup
24
TSCR = 0x80; // Timer enable
25
TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
26
TCTL2 = 0x00; // TC2 disconnected from Pin
27
TIOS |= 0x04; // TC2 is Output Compare
28
TMSK1 |= 0x04; // TC2 Interrupt enable
29
// enable Interrupts
30
asm("cli");
31
// loop endless (and let the interrupt work)
32
while(1) ;
33
}
34
//==============================================================

Wobei das uns jetzt glaube ich schon weiter bringt ;)

Sag mal wie weit dir das hilft!? Danke

von J. R. (cia_man)


Lesenswert?

Hier ist noch eine Timer-Idee ;)
1
#include <stdio.h>
2
3
#include <mc912d128.h>
4
5
6
void delay1ms(void) {
7
  asm("ldy #2666"); //2666 in Y-Register laden
8
  asm("dbne y,.");  // Decrement, bis Y=0 ist / 
9
            //3cyc x 125ns x 2666 = 0,99975ms
10
}
11
12
13
void wait(int duration)
14
{
15
  while(duration--)
16
  delay1ms();
17
}
18
19
20
21
void main(void) {
22
23
24
  DDRH |= 0x3F;
25
 
26
 
27
 
28
   
29
  while(1){
30
  
31
  PORTH ^=0x3F;
32
  wait(1000);
33
  
34
  }
35
}


Vlt hilft das auch!


Sag mir bitte inwieweit dir das hilft.

von Frank S. (franksanderdo)


Lesenswert?

Das ist sozusagen genial ;-)

von Frank S. (franksanderdo)


Lesenswert?

Also wegen überschneidung der Posts:

1. Post mit Timer und interrupt
So was suchte ich!

2. Post mit wait
Ich hau Dich, so was will ich net sehen ;-)

von J. R. (cia_man)


Lesenswert?

Juhuuu!!! ^^ Was nicht alles ein Blink-Programm bringt ;)


Okay vergiss 2. ;)

von Frank S. (franksanderdo)


Lesenswert?

ok dann basteln wir erst mal einen kleinen Sinus mit unbestimmter 
frequenz nur so zum üben:

kannst schon mal das Sägezahnprogramm mit fleißkomma wieder raus suchen 
und oben die maths Bibliothek einfügen.
Code schnipsel kommt gleich ;-)

Frank

von J. R. (cia_man)


Lesenswert?

Gutgut ;)

von Frank S. (franksanderdo)


Lesenswert?

1
main()
2
{ 
3
  int i = 1;
4
  int GradZaehler = 1;
5
  double myVValue = 0;  
6
  
7
  /* Init for SPI Interface */
8
  PORTS |= 0x80;
9
  DDRS = DDRS | 0xF0; /* outputs */
10
  SP0CR1 = 0x58; /* 0b01011000 */
11
  SP0CR2 = 0; /* Normal mode */
12
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
13
14
  /* Init to the DAC */
15
  PORTS &= ~0x80;  /* /SS output low */
16
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
17
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
18
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
19
  PORTS |= 0x80;    /* /SS output high */
20
21
  while (i>0) /* Endles Data sending for testing only */
22
  { 
23
    VValueTo18BitDAC(myVValue);
24
    myVValue = 2.5 + sin(GradZaehler++);
25
    if (GradZaehler > 360)
26
      GradZaehler = 1;
27
  }
28
  
29
  return 0;    
30
}

von Frank S. (franksanderdo)


Lesenswert?

Das sollte wenn ich net zu dumm bin einen 1 V Sinus um eine 2,5V Basis 
ergeben ;-)

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Geht! Du bist echt ein Held für mich ;) Die beiden Bilder geben dir auch 
mit dem "dreckigen" Sinus recht. :)

Saubere Sache! Thx

von Frank S. (franksanderdo)


Lesenswert?

Jochen das ist aber zu dreckig, da stimmt was nicht

Bitte mach mal einen Versuch mit 1 Mhz Takt am SPI!

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hier ein Ausschnitt aus dem Handbuch zum Thema Timer.

Mach ich mit 1.0 Mhz ;)

von Frank S. (franksanderdo)


Lesenswert?

Ich hätte 360 punkte erwartet nicht nur 6 oder 7

von J. R. (cia_man)


Lesenswert?

1.0 MHz liegen an! :0

Meinst du 4.0 Mhz???

von Frank S. (franksanderdo)


Lesenswert?

Uff das schockiert mich jetzt!
kannste mal eines mit 0,5 MHz machen?

ich verstehe gerade nicht was das Probelm ist das der keine 360 Schritte 
pro Zyklus macht :-(

von J. R. (cia_man)


Lesenswert?

Übrigens sollen dann später die Sinus-Werte aus einem Array gelesen 
werden...

Ich mach das mit den o,5 Mhz sofort ;)

von APW (Gast)


Lesenswert?

100kHz Sinus ? Hab ich das richtig verstanden ??

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW

da gibt es derzeit beim Jochen etwas Klärungsbedarf und es werden viele 
Werte durcheinander geworfen.

Ich glaube er braucht da was Zeit um das zu klären ;)

Grüße
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Ja ist alles zum probieren.... wie weit wir kommen ;)

Das ganze mit 500 kHz brachte keine Besserung! :(

Kann es auch am Oszi liegen? Settings?

von J. R. (cia_man)


Lesenswert?

Wir versuchen mal bis 70 kHz zu kommen.... die 100 KHz wären wirklich 
Obergrenze!

von Frank S. (franksanderdo)


Lesenswert?

Ich bin verwirrt

von J. R. (cia_man)


Lesenswert?

Warum? Weil der Sinus nicht so wird wie du willst?

von Frank S. (franksanderdo)


Lesenswert?

AHHHHHHHHHHHHHHHHHHHHHHHHHHH
Ich Rindviech!!!!!!!!!

änder bitte mal den
int Gradzaehler in einen
double GradZaehler

von J. R. (cia_man)


Lesenswert?

Auch wenn ich auf 31,25 KHz SPI Clock gehe ist kein Unterschied zu sehen 
:(

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4
5
6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8
9
10
11
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
12
{
13
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
14
  
15
  SP0DR = myValue; /* Data goes to SPI data register*/
16
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
17
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
18
}
19
20
void VValueTo18BitDAC(double VoltValue)
21
{
22
  unsigned long DACValue = 0;
23
  unsigned char mylowbyte = 0x00;
24
  unsigned char mymidbyte = 0x00;
25
  unsigned char myhighbyte = 0x00;
26
27
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
28
29
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
30
31
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
32
  DACValue = DACValue >> 8; /* shift the next Byte into position */
33
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
34
  DACValue = DACValue >> 8; /* shift the next Byte into position */
35
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
36
37
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
38
39
  if (VoltValue <= HalfRange) /* Check for Halfrange */
40
  {
41
    myhighbyte |= 0x08;   /* to be able to set the MSB */
42
  }
43
44
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
45
46
  PORTS &= ~0x80;  /* /SS output low */
47
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
48
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
49
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
50
  PORTS |= 0x80;    /* /SS output high */
51
}
52
53
main()
54
{ 
55
  int i = 1;
56
  double GradZaehler = 1;
57
  double myVValue = 0;  
58
  
59
  /* Init for SPI Interface */
60
  PORTS |= 0x80;
61
  DDRS = DDRS | 0xF0; /* outputs */
62
  SP0CR1 = 0x58; /* 0b01011000 */
63
  SP0CR2 = 0; /* Normal mode */
64
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
65
66
  /* Init to the DAC */
67
  PORTS &= ~0x80;  /* /SS output low */
68
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
69
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
70
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
71
  PORTS |= 0x80;    /* /SS output high */
72
73
  while (i>0) /* Endles Data sending for testing only */
74
  { 
75
    VValueTo18BitDAC(myVValue);
76
    myVValue = 2.5 + sin(GradZaehler++);
77
    if (GradZaehler > 360)
78
      GradZaehler = 1;
79
  }
80
  
81
  return 0;    
82
}


Programm. Und dazugehörige Aufnahme.

von APW (Gast)


Lesenswert?

Überleg dir mal, mit SPI können wir max 166000 Werte/s an einen (1) DAC
senden. Wenn das dein Ernst ist, kannst du schonmal den C-Compiler 
weglegen.
Das wird nur mit Integer+Hardcore Assembler was. Und selbst dann reicht 
es lange nicht.

Soll der Sinus auf den Sägezahn addiert oder multipliziert werden ?

Übrigens wegen
1
    VValueTo18BitDAC(myVValue);
2
    myVValue = 2.5 + sin(GradZaehler++);
3
    if (GradZaehler > 360)
4
      GradZaehler = 1;

Das muss Radiant sein, nicht Grad.

Und der HC12 hat keine FP-Unit, nur einige Befehle, die den Compiler 
dabei
unterstützen können. Wobei der ICC wahrscheinlich nicht den schnellsten
Code erzeugt.

Wenn die Speed-Anforderungen so hoch sind und es überhaupt HC12-artig
sein soll, dann würde ich nen HCS12, oder viel besser (und komplexer)
HCX12 nehmen, eine DAC event. parallel anbinden und wenn man auf C
besteht, den CodeWarrior-Compiler nehmen.

Diese Card12 gibts auch mit HCS12 und HCX12

von Frank S. (franksanderdo)


Lesenswert?

@APW

Wieder muss ich mich bedaken, an den radiant habe ich net gedacht :-(

von J. R. (cia_man)


Lesenswert?

Das heißt also besser wie so komme ich nicht mit dieser Karte... Und 
wenn wir einfach die Sinus-Werte in ein Array legen und danach erst 
schreiben???

Also die Sinus-Rechnung vor der eigentlichen Schreib-Operation machen?

von APW (Gast)


Lesenswert?

Du siehst ja am Oszillogramm, dass eine Ausgabe aktuell ca 1,5ms dauert,
und das nur mit Sinus alleine.

von J. R. (cia_man)


Lesenswert?

APW schrieb:

> Soll der Sinus auf den Sägezahn addiert oder multipliziert werden ?
>

addiert!

von J. R. (cia_man)


Lesenswert?

@APW: Welche Frequenz meinst du dann, dass wir überhaupt schaffen?

von APW (Gast)


Lesenswert?

J. R. schrieb:
> @APW: Welche Frequenz meinst du dann, dass wir überhaupt schaffen?

Kommt drauf an, wie kompromisslos du programmierst.
-kein Float, wenns eilig ist
-Werte vorberechnen
-Assembler benutzen
-nicht universeller (=langsamer/komplexer/mehr code) programmieren,
 als es die Aufgabenstellung (die wir nicht kennen) erfordert.
-Timings planen

Ohne Kenntnis der Aufgabenstellung kann man nichts genaues über
die Machbarkeit sagen.

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

also nochmal weil es so schön war.
Ich bin echt zu lange raus :-(
Später haben wir es leichter weil da benutzen wir eine Tabelle ;-)

1
  while (i>0) /* Endles Data sending for testing only */
2
  { 
3
    VValueTo18BitDAC(myVValue);
4
    myVValue = 2.5 + sin(GradZaehler * 0.17453293);
5
    GradZaehler += 1;
6
    if (GradZaehler > 360)
7
      GradZaehler = 1;
8
  }

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

0.17453293??? Mit pi???

von Frank S. (franksanderdo)


Lesenswert?

@APW

Ich fürchte das wir bald erkennen werden, das selbst mit optimalster 
Programmierung der HC12 seine Grenzen erreicht.

Dennoch würde ich gerne das ganze weiter treiben, nicht zuletzt damit 
Jochen die Möglichkeiten kennt und das auf einen anderen (schnelleren) 
Prozessor umsetzen kann.

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

@ Jochen

das ist die Umrechung von Grad in Bogenmaß.
Der sinus in C (und allen anderen programmiersprachen) arbeitet mit 
Bogenmaß ;-)
APW hat es geasgt und ich habe jetzt ein Beißspur im Schreibtisch ;-)

Grüße
frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hier die neuen Bilder mit der Verbesserung! :)

Aber ein Peak muss halt dennoch wieder drinnen sein :(

von J. R. (cia_man)


Lesenswert?

Bogenmaß = Grad * Pi/180 = Grad *0,017453.... ;) Oder?

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hier mit 0,017... Bilder schauen besser aus oder?

von APW (Gast)


Lesenswert?

probier mal das
 ...
    GradZaehler += 1;
    if (GradZaehler = 360)
      GradZaehler = 0;
 ...

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ok der Peak beim 0 Durchlauf da will ich jetzt mal nicht pingelig sein. 
;-)
Den bekommen wir noch weg ;-)

Damit haben wir einen Sinus.
Gib mir bitte heute Abend um mal die Timernummer zu studieren.
Ich denke das ich aus dem Timer einen Sinus bauen kann und wir in der 
Main routine nur den Basis wert generieren.
Ich hab da so eine Idee ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Gut ^^ aber die 0,017 stimmt oder?? ;)

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

APW schrieb:
> probier mal das
>  ...
>     GradZaehler += 1;
>     if (GradZaehler = 360)
>       GradZaehler = 0;
>  ...

Sieht nicht so gut aus ;)

von Frank S. (franksanderdo)


Lesenswert?

Jochen das kann jetzt aber net sein.
Zeig mal Code

von Frank S. (franksanderdo)


Lesenswert?

die o,o17... stimmt

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Jochen das kann jetzt aber net sein.
> Zeig mal Code
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4
5
6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8
9
10
11
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
12
{
13
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
14
  
15
  SP0DR = myValue; /* Data goes to SPI data register*/
16
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
17
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
18
}
19
20
void VValueTo18BitDAC(double VoltValue)
21
{
22
  unsigned long DACValue = 0;
23
  unsigned char mylowbyte = 0x00;
24
  unsigned char mymidbyte = 0x00;
25
  unsigned char myhighbyte = 0x00;
26
27
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
28
29
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
30
31
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
32
  DACValue = DACValue >> 8; /* shift the next Byte into position */
33
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
34
  DACValue = DACValue >> 8; /* shift the next Byte into position */
35
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
36
37
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
38
39
  if (VoltValue <= HalfRange) /* Check for Halfrange */
40
  {
41
    myhighbyte |= 0x08;   /* to be able to set the MSB */
42
  }
43
44
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
45
46
  PORTS &= ~0x80;  /* /SS output low */
47
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
48
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
49
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
50
  PORTS |= 0x80;    /* /SS output high */
51
}
52
53
main()
54
{ 
55
  int i = 1;
56
  double GradZaehler = 1;
57
  double myVValue = 0;  
58
  
59
  /* Init for SPI Interface */
60
  PORTS |= 0x80;
61
  DDRS = DDRS | 0xF0; /* outputs */
62
  SP0CR1 = 0x58; /* 0b01011000 */
63
  SP0CR2 = 0; /* Normal mode */
64
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
65
66
  /* Init to the DAC */
67
  PORTS &= ~0x80;  /* /SS output low */
68
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
69
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
70
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
71
  PORTS |= 0x80;    /* /SS output high */
72
73
  while (i>0) /* Endles Data sending for testing only */
74
  { 
75
    VValueTo18BitDAC(myVValue);
76
    myVValue = 2.5 + sin(GradZaehler * 0.017453293);
77
     GradZaehler += 1;
78
    if (GradZaehler = 360)
79
      GradZaehler = 0;
80
  }
81
82
83
  
84
  return 0;    
85
}

von Frank S. (franksanderdo)


Lesenswert?

Ach ja der ist herrlich ;-)

if (GradZaehler == 360)

dann funkts

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Frank Sander schrieb:
> Ach ja der ist herrlich ;-)
>
> if (GradZaehler == 360)
>
> dann funkts

Naja :) einen Peak hab ich aber noch ;) manchmal auch mehr... immer beim 
0-Durchgang... ???
1
while (i>0) /* Endles Data sending for testing only */
2
  { 
3
    VValueTo18BitDAC(myVValue);
4
    myVValue = 2.5 + sin(GradZaehler * 0.017453293);
5
     GradZaehler += 1;
6
    if (GradZaehler == 360)
7
    {
8
       GradZaehler = 0;
9
    }
10
  }
11
12
13
  
14
  return 0;    
15
}

Komisch? Klammern habe ich auch gesetzt!

von J. R. (cia_man)


Lesenswert?

Ich habe jetzt sooo viele Variationen probiert (hier nicht genannt).... 
Peak bleibt :( das kann doch nicht sein ;(

von Frank S. (franksanderdo)


Lesenswert?

Wenn Du den Oscar weiter auflöst, kommt der dann bei jedem Zyklus?

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Frank Sander schrieb:
> Wenn Du den Oscar weiter auflöst, kommt der dann bei jedem Zyklus?

Er kommt und geht immer bei 0-Durchgängen.... siehe Bilder...

Manchmal ist der Peak auch total weg... und im nächsten Moment ist er 
wieder da... :(

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ich vermute das der Oscar den peak nicht immer auflöst.
Den bekommen wir weg, das ist kein Problem.

Kannst DU bitte mal einen Zyklus die genaue Länge bestimmen?

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,
Hallo APW,

ich hab da mal wieder was gebastelt ;-)
Ob das funktioniert? Keine Ahnung!
Ich habe net alles verstanden was ich aus dem Timer Beispiel geklaut 
habe.
Evtl. findet ja noch jemand was mehr Text zu dem Timer im HC12
Jochen ist mal wieder das Versuchstier :-D

Fehlermeldungen bitte zu mir.
Anregungen bitte auch zu mir.

Grüße
Frank
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4
5
const double HalfRange = 2.5;
6
const double DACStepWidth = 5.0 / 0x03ffff;
7
8
double GradZaehler = 1;
9
double SinusOffset = 0.5;
10
double SinusAmplitude = 0.5;
11
12
void _HC12Setup(void) /* interesting but I did not see it is called some were */
13
{
14
  COPCTL = 0x08;        // disable Watchdog
15
}
16
17
#pragma interrupt_handler isrOC2 /* this most probably tells the Compiler about the interrupt hanlder */
18
19
void isrOC2(void) 
20
{
21
  unsigned long DACValue = 0;
22
  unsigned char mylowbyte = 0x00;
23
  unsigned char mymidbyte = 0x00;
24
  unsigned char myhighbyte = 0x00;
25
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
26
  double VoltValue = 0;
27
28
  TFLG1 = 0x04; // clear OC2 Intr Flag
29
  TC2 += 3125u; // 1 interrupt every 3125 timer ticks (0.05s) is kind of slow but good for the start ;-)
30
31
  VoltValue = SinusOffset + (sin(GradZaehler * 0.017453293) * SinusAmplitude);
32
33
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
34
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
35
36
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
37
  DACValue = DACValue >> 8; /* shift the next Byte into position */
38
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
39
  DACValue = DACValue >> 8; /* shift the next Byte into position */
40
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
41
42
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
43
44
  if (VoltValue <= HalfRange) /* Check for Halfrange */
45
  {
46
    myhighbyte |= 0x08;   /* to be able to set the MSB */
47
  }
48
49
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
50
51
  PORTS &= ~0x80;  /* /SS output low */
52
  SP0DR = myhighbyte; /* Data goes to SPI data register*/
53
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
54
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
55
  SP0DR = mymidbyte; /* Data goes to SPI data register*/
56
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
57
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
58
  SP0DR = mylowbyte; /* Data goes to SPI data register*/
59
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
60
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
61
  PORTS |= 0x80;    /* /SS output high */
62
}
63
64
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
65
{
66
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
67
  
68
  SP0DR = myValue; /* Data goes to SPI data register*/
69
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
70
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
71
}
72
73
main()
74
{ 
75
  int i = 1;
76
  /*********************************************************/
77
  /* Honestly the following I beblieve is not needed         */
78
  /*********************************************************/
79
  // install OC2 pseudo vector in RAM                        /***/
80
  // (if running with TwinPEEKs monitor)                    /***/
81
  *((unsigned char *)0x3FE2) = 0x06; // JMP opcode  /***/
82
  *((void (**)(void))0x3FE3) = isrOC2;                         /***/
83
  /********************************************************/
84
  /********************************************************/
85
86
  /*********************************************************/
87
  /*        Here starts what I beblieve is needed                */
88
  /*********************************************************/
89
  /* Init for SPI Interface */
90
  PORTS |= 0x80;
91
  DDRS = DDRS | 0xF0; /* outputs */
92
  SP0CR1 = 0x58; /* 0b01011000 */
93
  SP0CR2 = 0; /* Normal mode */
94
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
95
96
  /* Init to the DAC */
97
  PORTS &= ~0x80;  /* /SS output low */
98
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
99
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
100
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
101
  PORTS |= 0x80;    /* /SS output high */
102
103
  // Timer Setup
104
  TSCR = 0x80; // Timer enable
105
  TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
106
  TCTL2 = 0x00; // TC2 disconnected from Pin
107
  TIOS |= 0x04; // TC2 is Output Compare
108
  TMSK1 |= 0x04; // TC2 Interrupt enable
109
  // enable Interrupts
110
  asm("cli");
111
112
  while (i>0) 
113
  { 
114
    SinusOffset += DACStepWidth;
115
    if (SinusOffset >= (5.0 - SinusAmplitude))
116
      SinusOffset = SinusAmplitude;
117
  }  
118
  return 0;    
119
}

von APW (Gast)


Lesenswert?

Hallo Frank

Eine Frage. Hast du schon mal uC programmiert ?
(Ich meine mehr als 100 Zeilen und mit Interrups und so).
Bitte nicht übelnehmen.
In deinem Quellcode hats ein paar Sachen drin, da könnte ich schlaflose
Nächte bekommen ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW,

jep habe ich. Ist aber 20 Jahre her. Von daher würde ich mich heute 
wieder Anfänger nennen.
Habe allerdings noch nie Interrupts in C eingebunden. Dafür habe ich 
früher immer Assembler pur gearbeitet.

Sag mal an was Dich beunruhigt. Ich will ja auch dazulernen.
Sorry wenn ich Dir die Nachtruhe raube. ;-)

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Soll ich das Programm nun trotzdem eingeben? Ehr nicht oder? :)

Wollen wir bis APW antwortet den Sinus säubern? Frank?

Gruß

von APW (Gast)


Lesenswert?

Ich hab gedacht ihr überlegt euch, was euch gleich um die Ohren fliegt,
und was euch erst später probleme macht.

Frage an Jochen:
Benutzt du TwinPeeks? Außerdem verwendest du ICC mit den Bibliotheken
in der Version 7?

von J. R. (cia_man)


Lesenswert?

Ich verwende TwinPeeks & ICC V7 ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Du kannst ja die Zeit nutzen und schon mal eine Tabelle mit den 360 
Werten für den Sinus generieren ;-)

Damit können wir dann den sin() rauswerfen. Kommt sicherlich der 
Geschwindigkeit zugute.

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW

sag an was Dich am meisten stört und ich werde versuchen mich zu 
bessern.
Leider steh ich das den HC12 betrifft etwas auf dem Schlauch, weil ich 
den vorher noch nicht genutzt habe. Unterlagen habe ich nur was ich 
bisher aus dem Netz gesammelt habe.

Da ich das ganze neben meinem normalen Job betreibe, bitte ich um 
Nachsicht bei den diversen Böcken die ich einbaue. Ich hoffe das Jochen 
trotzdem die Ideen die dahinter stecken versteht und umsetzen kann.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hallo APW
>
> sag an was Dich am meisten stört und ich werde versuchen mich zu
> bessern.
> Leider steh ich das den HC12 betrifft etwas auf dem Schlauch, weil ich
> den vorher noch nicht genutzt habe. Unterlagen habe ich nur was ich
> bisher aus dem Netz gesammelt habe.
>
> Da ich das ganze neben meinem normalen Job betreibe, bitte ich um
> Nachsicht bei den diversen Böcken die ich einbaue. Ich hoffe das Jochen
> trotzdem die Ideen die dahinter stecken versteht und umsetzen kann.
>
> Grüße
> Frank

Ich will es versuchen Meister ;)

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> Du kannst ja die Zeit nutzen und schon mal eine Tabelle mit den 360
> Werten für den Sinus generieren ;-)
>
> Damit können wir dann den sin() rauswerfen. Kommt sicherlich der
> Geschwindigkeit zugute.
>
> Grüße
> Frank

Soll ich die dann mit dem Taschenrechner berechnen? Oder wie würdest du 
da vorgehen?

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Ich persönlich bin ja eine faule Sau :-D, deswegen würde ich z.B. Excel 
dafür nutzen.
Geht einfacher und schneller ;)
Ausserdem kannst Du von da die Daten einfacher übernehmen.

Wenn Du dann noch sofort die 18 Bit werde generierst.... Das wäre mal ne 
so schlecht ;-)

Grüße
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hab Excel genommen ;)

Hab das Programm hier im Inet gefunden und modifiziert. Die Werte in der 
E-Spalte hast du gemeint oder? ;)

Gruß

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

das sieht doch schon net schlecht aus.
Da müssen die 0 udn max werte noch korrigiert werden ;-)

Dann das ganze mit der Schrittweite multipliziert ergibt die Werte 
welche wir für den DAC brauchen.

Grüße
Frank

von APW (Gast)


Lesenswert?

Da sind einige Fallen drin, kleine wie große. Und die sind nichtmal
HC12-spezifisch.

Mal der Reihe nach (kein Anspruch auf Vollständigkeit)
1) SinusOffset: Damit rechnest du in der Haupschleife UND in
   der Interruptfunktion (kurz ISR)
a)Was passiert, wenn die ISR Variablen verwendet, die vielleicht
  zum Interruptzeitpunkt gerade in der Haupschleife bearbeitet werden ?
  -> aus ISR rauswerfen oder in der Haupschleife z.B. mit kurzen (!!)
     Interruptsperren absichern
b)Wiedereintrittsfähigkeit (siehe auch Docu zum ICC6/7).
  Hier habt ihr reines Glück, dass Jochen den ICC V7 verwendet,
  bei ICC V6 (und auch bei einigen anderen Entwicklungsumgebungen)
  kann die gleichzeitige Verwendung von Float-Rechnungen
  in einer ISR und in der Haupschleife schiefgehen.
  In der ICC-Doku steht:

ICCV7 for CPU12 generates reentrant code including floating-point 
mathematics (at V6, ICC12 floating-point code is non-reentrant due to 
the use of static variables).

2) Halte die ISR so kurz wie möglich. Das mag jetzt noch funktionieren,
   aber irgendwann, wenn man nicht aufpasst ist auf einmal die Zeit
   für die ISR-Abarbeitung länger als als das ISR-Timerintervall.
1
  VoltValue = SinusOffset + (sin(GradZaehler * 0.017453293) * SinusAmplitude);
2
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
  Das sind folgende Double-Rechnungen
  1x sin(), 2x Multiplikationen,
  1x Addition, 1x Division, 1x Konvertierung Double->Long

  Das frisst Zeit, und sollte nich in einer ISR stehen.
  Ich würde alles vorberechnen und in der ISR nur noch die
  fertigen Bytes über SPI rausschieben.

3) // Timer Setup
   TSCR = 0x80; // Timer enable
   ...(Timer Register init)
   Ich würde generell empfehlen, den Timer erst zu enablen, wenn die
   anderen Timer-Register initialisiert worden sind. Das kann dazu
   führen, dass das erste Zeitintervall nicht stimmt.

Am WE Veruche ich mal, das Programm (mit einigen Anpassungen) auf meiner
HW (S12Compact) laufen zu lassen. Da ist ein 16Bt DAC drauf, der auch
über SPI angebunden ist.

Wegen dem Sinus: Der DT128 hat doch 8KB Ram.
Da kann man locker eine Sinustabelle im Init-Teil des
Programms vorberechnen, am besten gleich als Ganzzahl !?

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> das sieht doch schon net schlecht aus.
> Da müssen die 0 udn max werte noch korrigiert werden ;-)
>
> Dann das ganze mit der Schrittweite multipliziert ergibt die Werte
> welche wir für den DAC brauchen.
>
> Grüße
> Frank

Hab nochmal das Diagramm durch ein ungerundetes ergänzt ;)

Aber ich verstehe jetzt nicht was du noch gerechent haben willst?

Kannst du mir mal die Fkt dazu hinschreiben?

von J. R. (cia_man)


Lesenswert?

APW schrieb:
> Da sind einige Fallen drin, kleine wie große. Und die sind nichtmal
> HC12-spezifisch.
>
> Mal der Reihe nach (kein Anspruch auf Vollständigkeit)
> 1) SinusOffset: Damit rechnest du in der Haupschleife UND in
>    der Interruptfunktion (kurz ISR)
> a)Was passiert, wenn die ISR Variablen verwendet, die vielleicht
>   zum Interruptzeitpunkt gerade in der Haupschleife bearbeitet werden ?
>   -> aus ISR rauswerfen oder in der Haupschleife z.B. mit kurzen (!!)
>      Interruptsperren absichern
> b)Wiedereintrittsfähigkeit (siehe auch Docu zum ICC6/7).
>   Hier habt ihr reines Glück, dass Jochen den ICC V7 verwendet,
>   bei ICC V6 (und auch bei einigen anderen Entwicklungsumgebungen)
>   kann die gleichzeitige Verwendung von Float-Rechnungen
>   in einer ISR und in der Haupschleife schiefgehen.
>   In der ICC-Doku steht:
>
> ICCV7 for CPU12 generates reentrant code including floating-point
> mathematics (at V6, ICC12 floating-point code is non-reentrant due to
> the use of static variables).
>
> 2) Halte die ISR so kurz wie möglich. Das mag jetzt noch funktionieren,
>    aber irgendwann, wenn man nicht aufpasst ist auf einmal die Zeit
>    für die ISR-Abarbeitung länger als als das ISR-Timerintervall.
>
1
>   VoltValue = SinusOffset + (sin(GradZaehler * 0.017453293) *
2
> SinusAmplitude);
3
>   DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
4
>
>   Das sind folgende Double-Rechnungen
>   1x sin(), 2x Multiplikationen,
>   1x Addition, 1x Division, 1x Konvertierung Double->Long
>
>   Das frisst Zeit, und sollte nich in einer ISR stehen.
>   Ich würde alles vorberechnen und in der ISR nur noch die
>   fertigen Bytes über SPI rausschieben.
>
> 3) // Timer Setup
>    TSCR = 0x80; // Timer enable
>    ...(Timer Register init)
>    Ich würde generell empfehlen, den Timer erst zu enablen, wenn die
>    anderen Timer-Register initialisiert worden sind. Das kann dazu
>    führen, dass das erste Zeitintervall nicht stimmt.
>
> Am WE Veruche ich mal, das Programm (mit einigen Anpassungen) auf meiner
> HW (S12Compact) laufen zu lassen. Da ist ein 16Bt DAC drauf, der auch
> über SPI angebunden ist.
>
> Wegen dem Sinus: Der DT128 hat doch 8KB Ram.
> Da kann man locker eine Sinustabelle im Init-Teil des
> Programms vorberechnen, am besten gleich als Ganzzahl !?


Zu 3. : Du würdest das also drehen...

// Timer Setup
  TSCR = 0x80; // Timer enable
  TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
  TCTL2 = 0x00; // TC2 disconnected from Pin
  TIOS |= 0x04; // TC2 is Output Compare
  TMSK1 |= 0x04; // TC2 Interrupt enable

TSCR = .... ganz nach unten?

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Wert aus Spalte E * (5/0x3ffff) ;-)

Damit sparen wir einen Rechneschritt auf dem Controler ;-)

Grüße
Frank

von APW (Gast)


Lesenswert?

J. R. schrieb:
> TSCR = .... ganz nach unten?

Ja, so würde ich das machen.
Ich schau erst heute mittag wieder rein.
Hinter mir stapelt sich die Arbeit.

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW,

1a: Mist da habe ich wirklich net bedacht :-(
Ich war davon ausgegangen das ein reiner lesezugriff im Handler mir 
keine Probleme bereitet.

1b: Jep verstanden! So langsam kommt es mir wieder wieso ich früher 
immer gepredigt habe interrupt handler nur in assembler zu schreiben. Da 
wäre ich auf die Idee gar net gekommen floating point zu nutzen ;-)

2: rechst haste, deswegen habe ich die Zeit im Moment auch noch so lang 
gelassen.
Die Idee hinter dem Programm:
Sinus wird durch den timer gebaut. Damit bekomme ich den halbwegs 
stabil.
Mit dieser Version wollte ich die generelle Idee testen. Optimierung 
(sin() raus, floating point raus) sollten dann folgen.

3. Ups, den Teil habe ich einfach übernommen und net gesehen das da die 
Reihefolge vertauscht ist. Sorry, ich gelobe Besserung, habt Geduld mit 
einem alten Mann ;-)

Wäre klasse wenn Du am WE das ganze mal was mehr gerade rücken könntest.
Ich werde mit Jochen bis dahin mal versuchen alles was an floating point 
weg optimiert werden kann weg zu optimieren ;-)

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

wie schauts sollen wir uns an der Tabelle versuchen?
Wir nutzen erst mal das Programm ohne interrupt ;-)

Grüße Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

TIPPFEHLER!!!

E2 / (5/0x3FFFF)

ware es gewesen.

von Frank S. (franksanderdo)


Lesenswert?

const long SinusWerte[] = {0, 915, 1830, 2744, 3657, 4569, 5480, 6389, 
7297, 8202, 9104, 10004, 10901... };

so fängt die Tabelle an. Kannst Du das bitte komplettieren.

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Hey!

In Office werde ich gleich reingehen und mein Glück versuchen... mom 
erst einmal die Screenshots vom Programm wie du es mir geschickt 
hast.... ;)

Danke!

PS: Sieht man da den Sinus???

von J. R. (cia_man)


Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> TIPPFEHLER!!!
>
> E2 / (5/0x3FFFF)
>
> ware es gewesen.

Das geht so nicht direkt :( da muss ich erstmal schauen...

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

also ich seh den Sinus da net wirklich.
ein Verdacht: 0,05 sec zwischen den Sinus werten kann was lang sein ;-)

Grüße
Frank

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

tataaaaa :) Wird jedoch weiter unten neg... :(

von J. R. (cia_man)


Lesenswert?

1
// Timer Setup
2
  TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
3
  TCTL2 = 0x00; // TC2 disconnected from Pin
4
  TIOS |= 0x04; // TC2 is Output Compare
5
  TMSK1 |= 0x04; // TC2 Interrupt enable
6
  TSCR = 0x80; // Timer enable
7
  // enable Interrupts
8
  asm("cli");

so geht mal gar nix ;(

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

das die Werte negativ werden ist genau was wir wollen ;-)
Kannst Du bitte (in unserem Programm ohne Interrupt) die Tabelle 
generieren?

Definition habe ich oben schon stehen ;-)

Ich werde derweil die anderen Änderungen vorbereiten.

Grüße
Frank

von J. R. (cia_man)


Lesenswert?

1
// Timer Setup
2
  TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
3
  TCTL2 = 0x00; // TC2 disconnected from Pin
4
  TIOS |= 0x04; // TC2 is Output Compare
5
  TSCR = 0x80; // Timer enable
6
  TMSK1 |= 0x04; // TC2 Interrupt enable
7
  // enable Interrupts
8
  asm("cli");

so geht es ebenfalls net :(

Es geht nur wie Frank es vorgeschlagen hat ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

Ich denke wir warten mit der Interruptroutine noch ein wenig.
Mein Vorschlag funkt ja auch net wirklich ;-)

Wenn wir für APW das ganze vorbereiten das die floating point 
Berechnungen weg sind wäre das Klasse.
Am WE werde ich versuchen mich in den Timer einzulesen.

Grüße Frank

von J. R. (cia_man)


Lesenswert?

So Arbeit erledigt.... bitte lass mich sowas nicht wieder machen :)
War übelst nervig^^
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4
5
6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8
9
const long SinusWerte[] = {0,915,1830,2744,3657,4569,5480,6389,7297,8202,9104,10004,10901,11794,12684,13570,14451,15329,
10
                           16201,17069,17932,18789,19640,20485,21325,22157,22983,23802,24614,25418,26214,27003,27783,
11
                           28555,29318,30072,30817,31552,32278,32994,33700,34396,35082,35756,36420,37073,37714,38344,38962,
12
                           39568,40163,40745,41314,41871,42416,42947,43465,43970,44462,44940,45404,45855,46292,46714,47123,
13
                           47516,47896,48261,48611,48946,49267,49572,49863,50138,50398,50642,50871,51085,51283,51465,51632,51783,
14
                           51918,52038,52141,52229,52301,52357,52397,52421,52429,52421,52397,52357,52301,52229,52141,52038,
15
                           51918,51783,51632,51465,51283,51085,50871,50642,50398,50138,49863,49572,49267,48946,48611,48261,
16
                           47896,47516,47123,46714,46292,45855,45404,44940,44462,43970,43465,42947,42416,41871,41314,40745,
17
                           40163,39568,38962,38344,37714,37073,36420,35756,35082,34396,33700,32994,32278,31552,30817,30072,
18
                           29318,28555,27783,27003,26214,25418,24614,23802,22983,22157,21325,20485,19640,18789,17932,17069,
19
                           16201,15329,14451,13570,12684,11794,10901,10004,9104,8202,7297,6389,5480,4569,3657,2744,1830,915,0,
20
                           -915,-1830,-2744,-3657,-4569,-5480,-6389,-7297,-8202,-9104,-10004,-10901,-11794,-12684,-13570,-14451,
21
                           -15329,-16201,-17069,-17932,-18789,-19640,-20485,-21325,-22157,-22983,-23802,-24614,-25418,-26214,
22
                           -27003,-27783,-28555,-29318,-30072,-30817,-31552,-32278,-32994,-33700,-34396,-35082,-35756,-36420,
23
                           -37073,-37714,-38344,-38962,-39568,-40163,-40745,-41314,-41871,-42416,-42947,-43465,-43970,-44462,
24
                           -44940,-45404,-45855,-46292,-46714,-47123,-47516,-47896,-48261,-48611,-48946,-49267,-49572,-49863,
25
                           -50138,-50398,-50642,-50871,-51085,-51283,-51465,-51632,-51783,-51918,-52038,-52141,-52229,-52301,
26
                           -52357,-52397,-52421,-52429,-52421,-52397,-52357,-52301,-52229,-52141,-52038,-51918,-51783,-51632, 
27
               -51465,-51283,-51085,-50871,-50642,-50398,-50138,-49863,-49572,-49267,-48946,-48611,-48261,-47896,
28
                           -47516,-47123,-46714,-46292,-45855,-45404,-44940,-44462,-43970,-43465,-42947,-42416,-41871,-41314,
29
                           -40745,-40163,-39568,-38962,-38344,-37714,-37073,-36420,-35756,-35082,-34396,-33700,-32994,-32278,
30
                           -31552,-30817,-30072,-29318,-28555,-27783,-27003,-26214,-25418,-24614,-23802,-22983,-22157,-21325,
31
                           -20485,-19640,-18789,-17932,-17069,-16201,-15329,-14451,-13570,-12684,-11794,-10901,-10004,-9104,-8202,
32
                           -7297,-6389,-5480,-4569,-3657,-2744,-1830,-915,-0};
33
34
35
36
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
37
{
38
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
39
  
40
  SP0DR = myValue; /* Data goes to SPI data register*/
41
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
42
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
43
}
44
45
void VValueTo18BitDAC(double VoltValue)
46
{
47
  unsigned long DACValue = 0;
48
  unsigned char mylowbyte = 0x00;
49
  unsigned char mymidbyte = 0x00;
50
  unsigned char myhighbyte = 0x00;
51
52
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
53
54
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
55
56
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
57
  DACValue = DACValue >> 8; /* shift the next Byte into position */
58
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
59
  DACValue = DACValue >> 8; /* shift the next Byte into position */
60
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
61
62
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
63
64
  if (VoltValue <= HalfRange) /* Check for Halfrange */
65
  {
66
    myhighbyte |= 0x08;   /* to be able to set the MSB */
67
  }
68
69
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
70
71
  PORTS &= ~0x80;  /* /SS output low */
72
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
73
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
74
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
75
  PORTS |= 0x80;    /* /SS output high */
76
}
77
78
main()
79
{ 
80
  int i = 1;
81
  double GradZaehler = 1;
82
  double myVValue = 0;  
83
  
84
  /* Init for SPI Interface */
85
  PORTS |= 0x80;
86
  DDRS = DDRS | 0xF0; /* outputs */
87
  SP0CR1 = 0x58; /* 0b01011000 */
88
  SP0CR2 = 0; /* Normal mode */
89
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
90
91
  /* Init to the DAC */
92
  PORTS &= ~0x80;  /* /SS output low */
93
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
94
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
95
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
96
  PORTS |= 0x80;    /* /SS output high */
97
98
  while (i>0) /* Endles Data sending for testing only */
99
  { 
100
    VValueTo18BitDAC(myVValue);
101
    myVValue = 2.5 + sin(GradZaehler * 0.017453293);
102
     GradZaehler += 1;
103
    if (GradZaehler == 360)
104
    {
105
       GradZaehler = 0;
106
    }
107
  }
108
109
110
  
111
  return 0;    
112
}

Das frisst er soweit ohne Fehler!

Danke!

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

ich hab da mal was vorbereitet "Jean Pütz" ;-)
Da fehlt jetzt noch die SinusTabelle  von Dir und ein Testlauf.

Grüße
Frank
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4
5
const double HalfRange = 2.5;
6
const double DACStepWidth = 5.0 / 0x03ffff;
7
8
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
9
{
10
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
11
  
12
  SP0DR = myValue; /* Data goes to SPI data register*/
13
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
14
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
15
}
16
17
void VValueTo18BitDAC(unsigned long VoltValue)
18
{
19
  unsigned long DACValue = 0;
20
  unsigned char mylowbyte = 0x00;
21
  unsigned char mymidbyte = 0x00;
22
  unsigned char myhighbyte = 0x00;
23
24
  DACValue = VoltValue;
25
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
26
27
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
28
  DACValue = DACValue >> 8; /* shift the next Byte into position */
29
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
30
  DACValue = DACValue >> 8; /* shift the next Byte into position */
31
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
32
33
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
34
35
  if (VoltValue <= 0x1ffff) /* Check for Halfrange */
36
  {
37
    myhighbyte |= 0x08;   /* to be able to set the MSB */
38
  }
39
40
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
41
42
  PORTS &= ~0x80;  /* /SS output low */
43
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
44
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
45
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
46
  PORTS |= 0x80;    /* /SS output high */
47
}
48
49
main()
50
{ 
51
  int i = 0;
52
53
  int GradZaehler = 0;
54
  double myVValue = 0;  
55
  
56
  /* Init for SPI Interface */
57
  PORTS |= 0x80;
58
  DDRS = DDRS | 0xF0; /* outputs */
59
  SP0CR1 = 0x58; /* 0b01011000 */
60
  SP0CR2 = 0; /* Normal mode */
61
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
62
63
  /* Init to the DAC */
64
  PORTS &= ~0x80;  /* /SS output low */
65
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
66
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
67
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
68
  PORTS |= 0x80;    /* /SS output high */
69
70
  while (i>0) /* Endles Data sending for testing only */
71
  { 
72
    myVValue = (2.5 / DACStepWidth) + SinusTabelle[GradZaehler++];    
73
    VValueTo18BitDAC(myVValue);
74
    if (GradZaehler > 360)
75
      GradZaehler = 0;
76
  }
77
  return 0;    
78
}

von Frank S. (franksanderdo)


Lesenswert?

Sorry Jochen,

muss leider manchmal sein ;-)
Deswegen hab ich das ja net selber gemacht.

Grüße Frank

von Frank S. (franksanderdo)


Lesenswert?

Ach ja, mit welchem SPI Takt rennen wir denn eigentlich gerade?

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4
5
6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8
9
const long SinusWerte[] = {0,915,1830,2744,3657,4569,5480,6389,7297,8202,9104,10004,10901,11794,12684,13570,14451,15329,
10
                           16201,17069,17932,18789,19640,20485,21325,22157,22983,23802,24614,25418,26214,27003,27783,
11
                           28555,29318,30072,30817,31552,32278,32994,33700,34396,35082,35756,36420,37073,37714,38344,38962,
12
                           39568,40163,40745,41314,41871,42416,42947,43465,43970,44462,44940,45404,45855,46292,46714,47123,
13
                           47516,47896,48261,48611,48946,49267,49572,49863,50138,50398,50642,50871,51085,51283,51465,51632,51783,
14
                           51918,52038,52141,52229,52301,52357,52397,52421,52429,52421,52397,52357,52301,52229,52141,52038,
15
                           51918,51783,51632,51465,51283,51085,50871,50642,50398,50138,49863,49572,49267,48946,48611,48261,
16
                           47896,47516,47123,46714,46292,45855,45404,44940,44462,43970,43465,42947,42416,41871,41314,40745,
17
                           40163,39568,38962,38344,37714,37073,36420,35756,35082,34396,33700,32994,32278,31552,30817,30072,
18
                           29318,28555,27783,27003,26214,25418,24614,23802,22983,22157,21325,20485,19640,18789,17932,17069,
19
                           16201,15329,14451,13570,12684,11794,10901,10004,9104,8202,7297,6389,5480,4569,3657,2744,1830,915,0,
20
                           -915,-1830,-2744,-3657,-4569,-5480,-6389,-7297,-8202,-9104,-10004,-10901,-11794,-12684,-13570,-14451,
21
                           -15329,-16201,-17069,-17932,-18789,-19640,-20485,-21325,-22157,-22983,-23802,-24614,-25418,-26214,
22
                           -27003,-27783,-28555,-29318,-30072,-30817,-31552,-32278,-32994,-33700,-34396,-35082,-35756,-36420,
23
                           -37073,-37714,-38344,-38962,-39568,-40163,-40745,-41314,-41871,-42416,-42947,-43465,-43970,-44462,
24
                           -44940,-45404,-45855,-46292,-46714,-47123,-47516,-47896,-48261,-48611,-48946,-49267,-49572,-49863,
25
                           -50138,-50398,-50642,-50871,-51085,-51283,-51465,-51632,-51783,-51918,-52038,-52141,-52229,-52301,
26
                           -52357,-52397,-52421,-52429,-52421,-52397,-52357,-52301,-52229,-52141,-52038,-51918,-51783,-51632, 
27
               -51465,-51283,-51085,-50871,-50642,-50398,-50138,-49863,-49572,-49267,-48946,-48611,-48261,-47896,
28
                           -47516,-47123,-46714,-46292,-45855,-45404,-44940,-44462,-43970,-43465,-42947,-42416,-41871,-41314,
29
                           -40745,-40163,-39568,-38962,-38344,-37714,-37073,-36420,-35756,-35082,-34396,-33700,-32994,-32278,
30
                           -31552,-30817,-30072,-29318,-28555,-27783,-27003,-26214,-25418,-24614,-23802,-22983,-22157,-21325,
31
                           -20485,-19640,-18789,-17932,-17069,-16201,-15329,-14451,-13570,-12684,-11794,-10901,-10004,-9104,-8202,
32
                           -7297,-6389,-5480,-4569,-3657,-2744,-1830,-915,-0};
33
34
35
36
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
37
{
38
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
39
  
40
  SP0DR = myValue; /* Data goes to SPI data register*/
41
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
42
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
43
}
44
45
void VValueTo18BitDAC(double VoltValue)
46
{
47
  unsigned long DACValue = 0;
48
  unsigned char mylowbyte = 0x00;
49
  unsigned char mymidbyte = 0x00;
50
  unsigned char myhighbyte = 0x00;
51
52
  DACValue = VoltValue;
53
54
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
55
56
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
57
  DACValue = DACValue >> 8; /* shift the next Byte into position */
58
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
59
  DACValue = DACValue >> 8; /* shift the next Byte into position */
60
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
61
62
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
63
64
  if (VoltValue <= 0x1ffff) /* Check for Halfrange */
65
  {
66
    myhighbyte |= 0x08;   /* to be able to set the MSB */
67
  }
68
69
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
70
71
  PORTS &= ~0x80;  /* /SS output low */
72
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
73
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
74
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
75
  PORTS |= 0x80;    /* /SS output high */
76
}
77
78
main()
79
{ 
80
  int i = 0;
81
  int GradZaehler = 0;
82
  double myVValue = 0;  
83
  
84
  /* Init for SPI Interface */
85
  PORTS |= 0x80;
86
  DDRS = DDRS | 0xF0; /* outputs */
87
  SP0CR1 = 0x58; /* 0b01011000 */
88
  SP0CR2 = 0; /* Normal mode */
89
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
90
91
  /* Init to the DAC */
92
  PORTS &= ~0x80;  /* /SS output low */
93
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
94
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
95
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
96
  PORTS |= 0x80;    /* /SS output high */
97
98
  while (i>0) /* Endles Data sending for testing only */
99
  { 
100
    
101
    myVValue = (2.5 / DACStepWidth) + SinusWerte[GradZaehler++];    
102
    VValueTo18BitDAC(myVValue);
103
    if (GradZaehler > 360)
104
    {
105
       GradZaehler = 0;
106
    }
107
  }
108
109
110
  
111
  return 0;    
112
}


Läuft net wie es soll??? Habe mein Programm an den entsprechenden 
Stellen ausgebessert... keine Fehler gemeldet... kannst du nochmal 
drüber schauen, dass auch alles stimmt?

Oben Screen vom Oszi....

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

SP0BR = 0x03; /* 0,5 MHz SPI clock */ :)

mom im Anhang mal die Tabelle: zum Nachschauen... ;)

von Frank S. (franksanderdo)


Lesenswert?

Hallo Jochen,

kannst Du bitte mal den Printf code in das Programm stricken und 
folgenden sprintf:
Tut mich mal interessieren wo ich mich da verrechne.
1
...
2
char mycharacterarray[128]; /* This is a 128 characters long array */
3
...
4
5
  while (i>0) /* Endles Data sending for testing only */
6
  { 
7
    
8
    myVValue = (2.5 / DACStepWidth) + SinusWerte[GradZaehler++];    
9
10
    sprintf(mycharacterarray,"myValue: %f  GradZaehler %i",myValue,GradZaehler);
11
    sci0_puts(mycharacterarray);   
12
    
13
    VValueTo18BitDAC(myVValue);
14
    if (GradZaehler > 360)
15
    {
16
       GradZaehler = 0;
17
    }
18
  }

von J. R. (cia_man)


Lesenswert?

Schlechte Nachrichten:

Das Programm gibt gar nichts aus!
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4
5
6
#define RDRF 0x20   // Receive Data Register Full Bit
7
#define TDRE 0x80   // Transmit Data Register Empty Bit
8
9
10
const double HalfRange = 2.5;
11
const double DACStepWidth = 5.0 / 0x03ffff;
12
13
const long SinusWerte[] = {0,915,1830,2744,3657,4569,5480,6389,7297,8202,9104,10004,10901,11794,12684,13570,14451,15329,
14
                           16201,17069,17932,18789,19640,20485,21325,22157,22983,23802,24614,25418,26214,27003,27783,
15
                           28555,29318,30072,30817,31552,32278,32994,33700,34396,35082,35756,36420,37073,37714,38344,38962,
16
                           39568,40163,40745,41314,41871,42416,42947,43465,43970,44462,44940,45404,45855,46292,46714,47123,
17
                           47516,47896,48261,48611,48946,49267,49572,49863,50138,50398,50642,50871,51085,51283,51465,51632,51783,
18
                           51918,52038,52141,52229,52301,52357,52397,52421,52429,52421,52397,52357,52301,52229,52141,52038,
19
                           51918,51783,51632,51465,51283,51085,50871,50642,50398,50138,49863,49572,49267,48946,48611,48261,
20
                           47896,47516,47123,46714,46292,45855,45404,44940,44462,43970,43465,42947,42416,41871,41314,40745,
21
                           40163,39568,38962,38344,37714,37073,36420,35756,35082,34396,33700,32994,32278,31552,30817,30072,
22
                           29318,28555,27783,27003,26214,25418,24614,23802,22983,22157,21325,20485,19640,18789,17932,17069,
23
                           16201,15329,14451,13570,12684,11794,10901,10004,9104,8202,7297,6389,5480,4569,3657,2744,1830,915,0,
24
                           -915,-1830,-2744,-3657,-4569,-5480,-6389,-7297,-8202,-9104,-10004,-10901,-11794,-12684,-13570,-14451,
25
                           -15329,-16201,-17069,-17932,-18789,-19640,-20485,-21325,-22157,-22983,-23802,-24614,-25418,-26214,
26
                           -27003,-27783,-28555,-29318,-30072,-30817,-31552,-32278,-32994,-33700,-34396,-35082,-35756,-36420,
27
                           -37073,-37714,-38344,-38962,-39568,-40163,-40745,-41314,-41871,-42416,-42947,-43465,-43970,-44462,
28
                           -44940,-45404,-45855,-46292,-46714,-47123,-47516,-47896,-48261,-48611,-48946,-49267,-49572,-49863,
29
                           -50138,-50398,-50642,-50871,-51085,-51283,-51465,-51632,-51783,-51918,-52038,-52141,-52229,-52301,
30
                           -52357,-52397,-52421,-52429,-52421,-52397,-52357,-52301,-52229,-52141,-52038,-51918,-51783,-51632, 
31
               -51465,-51283,-51085,-50871,-50642,-50398,-50138,-49863,-49572,-49267,-48946,-48611,-48261,-47896,
32
                           -47516,-47123,-46714,-46292,-45855,-45404,-44940,-44462,-43970,-43465,-42947,-42416,-41871,-41314,
33
                           -40745,-40163,-39568,-38962,-38344,-37714,-37073,-36420,-35756,-35082,-34396,-33700,-32994,-32278,
34
                           -31552,-30817,-30072,-29318,-28555,-27783,-27003,-26214,-25418,-24614,-23802,-22983,-22157,-21325,
35
                           -20485,-19640,-18789,-17932,-17069,-16201,-15329,-14451,-13570,-12684,-11794,-10901,-10004,-9104,-8202,
36
                           -7297,-6389,-5480,-4569,-3657,-2744,-1830,-915,-0};
37
               
38
void sci0_init(void)
39
{
40
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
41
    SC0BDL=26; // MCLK/(16*BaudRate)
42
    SC0CR1=0;
43
    SC0CR2=0x0C; //TE+RE enable
44
}
45
46
void sci0_putc(char data)
47
{
48
   while ((SC0SR1 & TDRE) == 0){};
49
   SC0DRL = data;
50
}
51
52
void sci0_puts(char* data)
53
{
54
   while (*data)
55
       sci0_putc(*data++);
56
}
57
58
               
59
60
61
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
62
{
63
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
64
  
65
  SP0DR = myValue; /* Data goes to SPI data register*/
66
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
67
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
68
}
69
70
void VValueTo18BitDAC(double VoltValue)
71
{
72
  unsigned long DACValue = 0;
73
  unsigned char mylowbyte = 0x00;
74
  unsigned char mymidbyte = 0x00;
75
  unsigned char myhighbyte = 0x00;
76
77
  DACValue = VoltValue;
78
79
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
80
81
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
82
  DACValue = DACValue >> 8; /* shift the next Byte into position */
83
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
84
  DACValue = DACValue >> 8; /* shift the next Byte into position */
85
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
86
87
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
88
89
  if (VoltValue <= 0x1ffff) /* Check for Halfrange */
90
  {
91
    myhighbyte |= 0x08;   /* to be able to set the MSB */
92
  }
93
94
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
95
96
  PORTS &= ~0x80;  /* /SS output low */
97
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
98
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
99
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
100
  PORTS |= 0x80;    /* /SS output high */
101
}
102
103
main()
104
{ 
105
  int i = 0;
106
  int GradZaehler = 0;
107
  double myVValue = 0;  
108
  
109
  char mycharacterarray[128]; /* This is a 128 characters long array */
110
  
111
  /* Init for SPI Interface */
112
  PORTS |= 0x80;
113
  DDRS = DDRS | 0xF0; /* outputs */
114
  SP0CR1 = 0x58; /* 0b01011000 */
115
  SP0CR2 = 0; /* Normal mode */
116
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
117
118
  /* Init to the DAC */
119
  PORTS &= ~0x80;  /* /SS output low */
120
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
121
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
122
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
123
  PORTS |= 0x80;    /* /SS output high */
124
125
  while (i>0) /* Endles Data sending for testing only */
126
  { 
127
    
128
    myVValue = (2.5 / DACStepWidth) + SinusWerte[GradZaehler++];    
129
   
130
    sprintf(mycharacterarray,"myVValue: %f  GradZaehler %i",myVValue,GradZaehler);
131
    sci0_puts(mycharacterarray);   
132
    
133
    VValueTo18BitDAC(myVValue);
134
    if (GradZaehler > 360)
135
    {
136
       GradZaehler = 0;
137
    }
138
  }
139
140
141
  
142
  return 0;    
143
}


:(

von Frank S. (franksanderdo)


Lesenswert?

lol stimmt!!!

schau mal auf den Wert i und unter welche Bedingung die while Schleife 
rennt ;)
Korrigier das bitte mal, da habe ich irgendwas verdreht :-(

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Verbessert! ;)

00>g 4000
Executing 4000...myVValue: 131071.5  GradZaehler 1myVValue: 131986.5 
GradZaehler 2myVValue: 132901.5  GradZaehler 3myVValue: 13
3815.5  GradZaehler 4myVValue: 134728.5  GradZaehler 5myVValue: 135640.5 
GradZaehler 6myVValue: 136551.5  GradZaehler 7myVValue
: 137460.5  GradZaehler 8myVValue: 138368.5  GradZaehler 9myVValue: 
139273.5  GradZaehler 10myVValue: 140175.5  GradZaehler 11my
VValue: 141075.5  GradZaehler 12myVValue: 141972.5  GradZaehler 
13myVValue: 142865.5  GradZaehler 14myVValue: 143755.5  GradZaeh
ler 15myVValue: 144641.5  GradZaehler 16myVValue: 145522.5  GradZaehler 
17myVValue: 146400.5  GradZaehler 18myVValue: 147272.5
GradZaehler 19myVValue: 148140.5  GradZaehler 20myVValue: 149003.5 
GradZaehler 21myVValue: 149860.5  GradZaehler 22myVValue: 15
0711.5  GradZaehler 23myVValue: 151556.5  GradZaehler 24myVValue: 
152396.5  GradZaehler 25myVValue: 153228.5  GradZaehler 26myVV
alue: 154054.5  GradZaehler 27myVValue: 154873.5  GradZaehler 
28myVValue: 155685.5  GradZaehler 29myVValue: 156489.5  GradZaehle
r 30myVValue: 157285.5  GradZaehler 31myVValue: 158074.5  GradZaehler 
32myVValue: 158854.5  GradZaehler 33myVValue: 159626.5  Gr
adZaehler 34myVValue: 160389.5  GradZaehler 35myVValue: 161143.5 
GradZaehler 36myVValue: 161888.5  GradZaehler 37myVValue: 1626
23.5  GradZaehler 38myVValue: 163349.5  GradZaehler 39myVValue: 164065.5 
GradZaehler 40myVValue: 164771.5  GradZaehler 41myVVal
ue: 165467.5  GradZaehler 42myVValue: 166153.5  GradZaehler 43myVValue: 
166827.5  GradZaehler 44myVValue: 167491.5  GradZaehler
45myVValue: 168144.5  GradZaehler 46myVValue: 168785.5  GradZaehler 
47myVValue: 169415.5  GradZaehler 48myVValue: 170033.5  Grad
Zaehler 49myVValue: 170639.5  GradZaehler 50myVValue: 171234.5 
GradZaehler 51myVValue: 171816.5  GradZaehler 52myVValue: 172385
.5  GradZaehler 53myVValue: 172942.5  GradZaehler 54myVValue: 173487.5 
GradZaehler 55myVValue: 174018.5  GradZaehler 56myVValue
: 174536.5  GradZaehler 57myVValue: 175041.5  GradZaehler 58myVValue: 
175533.5  GradZaehler 59myVValue: 176011.5  GradZaehler 60
myVValue: 176475.5  GradZaehler 61myVValue: 176926.5  GradZaehler 
62myVValue: 177363.5  GradZaehler 63myVValue: 177785.5  GradZa
ehler 64myVValue: 178194.5  GradZaehler 65myVValue: 178587.5 
GradZaehler 66myVValue: 178967.5  GradZaehler 67myVValue: 179332.5
  GradZaehler 68myVValue: 179682.5  GradZaehler 69myVValue: 180017.5 
GradZaehler 70myVValue: 180338.5  GradZaehler 71myVValue:
180643.5  GradZaehler 72myVValue: 180934.5  GradZaehler 73myVValue: 
181209.5  GradZaehler 74myVValue: 181469.5  GradZaehler 75my
VValue: 181713.5  GradZaehler 76myVValue: 181942.5  GradZaehler 
77myVValue: 182156.5  GradZaehler 78myVValue: 182354.5  GradZaeh
ler 79myVValue: 182536.5  GradZaehler 80myVValue: 182703.5  GradZaehler 
81myVValue: 182854.5  GradZaehler 82myVValue: 182989.5
GradZaehler 83myVValue: 183109.5  GradZaehler 84myVValue: 183212.5 
GradZaehler 85myVValue: 183300.5  GradZaehler 86myVValue: 18
3372.5  GradZaehler 87myVValue: 183428.5  GradZaehler 88myVValue: 
183468.5  GradZaehler 89myVValue: 183492.5  GradZaehler 90myVV
alue: 183500.5  GradZaehler 91myVValue: 183492.5  GradZaehler 
92myVValue: 183468.5  GradZaehler 93myVValue: 183428.5  GradZaehle
r 94myVValue: 183372.5  GradZaehler 95myVValue: 183300.5  GradZaehler 
96myVValue: 183212.5  GradZaehler 97myVValue: 183109.5  Gr
adZaehler 98myVValue: 182989.5  GradZaehler 99myVValue: 182854.5 
GradZaehler 100myVValue: 182703.5  GradZaehler 101myVValue: 18
2536.5  GradZaehler 102myVValue: 182354.5  GradZaehler 103myVValue: 
182156.5  GradZaehler 104myVValue: 181942.5  GradZaehler 105
myVValue: 181713.5  GradZaehler 106myVValue: 181469.5  GradZaehler 
107myVValue: 181209.5  GradZaehler 108myVValue: 180934.5  Gra
dZaehler 109myVValue: 180643.5  GradZaehler 110myVValue: 180338.5 
GradZaehler 111myVValue: 180017.5  GradZaehler 112myVValue: 1
79682.5  GradZaehler 113myVValue: 179332.5  GradZaehler 114myVValue: 
178967.5  GradZaehler 115myVValue: 178587.5  GradZaehler 11
6myVValue: 178194.5  GradZaehler 117myVValue: 177785.5  GradZaehler 
118myVValue: 177363.5  GradZaehler 119myVValue: 176926.5  Gr
adZaehler 120myVValue: 176475.5  GradZaehler 121myVValue: 176011.5 
GradZaehler 122myVValue: 175533.5  GradZaehler 123myVValue:
175041.5  GradZaehler 124myVValue: 174536.5  GradZaehler 125myVValue: 
174018.5  GradZaehler 126myVValue: 173487.5  GradZaehler 1
27myVValue: 172942.5  GradZaehler 128myVValue: 172385.5  GradZaehler 
129myVValue: 171816.5  GradZaehler 130myVValue: 171234.5  G
radZaehler 131myVValue: 170639.5  GradZaehler 132myVValue: 170033.5 
GradZaehler 133myVValue: 169415.5  GradZaehler 134myVValue:
 168785.5  GradZaehler 135myVValue: 168144.5  GradZaehler 136myVValue: 
167491.5  GradZaehler 137myVValue: 166827.5  GradZaehler
138myVValue: 166153.5  GradZaehler 139myVValue: 165467.5  GradZaehler 
140myVValue: 164771.5  GradZaehler 141myVValue: 164065.5
GradZaehler 142myVValue: 163349.5  GradZaehler 143myVValue: 162623.5 
GradZaehler 144myVValue: 161888.5  GradZaehler 145myVValue
: 161143.5  GradZaehler 146myVValue: 160389.5  GradZaehler 147myVValue: 
159626.5  GradZaehler 148myVValue: 158854.5  GradZaehler
 149myVValue: 158074.5  GradZaehler 150myVValue: 157285.5  GradZaehler 
151myVValue: 156489.5  GradZaehler 152myVValue: 155685.5
 GradZaehler 153myVValue: 154873.5  GradZaehler 154myVValue: 154054.5 
GradZaehler 155myVValue: 153228.5  GradZaehler 156myVValu
e: 152396.5  GradZaehler 157myVValue: 151556.5  GradZaehler 158myVValue: 
150711.5  GradZaehler 159myVValue: 149860.5  GradZaehle
r 160myVValue: 149003.5  GradZaehler 161myVValue: 148140.5  GradZaehler 
162myVValue: 147272.5  GradZaehler 163myVValue: 146400.5
  GradZaehler 164myVValue: 145522.5  GradZaehler 165myVValue: 144641.5 
GradZaehler 166myVValue: 143755.5  GradZaehler 167myVVal
ue: 142865.5  GradZaehler 168myVValue: 141972.5  GradZaehler 
169myVValue: 141075.5  GradZaehler 170myVValue: 140175.5  GradZaehl
er 171myVValue: 139273.5  GradZaehler 172myVValue: 138368.5  GradZaehler 
173myVValue: 137460.5  GradZaehler 174myVValue: 136551.
5  GradZaehler 175myVValue: 135640.5  GradZaehler 176myVValue: 134728.5 
GradZaehler 177myVValue: 133815.5  GradZaehler 178myVVa
lue: 132901.5  GradZaehler 179myVValue: 131986.5  GradZaehler 
180myVValue: 131071.5  GradZaehler 181myVValue: 130156.5  GradZaeh
ler 182myVValue: 129241.5  GradZaehler 183myVValue: 128327.5 
GradZaehler 184myVValue: 127414.5  GradZaehler 185myVValue: 126502
.5  GradZaehler 186myVValue: 125591.5  GradZaehler 187myVValue: 124682.5 
GradZaehler 188myVValue: 123774.5  GradZaehler 189myVV
alue: 122869.5  GradZaehler 190myVValue: 121967.5  GradZaehler 
191myVValue: 121067.5  GradZaehler 192myVValue: 120170.5  GradZae
hler 193myVValue: 119277.5  GradZaehler 194myVValue: 118387.5 
GradZaehler 195myVValue: 117501.5  GradZaehler 196myVValue: 11662
0.5  GradZaehler 197myVValue: 115742.5  GradZaehler 198myVValue: 
114870.5  GradZaehler 199myVValue: 114002.5  GradZaehler 200myV
Value: 113139.5  GradZaehler 201myVValue: 112282.5  GradZaehler 
202myVValue: 111431.5  GradZaehler 203myVValue: 110586.5  GradZa
ehler 204myVValue: 109746.5  GradZaehler 205myVValue: 108914.5 
GradZaehler 206myVValue: 108088.5  GradZaehler 207myVValue: 1072
69.5  GradZaehler 208myVValue: 106457.5  GradZaehler 209myVValue: 
105653.5  GradZaehler 210myVValue: 104857.5  GradZaehler 211my
VValue: 104068.5  GradZaehler 212myVValue: 103288.5  GradZaehler 
213myVValue: 102516.5  GradZaehler 214myVValue: 101753.5  GradZ
aehler 215myVValue: 100999.5  GradZaehler 216myVValue: 100254.5 
GradZaehler 217myVValue: 99519.5  GradZaehler 218myVValue: 9879
3.5  GradZaehler 219myVValue: 98077.5  GradZaehler 220myVValue: 97371.5 
GradZaehler 221myVValue: 96675.5  GradZaehler 222myVVal
ue: 95989.5  GradZaehler 223myVValue: 95315.5  GradZaehler 224myVValue: 
94651.5  GradZaehler 225myVValue: 93998.5  GradZaehler 2
26myVValue: 93357.5  GradZaehler 227myVValue: 92727.5  GradZaehler 
228myVValue: 92109.5  GradZaehler 229myVValue: 91503.5  GradZ
aehler 230myVValue: 90908.5  GradZaehler 231myVValue: 90326.5 
GradZaehler 232myVValue: 89757.5  GradZaehler 233myVValue: 89200.
5  GradZaehler 234myVValue: 88655.5  GradZaehler 235myVValue: 88124.5 
GradZaehler 236myVValue: 87606.5  GradZaehler 237myVValue
: 87101.5  GradZaehler 238myVValue: 86609.5  GradZaehler 239myVValue: 
86131.5  GradZaehler 240myVValue: 85667.5  GradZaehler 241
myVValue: 85216.5  GradZaehler 242myVValue: 84779.5  GradZaehler 
243myVValue: 84357.5  GradZaehler 244myVValue: 83948.5  GradZae
hler 245myVValue: 83555.5  GradZaehler 246myVValue: 83175.5  GradZaehler 
247myVValue: 82810.5  GradZaehler 248myVValue: 82460.5
 GradZaehler 249myVValue: 82125.5  GradZaehler 250myVValue: 81804.5 
GradZaehler 251myVValue: 81499.5  GradZaehler 2ÿ

So und oben auch der passende Screenshot ;) Juhuuu!!! Aber die Peaks :(

Oszi hat Bild leicht verschoben beim Hardcopy ;)

von Frank S. (franksanderdo)


Lesenswert?

ok kannst die textausgabe wieder raus nehmen ;-)

von Frank S. (franksanderdo)


Lesenswert?

Dann werden wir uns mal den Peaks widmen.

Kannst Du mal mit dem Oscar spielen das wir uns so einen Peak geaneur 
anschauen können?
Also den Peak vergößern

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4
5
6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8
9
const long SinusWerte[] = {0,915,1830,2744,3657,4569,5480,6389,7297,8202,9104,10004,10901,11794,12684,13570,14451,15329,
10
                           16201,17069,17932,18789,19640,20485,21325,22157,22983,23802,24614,25418,26214,27003,27783,
11
                           28555,29318,30072,30817,31552,32278,32994,33700,34396,35082,35756,36420,37073,37714,38344,38962,
12
                           39568,40163,40745,41314,41871,42416,42947,43465,43970,44462,44940,45404,45855,46292,46714,47123,
13
                           47516,47896,48261,48611,48946,49267,49572,49863,50138,50398,50642,50871,51085,51283,51465,51632,51783,
14
                           51918,52038,52141,52229,52301,52357,52397,52421,52429,52421,52397,52357,52301,52229,52141,52038,
15
                           51918,51783,51632,51465,51283,51085,50871,50642,50398,50138,49863,49572,49267,48946,48611,48261,
16
                           47896,47516,47123,46714,46292,45855,45404,44940,44462,43970,43465,42947,42416,41871,41314,40745,
17
                           40163,39568,38962,38344,37714,37073,36420,35756,35082,34396,33700,32994,32278,31552,30817,30072,
18
                           29318,28555,27783,27003,26214,25418,24614,23802,22983,22157,21325,20485,19640,18789,17932,17069,
19
                           16201,15329,14451,13570,12684,11794,10901,10004,9104,8202,7297,6389,5480,4569,3657,2744,1830,915,0,
20
                           -915,-1830,-2744,-3657,-4569,-5480,-6389,-7297,-8202,-9104,-10004,-10901,-11794,-12684,-13570,-14451,
21
                           -15329,-16201,-17069,-17932,-18789,-19640,-20485,-21325,-22157,-22983,-23802,-24614,-25418,-26214,
22
                           -27003,-27783,-28555,-29318,-30072,-30817,-31552,-32278,-32994,-33700,-34396,-35082,-35756,-36420,
23
                           -37073,-37714,-38344,-38962,-39568,-40163,-40745,-41314,-41871,-42416,-42947,-43465,-43970,-44462,
24
                           -44940,-45404,-45855,-46292,-46714,-47123,-47516,-47896,-48261,-48611,-48946,-49267,-49572,-49863,
25
                           -50138,-50398,-50642,-50871,-51085,-51283,-51465,-51632,-51783,-51918,-52038,-52141,-52229,-52301,
26
                           -52357,-52397,-52421,-52429,-52421,-52397,-52357,-52301,-52229,-52141,-52038,-51918,-51783,-51632, 
27
               -51465,-51283,-51085,-50871,-50642,-50398,-50138,-49863,-49572,-49267,-48946,-48611,-48261,-47896,
28
                           -47516,-47123,-46714,-46292,-45855,-45404,-44940,-44462,-43970,-43465,-42947,-42416,-41871,-41314,
29
                           -40745,-40163,-39568,-38962,-38344,-37714,-37073,-36420,-35756,-35082,-34396,-33700,-32994,-32278,
30
                           -31552,-30817,-30072,-29318,-28555,-27783,-27003,-26214,-25418,-24614,-23802,-22983,-22157,-21325,
31
                           -20485,-19640,-18789,-17932,-17069,-16201,-15329,-14451,-13570,-12684,-11794,-10901,-10004,-9104,-8202,
32
                           -7297,-6389,-5480,-4569,-3657,-2744,-1830,-915,-0};
33
               
34
         
35
36
37
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
38
{
39
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
40
  
41
  SP0DR = myValue; /* Data goes to SPI data register*/
42
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
43
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
44
}
45
46
void VValueTo18BitDAC(double VoltValue)
47
{
48
  unsigned long DACValue = 0;
49
  unsigned char mylowbyte = 0x00;
50
  unsigned char mymidbyte = 0x00;
51
  unsigned char myhighbyte = 0x00;
52
53
  DACValue = VoltValue;
54
55
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
56
57
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
58
  DACValue = DACValue >> 8; /* shift the next Byte into position */
59
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
60
  DACValue = DACValue >> 8; /* shift the next Byte into position */
61
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
62
63
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
64
65
  if (VoltValue <= 0x1ffff) /* Check for Halfrange */
66
  {
67
    myhighbyte |= 0x08;   /* to be able to set the MSB */
68
  }
69
70
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
71
72
  PORTS &= ~0x80;  /* /SS output low */
73
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
74
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
75
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
76
  PORTS |= 0x80;    /* /SS output high */
77
}
78
79
main()
80
{ 
81
  int i = 1;
82
  int GradZaehler = 0;
83
  double myVValue = 0;  
84
  
85
  
86
  /* Init for SPI Interface */
87
  PORTS |= 0x80;
88
  DDRS = DDRS | 0xF0; /* outputs */
89
  SP0CR1 = 0x58; /* 0b01011000 */
90
  SP0CR2 = 0; /* Normal mode */
91
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
92
93
  /* Init to the DAC */
94
  PORTS &= ~0x80;  /* /SS output low */
95
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
96
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
97
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
98
  PORTS |= 0x80;    /* /SS output high */
99
100
  while (i>0) /* Endles Data sending for testing only */
101
  { 
102
    
103
    myVValue = (2.5 / DACStepWidth) + SinusWerte[GradZaehler++];    
104
    
105
    VValueTo18BitDAC(myVValue);
106
    if (GradZaehler > 360)
107
    {
108
       GradZaehler = 0;
109
    }
110
  }
111
112
113
  
114
  return 0;    
115
}

Version ohne Printf!! ;) Screenshots oben!

von Frank S. (franksanderdo)


Lesenswert?

Stell mal nur eine Halbwelle auf dem Oscar dar

Ich will sicher stellen das es wirklich der 0 Durchlaf ist. Sieht mir 
aber ganz feste danach aus.

da tun wir mal folgende Zeile ändern:

  if (VoltValue <= 0x1ffff) /* Check for Halfrange */

wird

  if (VoltValue < 0x1ffff) /* Check for Halfrange */

von J. R. (cia_man)


Angehängte Dateien:

Lesenswert?

Peak in nah! Ich muss nun leider für heute Schluss machen! Hab noch 
etwas anderes zu erledigen das wichtiger ist ;) Arbeit :(

Moin geht's  von meiner Seite hier weiter!

Gruß & Danke

von Frank S. (franksanderdo)


Lesenswert?

Ach ja ich wüsste noch gerne wie schnell wir jetzt können.
Ergo mach mal den SPI schneller ;)

von Frank S. (franksanderdo)


Lesenswert?

Ok dann schaff mal ne Runde.

Ich werde heute Nacht noch mal ein wenig stricken ;-)

Grüße
Frank

von Frank S. (franksanderdo)


Lesenswert?

Hallo APW

kannst Du mir bitte deine e-mail via PN schicken?
Ich hatte gestern ein längeres Gespräch mit Jochen und wir würden Dich 
gerne auch informieren, aber nicht unbedingt hier ;-)

Dank Dir

Grüße
Frank

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.