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!
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.
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!
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
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!
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! :(
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
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
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!
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
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^^ ;)
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.
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
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
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
voidSetPortA(intnum,intlevel)
2
{
3
if(level==0){
4
PORTA&=~(1<<num);/* Output Latch auf Null setzen. */
5
DDRA|=(1<<num);/* Port-Pin als Ausgang konfigurien. */
6
}elseif(level==1){
7
DDRA&=~(1<<num);/* Port-Pin als Eingang konfigurieren, der Pullup-Widerstand stellt jetzt wieder +5V Pegel ein. */
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ß
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!
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
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!
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
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!
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
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
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
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
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
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ß
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
^^
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
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ß
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
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
voidSPIinit(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
unsignedcharSPI_trans(unsignedcharval)
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
>// 1 Slave Select active (works together with DDS7)
10
>// 0 MSB first (not LSBF)
11
>.....................
12
>.....................
13
>unsignedcharSPI_trans(unsignedcharval)
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
>returnSPIDR;// 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ß.
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
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
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
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
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!
while((SP0SR&0x80)==0);/* wait for transfer to finish */
18
19
returnSP0DR;
20
21
SP0DR=0x00;
22
23
while((SP0SR&0x80)==0);/* wait for transfer to finish */
24
25
returnSP0DR;
26
27
SP0DR=0x02;
28
29
while((SP0SR&0x80)==0);/* wait for transfer to finish */
30
31
returnSP0DR;
32
33
SP0DR=0x10;
34
35
while((SP0SR&0x80)==0);/* wait for transfer to finish */
36
37
returnSP0DR;
38
39
SP0DR=0x03;
40
41
while((SP0SR&0x80)==0);/* wait for transfer to finish */
42
43
returnSP0DR;
44
45
SP0DR=0xFC;
46
47
while((SP0SR&0x80)==0);/* wait for transfer to finish */
48
49
returnSP0DR;
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. ;)
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
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
unsignedcharmuelleimer;/* 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 ;-)
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
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ß
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!
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
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
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
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
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 ;)
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
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!
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
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
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
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
inti=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 */
@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
> 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.
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
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!
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
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
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
inti=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 */
unsignedcharmy_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!
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
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
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...
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
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
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?
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
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
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
inti=1;
19
unsignedcharmyvalue=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 */
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
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
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...
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!
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
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
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
inti=1;
18
unsignedcharmylowbyte=0x00;
19
unsignedcharmymidbyte=0x00;
20
unsignedcharmyhighbyte=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*/
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
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.
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
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
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!
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
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
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
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ß
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
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? :)
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
unsignedcharmyhighbyte=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*/
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
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? :)
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
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
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.
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
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?
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
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
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
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
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
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
inti=1;
18
unsignedcharmylowbyte=0x00;
19
unsignedcharmymidbyte=0x00;
20
unsignedcharmyhighbyte=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!!!!
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
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?
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.
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 :)
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;
}
}
}
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
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
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
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
voiddelay1ms(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
voidwait(intduration)
22
{
23
while(duration--)
24
delay1ms();
25
}
26
27
28
29
main()
30
{
31
32
inti=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 */
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!
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 ....!?!?)
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
voiddelay1ms(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
voidwait(intduration)
22
{
23
while(duration--)
24
delay1ms();
25
}
26
27
28
29
main()
30
{
31
32
inti=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
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
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ß
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
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
inti=1;
18
unsignedcharmylowbyte=0x00;
19
unsignedcharmymidbyte=0x00;
20
unsignedcharmyhighbyte=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*/
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
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
inti=1;
18
unsignedcharmylowbyte=0x00;
19
unsignedcharmymidbyte=0x00;
20
unsignedcharmyhighbyte=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!
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
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
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
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
constdoubleHalfRange=2,5;
5
constdoubleDACStepWidth=5/0x03ffff;
6
7
voidmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
8
{
9
unsignedcharmydelete;/* 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
voidVValueTo18BitDAC(doubleVoltValue)
17
{
18
unsignedlongDACValue=0;
19
unsignedcharmylowbyte=0x00;
20
unsignedcharmymidbyte=0x00;
21
unsignedcharmyhighbyte=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 */
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
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
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
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
unsignedcharmySPITrans(unsignedcharmyValue)/*Transmit Byte via SPI*/
6
{
7
unsignedcharmydelete;/* 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
voiddelay1ms(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
voidwait(intduration)
23
{
24
while(duration--)
25
delay1ms();
26
}
27
28
29
30
unsignedcharmyVorzeichenFunktion(doublezaehlen)
31
{
32
unsignedcharmyhighbytetemp;
33
intMSB=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
returnmyhighbytetemp;
54
55
}
56
57
58
59
main()
60
{
61
unsignedcharmyhighbyte;
62
inti=1;
63
doublezaehlen=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 */
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
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
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!
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
constdoubleHalfRange=2,5;
2
constdoubleDACStepWidth=5/0x03ffff;
...
Der eigentliche Wert (VoltValue) kommt als Reale Zahl an.
...
1
voidVValueTo18BitDAC(doubleVoltValue)
...
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.
...
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 ;)
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
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.
!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 ;)
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
:(
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 ;-)
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 */
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
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!
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 ;-)
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 ;-)
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