PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Spannungseingang EC-Motor Steuerung mittels DAC8550



gesamtplan
30.06.2009, 21:57
Hallo,

ich habe einen guten und günstigen Papst Aussenläufer erstanden. Leider hat das Ding zur Drehzahlregelung nur einen Spannungseingang. Ich würde den Motor gerne mit einem ATMEGA8 ansteuern. Jetzt stellt sich mir die Frage wie mach ich das am dümmsten.

Meine Idee war einen DAC zu benutzen, welchen ich über SPI ansteuere. Zu diesem Zweck hab ich mir einen DAC 8550 http://focus.ti.com/lit/ds/symlink/dac8550.pdf
besorgt und für DIL brauchbar gemacht. Allerdings werde ich nicht ganz schlau wie ich den ansteuern soll.

Als Referenzspannung hab ich zum Testen die 5V von VDD genommen und Vout direkt mit Vfb rückgekoppelt um den Operationsverstärker zu beschicken.

Ich habe das Teil über das SPI Interface angeschlossen und über Bascom mal was rübergeschickt. Leider steht der Vout auf 2,5 V und es rührt sich nix wenn ich Daten rübersende. Hab mit dem Oszi auch schon nachgeguckt ob das SPI Interface auch Daten schickt und das scheint zu passen. Leider verstehe ich nicht ganz was ich genau schicken soll, da hier ja irgendwie 16 Bit geschickt werden sollen. Ich weiß auch nicht warum am Ausgang wenn über das Interface nix kommt 2,5V anliegen.

Ich programmieren in Bascom und wäre über etwas Hilfe sehr erfreut.

BASTIUniversal
01.07.2009, 12:08
Hi!
Vielleicht solltest du mal deinen bisherigen Bascom-Code posten, sonst ist es schwer, dir zu helfen. Wichtig ist vor allem die Konfiguration der SPI-Schnittstelle und das, was du sendest.
Laut Datenblatt hat dein DAC ein SPI-Kompatibles Interface, das 24 Bits (also 3 Bytes) erwartet (MSB First). Die ersten 6 Bits des ersten Bytes sind egal, die letzten 2 Bits entscheiden über den Power Down Modus. Die verschiedenen Modi findest du im Datenblatt auf Seite 17.
Die dann folgenden 2 Bytes entscheiden über die Ausgangsspannung. Sendet man eine 0, dann beträgt die Ausgangsspannung genau die Hälfte von VRef. Bei -32768 ist sie 0, bei +32768 ist sie VRef.
Das schreiben in das Register des DAC beginnt, wenn der Pegel an Sync auf Low-Level gezogen wird. Bevor man ein zweites mal schreiben kann, muss der Pegel an Sync kurz auf High gezogen werden. Da die Sync-Leitung während der ganzen Schreibaktion auf Low liegen muss, muss man die Leitung manuell steuern (also das Automatische Slave Select abschalten).
Mit jeder fallenden Flanke an SCLK wird das Bit ins Register übernommen, das gerade an Din anliegt. Nach der 24sten Flanke (also wenn alle 3 Bytes im Register sind) wird die neue Einstellung übernommen und die neue Spannung wird generiert.
Netterweise scheint das SPI-System des Mega kompatibel mit dem vom 68HC11 zu sein. Für den stehen weiter unten die nötigen Einstellungen (CPOL = 0 und CPHA = 1).

Deine Einstellung in Bascom sollten also ungefähr so aussehen:

Config SPI = Hard, Interrupt = Off, Data Order = MSB, Master = Yes, Polarity = Low, Phase = 1, Clockrate = 4, Noss = 1

SPIINIT

Set Portb.5 (an Portb.5 kommt dann Sync)
waitms 1
Reset Portb.5

SPIOUT &B0000 0000
Waitms 1
SPIOUT &B1101 1000
waitms 1
SPIOUT &B1111 0000


Das müsste dem Wert -10.000 entsprechen (Integer) und demnach einer Ausgangsspannung von etwa 1,74V entsprechen.
Kann natürlich auch sein, dass sich da jetzt irgendwo ein Fehler drin versteckt...einfach selber noch mal nachlesen (Datenblatt ist eigentlich leicht verständlich) und ausprobieren.
Eventuell noch mal die Verkabelung checken (MOSI kommt an Din).

MfG
Basti

gesamtplan
01.07.2009, 17:29
So ich hab jetzt mal folgendes probiert.
Portb.1 ist der Sync also Set macht dann wohl den Port low und reset den port wieder hight oder verstehe ich da was falsch. Die Variable a b und c beinhalten die Bytes die geschickt werden sollen.



Dim Var As Byte
'Dim Opto As Bit
'Config Pinc.5 = Output
'Config Pinc.4 = Output

Config Int0 = Falling
Config Timer1 = Timer , Prescale = 256
Const Timervorgabe = 36735 'Berechnung von einer 1s 36735=1s 7935=2s
Const Markierungenproscheibe = 6 '6 Impulse Papst 8 Impulse Scheibe
Const Messzeit = 1 'Messzeit in s
Dim Zaehlerirq0 As Long
Dim Impulseprosekunde As Long
Dim Impulseprominute As Long
Dim Umdrehungenprominute As Integer
Dim Y As Byte
Dim X As Byte
Dim A As Byte
Dim B As Byte
Dim C As Byte
A = &B00000000
B = &B11011000
C = &B11110000

'Config Spi = Soft , Dout = Pinb.1 , Ss = Pinb.2 , Clock = Pinb.5
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 1 , Clockrate = 4 , Noss = 1
Spiinit
.... codeschnipsel zum Auswerten der Drehzahl durch Impulsgeber und per Knopfdruck ins Unterprogramm hüpfen

Countup:
Var = Var + 10
'X = X + 10
Set Portb.1
Waitms 1
Spiout A , 1
Waitms 1
Spiout B , 1
Waitms 1
Spiout C , 1
Waitms 1
Reset Portb.1
Return

Countdown:
Var = Var - 10
'X = X + 10
Set Portb.1
Waitms 1
Spiout A , 1
Waitms 1
Spiout B , 1
Waitms 1
Spiout C , 1
Waitms 1
Reset Portb.1
Return


Count up und down werden über den Debounce Befehler ausgelöst

An Portb1 hängt mein SYNC, das SCK hängt am Portb.5 und an Portb.3 hängt Din.

So wies aussieht kommt nicht mal was an wenn ich auf den Knopf drücke


Ich habe festgestellt beim programmieren stellt sich ab und an mal der Spannungswert um, da bekommt der DAC wohl was vom verifizieren des ISP Programmers mit.

gesamtplan
01.07.2009, 18:42
So jetzt scheints zu funktionieren.



Dim A As Byte
Dim B As Byte
Dim C As Byte
A = &B00000000
B = &B11011000
C = &B11110000

Config Spi = Soft , Dout = Pinb.3 , Ss = None , Clock = Pinb.5

Reset Portb.1
'Waitms 1
Spiout A , 1
'Waitms 1
Spiout B , 1
'Waitms 1
Spiout C , 1
'Waitms 1
Set Portb.1



Portb.1 ist für das freischalten der Übertraung zuständig. Wenn ich das Programm starte kommen 1,78 irgendwas Volt an Vout. Beim neustarten des Atmel liegen 2,5 V an. Jetzt muss ich mir nur noch ne Zählweise überlegen damit ich B und C befüttern kann von -32... bis +32... Wie setzt man da an?

Viele Grüße und Danke

BASTIUniversal
02.07.2009, 10:35
Hi!
Freut mich, dass es funktioniert!
Versuchs einfach mal so:

Dim X as Integer
X = 40000
Spiout X, 1 (oder 2)

gesamtplan
04.07.2009, 10:58
Hallo,

So jetzt bin ich langsam am verzweifeln. Folgende sonderbarkeit trägt sich in meinen Microcontrollerlanden zu. Ich verstehs nicht so ganz. Ich habs jetzt soweit, dass ich an den DAC Daten schicken kann. Diese werden auch richtig interpretiert auf der Gegenstelle. Allerdings funktioniert das nicht immer. Nehme ich den µC vom Strom und stecke das Ding wieder an, wird der Wert in 90% zum DAC geschickt. Läuft der µC allerdings und ich versuche über meine Taster "Countup und Countdown" das I zu verändern passiert rein garnix am DAC. Im Display sehe ich die Werte von I sich verändern und die zwei Bytes (D1 und D2) liegen als Dezimalwert auch auf und ändern Ihre Werte ebenfalls. Nur scheint noch irgendwas in der SPI Übertragung nicht so zu tun wies soll.



' Hardware PWM mit Timer1

$regfile = "m8def.dat"
$crystal = 73728000


Dim Var As Byte
'Dim Opto As Bit
'Config Pinc.5 = Output
'Config Pinc.4 = Output

Config Int0 = Falling
Config Timer1 = Timer , Prescale = 256
Const Timervorgabe = 36735 'Berechnung von einer 1s 36735=1s 7935=2s
Const Markierungenproscheibe = 6 '6 Impulse Papst 8 Impulse Scheibe
Const Messzeit = 1 'Messzeit in s
Dim Zaehlerirq0 As Long
Dim Impulseprosekunde As Long
Dim Impulseprominute As Long
Dim Umdrehungenprominute As Integer
Dim Y As Byte
Dim X As Byte
Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim D(2) As Byte
Dim I As Integer At D Overlay

Config Spi = Soft , Dout = Pinb.3 , Ss = None , Clock = Pinb.5
Spiinit

'I = -32768
'I = 32767
I = 30000
A = &B00000000
'B = &B11011000
'C = &B11110000
'B = &B01111111 'Vollausschlag
'C = &B11111111 'Vollausschlag
B = &B10000000 '0V
C = &B00000000 '0V
'Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 1 , Clockrate = 4 , Noss = 1

'Spiinit
'Set Portb.2
'Waitms 1
'Spiout A , 1
'Waitms 1
'Spiout B , 1
'Waitms 1
'Spiout C , 1
'Waitms 1
'Reset Portb.2





'LCD Config
Config Lcd = 40 * 2
'Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.3 , Db6 = Portd.6 , Db7 = Portd.1 , E = Portd.5 , Rs = Portd.7
Config Lcdbus = 4
Config Lcdmode = Port
Initlcd
Cls


'Config Portb.1 = Output
'Config Portb.2 = Output

'Config Timer2 = Pwm , Compare Pwm = Clear Up , Prescale = 1 Pwm = On

Config Pinc.1 = Input 'Taster Schalter 1
Config Pinc.2 = Input 'Taster Schalter 2
Config Pind.2 = Input
Opto Alias Pind.2
Portd.2 = 1
Portc.1 = 1 'interner Pullup Schalter1
Portc.2 = 1
Var = 0
'Portb.0 = Opto


Zaehlerirq0 = 0
On Int0 Irq0
Enable Int0
On Timer1 Timer_irq
Enable Timer1
Enable Timer2
Enable Interrupts

'Locate 1 , 1
'Lcd "ich bin ein PULS"




Gosub Spi
'Goto 0 'Restart das Ding


Taster1 Alias Pinc.1
Taster2 Alias Pinc.2


Do
Locate 2 , 1
Lcd D(2) ; " " ; D(1)

Locate 1 , 8
Lcd I

If Taster1 = 0 Then
Gosub Countup
End If

If Taster2 = 0 Then
Gosub Countdown
End If

'If Opto = 0 Then
'Locate 1 , 1
'Lcd "0"
'Else
'Locate 1 , 1
'Lcd "1"
'End If

'Locate 2 , 1
'Lcd Impulseprosekunde

Impulseprominute = Impulseprosekunde * 60
Impulseprominute = Impulseprominute / Messzeit
Umdrehungenprominute = Impulseprominute / Markierungenproscheibe

Locate 1 , 1
Lcd Umdrehungenprominute

'Locate 2 , 10
'Lcd X



'Debounce Pinc.1 , 0 , Countup , Sub

'Debounce Pinc.2 , 0 , Countdown , Sub

'Locate 1 , 1
'Lcd "Pulsweite "
'Locate 2 , 1
'Lcd ; Var ; " Steps O:" ; Opto


'Nicht relevant 'Compare1a = Var '256 - Var
'Ocr2 = 255 - Var 'PWM 3 'Var
Loop


Countup:
I = I + 1000
Waitms 20
Gosub Spi
Return
Countdown:

I = I + 1000
Waitms 20
Gosub Spi
Return

Irq0:
Incr Zaehlerirq0
Return

Timer_irq:
Timer1 = Timervorgabe
Impulseprosekunde = Zaehlerirq0
Zaehlerirq0 = 0
Return

Spi:
Spiinit
Reset Portb.1
Spiout A , 1
Spiout D(2) , 1
Spiout D(1) , 1
Set Portb.1
Return



End



Ähnlichen Code fürs SPI Interface habe bei einem anderen Projekt mit einem PGA2320 erfolgreich im Einsatz. Dort werden 16Bit als zwei Byte geschickt und das geht auch ratz fatz...

Wo soll ich ansetzen. Ich habe das Programm auch schon für den ATMEGA16 portiert. Dort habe ich das selbe Phänomen. Kann ich nicht programmieren, oder sehe ich den Wald vor lauter Bäumen nicht? Für etwas Hilfe wäre ich sehr dankbar.

Noch eine kurze Info zur Hardware:
KC168 Testboard + Wildverkabelung auf DAC8550, welcher am Steckbrett seinen Dienst tut und über einen DIL Adapter dort fixiert ist.

Wie lang darf das Kabel fürs SPI eigentlich sein und ist es möglich, dass der EC-Motor irgendeinen Einfluss auf das ganze hat?

Wäre es sinnvoll irgenwo noch ein paar Kondensatoren zu setzen? Derzeit gibt es nur eine direkte Verbindung zwischen den Schnittstellen.

gesamtplan
04.07.2009, 19:28
So des Rätsels Lösung ist ganz einfach:

Portb.1 = Output

Zum code hinzufügen und es funktioniert.

Eine teuere Erkenntnis. Zwei Stunden suchen im Code.

Schließlich doch nochmal die Hardware durchgemessen... und siehe da Portb.1 geht nicht nach low....

Besserwessi
04.07.2009, 20:44
Für die Kontrolle eines Lüfters ist das ein reichlich überdimensionierter DAC. Es hätte wohl auch ein 8 Bit DAC gereicht.

Die Übliche Lösung wäre es ein PWM Signal zu Filtern. Enweder per RC und dann verstärken, oder auch per LC Filter mit Freilaufdiode ähnlich wie beim Schaltnetzteil.

gesamtplan
04.07.2009, 21:02
Ich würde dir zustimmen, wenn es denn ein Lüfter wäre. Nur wird das ganze wenns groß ist ein Antrieb für einen Plattenspieler mit integrierter Drehzahlregelung.Für ne Lüftersteuerung würde ich keinen solchen Aufriss veranstalten.

Aber für den Spannungseingang eines Präzessionsmotors für 200 Euros darfs auch ein DAC mit 16 Bit sein. Vor allem wenn man das Ding als Sample rumliegen hat. Lieber wäre mit der gleiche Motor mit Frequenzeingang gewesen. Den hätte man einfach über PWM befeuern können. Aber man kriegt ja nicht immer was man will...

Anbei noch ein kurzer Bildbeitrag damit man sieht für was ich den "Lüfter" brauche. ;-)

Viele Grüße

Rainer