Du solltest dir das Datenblatt vom UC3 mal anschauen. Unter der Rubrik
GPIO-Controller solltest du fündig werden. Da stehen alle wichtigen
Register beschrieben.
Aber ich bin mir sicher, dass du nicht damit auskommen wirst, einfach
die #defines zu ändern. Da wirst du sicherlich noch was im Code ändern
müssen, vor allem da sich die Register vom AVR nicht 1:1 auf den AVR32
übertragen lassen.
MfG
Marius
Es gibt bereits header-Dateien, bei denen die Ports bereits alle
definiert sind. Beim Einbinden der IO-Bibliotheken kannst du sie
problemlos verwenden. Am besten du schaust dir einfach eines der
Beispiele an, die im "AVR32 Studio" bereits integriert sind.
Hi,
du musst glaube ich zuerst die avr/io.h einbinden und eine sogenannte
gpio.h, evtl. funktioniert das bei dir, bei mir hats so nicht geklappt
und ich bin noch am probieren.
Im Programm schreibst du dann einfach:
gpio_set(bzw. clear)_gpio_pin(AVR32_PIN_PA02);
Ob das funktioniert weiss ich noch nicht, da ich noch Probleme mit der
HEADERDATEI gpio.h hab.
Eine Alternative ist eine einfache Zuweisung:
PORTB=0X0001, womit eigentlich das 1. Bit gesetzt werden müsste.
Evtl. einfach mal probieren mit einer LED an 5V und einem Vorwiderstand
220 Ohm, Spannungsquelle anschließen an die LED und das 2. Ende in den
Controller.
Wenn es klappt am besten mal posten.
Gruß JO
Hi
Also ist ganz simpel
#include <avr32/io.h>
einbinden, mehr brauchst du nicht.
So es gibt 1 Register mehr bei AVR32 als bei den 8bit AVRs die du
setzten musst und das ist der GPIO enable register. Außerdem musst du
beachten das die port 32bit lang sind und nicht nur 8 bit. In dem
Beispiel enable ich mal PA0 und PA4. Dabei setzte ich PA0 auf low und
PA4 auf high.
AVR32_GPIO.port[0].gper = 0x00000011; // GPIO enable Register
mit 1 machst du den GPIO active. Die 0 in den [] steht für den Port.
0 = A, 1 = B, 2 = C
AVR32_GPIO.port[0].oder = 0x00000011; // GPIO als ausgang.
Die 0 wieder für den A PORT.
AVR32_GPIO.port[0].oder ist also DDRA
AVR32_GPIO.port[0].ovr = 0x00000010; // GPIO zustandt
So hier hab ich mit na 1 PA4 auf High gesetzt und PA0 auf low.
So ich hoffe es war gut verständlich. Fall noch fragen sind, dann
einfach posten.
Hallo Zippi,
ok, das ist soweit klar.
Und mit gpio.h sollte es so aussehen oder?
1
#define EN_PIN 0
2
#define ENABLE_LOW gpio_clr_gpio_pin(EN_PIN);
3
#define ENABLE_HIGH gpio_set_gpio_pin(EN_PIN);
4
5
gpio_enable_module_pin(EN_PIN,0);
wobei mir nicht klar ist für was der zweite Parameter 0(function a, b,
c) steht.
Wenn ich jetzt PA0-PA7 definiert habe,wie sendet man ein Byte dort hin?
Hi also der 2. Parameter 0 steht für das Modul.
Wenn du mal im Datenblatt(UC3A) auf seite 45 gehst dann siehst du unten
eine Tabelle.
12.7 Peripheral Multiplexing on I/O lines
Da kannst du die Functionen durchschalten. 0 = Function A, 1 = Function
B, 2 = Function C.
Aber so wie ich das Verstanden hab willst du die IOs schalten und keine
Function.
Zurzeit würdest du Also PA0 Auf Function USART0 - RXD setzten.
Richtig wäre:
1
#define EN_PIN 0
2
#define ENABLE_LOW gpio_clr_gpio_pin(EN_PIN);
3
#define ENABLE_HIGH gpio_set_gpio_pin(EN_PIN);
4
5
gpio_enable_gpio_pin(EN_PIN);
Wobei ich sagen muss das der GPIO mit jedem
1
gpio_set_gpio_pin(unsignedintpin);
2
gpio_clr_gpio_pin(unsignedintpin);
neu enabled wird.
Wichtig ist das du in der Tabelle schaust welchen GPIO du setzten
willst. Dort gibt es keinen definierten port. Also PORT A ist GPIO(0-31)
wobei es 31 nicht giebt warum auch immer. Und PORT B ist GPIO(32-63).
So jetzt willst du ein Byte über nen ganzen port bringen. Naja du kannst
mit der GPIO.h nur alle bits einzeln setzten. Da wäre natürlich ziemlich
beschissen. Deswegen hab ich ja das oben mit den Registern direct
erklärt.
HI ich könnt ja mal ne Wiki schreiben :D.
Also pgm_read_byte scheint was aus der AVR Lib zu sein oder? Ob das bei
AVR32 läuft weiß ich nicht musst du testen.
Das ovr (Output Value Register) wo der Name für die function steht ;).
Also nen wert am Pin einlesen geht damit nicht.
Da brauchst du das pvr (PIN VALUE REGISTER).
1
Port=AVR32_GPIO.port[1].pvr;// damit liest du komplett PORTB ein
So jetzt nochmal zu deinen 8bit daten. Die sollen auf PA0-PA7 oder?
Dazu will ich die jetzt noch eine zusatz Funktion erklären die ganz toll
ist beim AVR32
Man kann bei den GPIOs hinter redem register noch ein s, c oder t
schreiben.
s = setzen(set). Es setzt die pins auf 1 die du auf 1 gestellt hast.
C = löschen(clear). Es löscht die pins mit 0 die du auf 1 gestellt hast.
T = umschalten(toggle). Die pins die du auf 1 gestellt hast wechseln den
zustandt. (das gilt nur fürs schreiben)
So jetzt mach ich dir mal Funktionen.
AVR32_GPIO.port[0].oders=0x000000ff;// setzt PA0-PA7 als ausgang
5
}
6
/*Hier wird wirklich nur Pa0-PA7 als ausgang gesetzt. Wenn PA8 schon ein ausgang war wird das bit nicht auf 0 gestellt das ich die function s (set) genutzt habe.*/
Oh hab garnet gesehen das du geschrieben hast ;).
Aber das ist richtig so sollte an PORTB 0x1f03ffff anliegen.
Was hast du eigentlich für ein Projekt vor??? Wenn ich mal fragen darf.
Es gibt ja leider noch nicht sehr viele UC3 Progger :(.
Als absoluten µC-Newbies mit rudimentären C-Kenntnissen sagt uns das
leider gar nichts. Wir munkeln nur, dass dem übergebenen Pin (2) eine 5
zugeordnet wird (??)
Was wird also genau zugeordnet und ist das die richtige Funktion, um auf
einem Pin ein anliegendes Stromsignal zu erkennen?
echt cool. Ja wenn man einmal richt drin ist, macht es immer mehr spaß
;).
Finde den AVR32 echt super. Was für ein board hast du genommen? Kannst
du mal Bilder von deinem Projekt zeigen und schreiben was noch so genau
damit vor hast.
mfg
Achja zu den beiden Studenten (oder heist du so ;)). Ich kann nur sagen,
dass das nutzen der vorgefertugten funktionen nicht umbedingt einfacher
ist und vorallem nicht schneller ;). Aber jeden das seine.
Also das mit den 5 bestimmt nur den port. Der Prozessor(welchen hab ihr
überhaupt???) hat mehrere PORTs A,B,C,X. Da das framework(also eure
fertige funktion) so aufgebaut ist das ihr nur den GPIO pin angeben
müsst, wird der port duch
wird dann der pin bestimmt. das & 0x1f sorgt dafür das ihr nur maximal
eine 31 habt, da jeder port nur 31 pins nutzt.
mit gpio_get_pin_value(2); bekommt ihr also den wert von PA2.
Als bespiel fur PB2 müsste man gpio_get_pin_value(34); eingeben ;).
Nach als zusatz info: Ihr musst vorher noch den Pin als eingang setzten
damit das auch funktioniert.
hab dank zippi!
sind wirklich 2 studenten und haben zu testzwecken n fertiges eval board
uc3a von in-circuit mit dem uc3a1215-u geholt.
gut zu wissen, dass man vorgefertigte methoden nicht nutzen muss.
dachten, die gehören zur standardbiblo.
weißt du zufällig ob/wo wir vorgefertigte methoden (pvr,ovr,etc.) incl.
doku als pdf finden können?
mfg
Ne leider hab ich auch noch nirgends so eine art doku direct gefunden.
Aber wenn man mal das Kapitel von GPIO im datenblatt durchliest, sollte
man nach und nach auch die vorgefertigte gpio.c aus dem Framework
verstehen.
Sonst könnt ihr auch fragen. Weiter oben im thread steht ja auch wie man
es ohne fertige funktionen macht. Probiert einfach mal rum. Wenn man es
1x verstanden hat ist es total einfach ;).
Ich werde die tage auch mal mit einer art wiki anfangen und alles
nochmal genau erklären. Link stell ich dann hier rein.
LG
Und natürlich sind wir auf eine Wiki gespannt.
Am liebsten wäre mir wirklich, komplett ohne GPIO auszukommen und eher
so vorzugehen, wie es im AVR-GCC-Tutorial für die 8Bit-Avrs beschrieben
ist. Das erscheint mir logischer und universeller.
PS: Unsere geplanten Projekte:
Christian:
- mehrere Spannungen mittels Multiplexer messen (in Brennstoffzellen)
Andreas:
- Temperatur messen, auf Grundlage dessen Lüfter regeln
- über Leistungskurve (Spannung * Strom) einer Brennstoffzelle deren
Reaktionsluftzufuhr regeln (also Steuersignal für Kompressor ausgeben,
entweder 1-10V/1-5V oder Servosignal)
Zeitraum zur Bewerkstelligung: 2 Monate ... ihr werdet also öfter von
uns hören ;-)
Gruß
Andreas
Ich (Andreas von 2 Studenten) bin jetzt mittlerweile im
Leuchtdiodenstadium bei den AVR32 angekommen und habe folgendes Problem:
Ich gebe eine hochzählende Zahl zu Testzwecken binär auf Dioden aus,
allerdings habe ich das Problem, dass bei 1 die Dioden aus sind und bei
0 an.
Sprich eine 5 wird bei 6 Dioden verkehrt dargestellt, anstatt 000101
bekomme ich 111010.
Was habe ich im Quelltext falsch gemacht?
Ich habe immer noch ein bißchen Probleme mit den Zuordnungen von Bytes
und den vorgefertigten GPIO-Befehlen.
Die Zahl läuft nur bis 63 hoch, wegen der 6 Dioden.
1
intmain(void)
2
{
3
U16zahl=0;//Zähler
4
U32i;//you will find this definition of >U32< in driver "compiler.h"
Mit den durch "//" maskierten Befehlen komme ich auch leider zu keinem
anderen Ergebnis.
Weitere Frage:
Wie kann ich z.B. folgendes erreichen: 19 ms an Pin 10 kein Signal und 1
ms Signal (für ein Servosignal)? Irgendwie habe ich in der Doku was von
den Timern gelesen, scheitere aber schon an der Auswahl der richtigen
Uhr und bin bei den entsprechenden An- und Ausschaltbits überfragt.
(Zippi... wir wollen deine WIKI! :D)
Problem 1 gelöst (invertiertes Blinken):
Es lag an einem Sachverhalt names Sourcing & Sinking, bzw. dem
Vertauschen.
Ich hatte aus Versehen bei allen Dioden den Widerstand zw. GND und Diode
anstatt zwischen Pin und Diode. Dadurch floss irgendwie der Strom
anders.
Einer servo über GPIO mit warte schleifen zu schreiben ist natürlich
mehr als fusch^^. Und befor ihr zu den Timern bzw ne servo macht man mit
PWM. Geht solltet ihr anfang die CPU zu initialisieren. Sonst arbeitet
ihr nur mit dem ungenauen internen tackt. Infos stehen im aktuellem
Datenblatt auf seite 68. Im kapitel 13.6.1 Mein Clock Control.
Naja aber weil ich mal nicht so bin gibt es von mir auch einen source.
In dem Soucre könnt ihr theoretisch jeden clock einstellen von 6-66Mhz
Praktisch aber nicht weil alles unter 42 nicht mehr ganz spezifisch ist.
Warum das so ist steh im datenblatt (falls ihr lust habt könnt ihr das
auch anpassen). Gehen tut es aber trozdem. Zusätzlich gehen nur takte
die durch 6 teilbar sind.
Von mir getestete Clocks:
12/18/24/30/36/42/48/54/60/66/72/78/84/90 Mhz. Haben alle funktioniert.
Natürlich ist alles über 66 Mhz übertaktung.
Der Source geht nicht mit UES prozessoren. Und ich hab ihn nur auf einem
UC3A getestet.
PS: Die Wiki muss leider erstmal noch etwas warten da ich noch ein
vernünftiges Wiki skript suche.
Hi Phil,
vielen Dank für deine Hilfe!
Mit den Timern werde ich mich wohl erst nächste Woche ausführlicher
beschäftigen. (Erstmal das entsprechende Kapitel dazu recherchieren und
deinen Quelltext ansehen.)
Mittlerweile schaffe ich es zumindest auch Signale zu geben. Wie kann
ich aber erwirken, dass nicht erst nach dem Schleifendurchlauf "test"
geprüft wird, sondern bei jeder Betätigung sofort eine andere Funktion
aufgerufen wird?
bisheriger Stand:
1
intmain(void)
2
{
3
Booltest;//Variable für einen Taster
4
U16zahl=0;//Zähler
5
U32i;//you will find this definition of >U32< in driver "compiler.h"
Hehe genau das ist das Problem.
Normal macht man nicht einfach in einem Code eine Schleife die so lange
dauert und dann noch genau sein soll, deswegen timer ;). Achja mein
Code(clock.c) hat nichts mit dem Timer zu tun. Da geht es nur um den CPU
main clock.
Für Timer information im datenblatt ab S. 639 bis S. 672. Ich würde euch
raten den ganzen Teil auszudrucken und zu lesen. Wenn ihr fragen habt
einfach Posten.
Doch wenn ihr für den Anfang nur einen Servo Motor ansteuern wollt wäre
ab S. 673(PWM) besser(viel besser ;)).
Zu euerm Code nochmal
Wenn ihr:
Hallo Phil,
danke für die Vereinfachung des Quellcodes. Somit springt sozusagen
früher das "Interrupt" ein (obwohl dafür ja meist eine extra-Routine
genutzt wird, oder?).
Ich versuche jetzt exemplarisch den PWM.Controller zum laufen zu
bekommen und testhalber immer von 0 bis Maximum ansteigen zu lassen.
Wollen wir bezüglich der ganzen Thematik ein neues Thema namens first
steps und try outs auf AVR32 eröffnen? Wäre sicher interessant für
andere Einsteiger die grundlegenden Sachen auf einem Haufen zu finden
(wird vielleicht die Beta-Variante der Wiki ;-)).
Gruß
Andreas
So.. da eben die Bearbeite-Funktion meinen ganzen Text gelöscht hat,
nochmal in kurzer Form:
Arbeitsschritte PWM:
- im Powermanager die PWM-Clock anschalten (wie geht das?)
Es gibt 13 Uhren, 11 Modulo-Uhren und 2 Linearteiler. Basis ist die
PWM-Master-Clock (MCK).
In den Header-Files habe ich aber nur folgendes gefunden:
Allerdings nichts, was die Uhr betrifft.
Was bedeutet eigentlich ein Konstrukt vom Typ "(*((volatile
avr32_pwm_t*)AVR32_PWM_ADDRESS))"? War das etwas mit Pointern? Also an
Adresse X wird Platz für Datentyp soundso frei gehalten?
So etwas wie avr32_pwm_t oder avr32_gpio_t (also mit t am Ende) liest
man ja öfter.
Das PWM Enable-Register scheint zum einschalten zusein. Die Struktur ist
auch im Datenblatt unter 32.7.2 zu sehen, allerdings bewirkt ein
AVR32_PWM.MR...irgendwas gar nichts :-(
OK,
Wegen dem Volatile das steht hier gut beschrieben:
http://www.imb-jena.de/~gmueller/kurse/c_c++/c_volat.html
So nun zu deinen Uhren.
Erstmal sind das keine 13 Uhren die der AVR32 hat sonden Takte bzw
taktleitungen.
Auf Seite 70 Stehen die einstellungen für die einzelnen Taktleitungen.
Der PWM takt steht im PBAMASK an bit 12. Wichtig zu wissen wäre noch das
alle Taktleitungen im Reset aktive sind, dass heist dort brauchst du
erstmal nichts verändern.
Interessant ist aber, dass das abstellen von nicht benötigten Takten bis
zu 25% Stom sparen kann. Das heist also bei 66Mhz nur 30mA bei einer
Spannung von 3,3V. Nur so nebenbei ;).
Was du dir noch anschauen solltest ist wie man Register direct
anspricht. Du benutzt ja meistens immer die GPIO.h oder jetzt die PWM.h.
Wenn du richtig verstehen wills was du da eigentlich Programmierst oder
einstellst rate ich dir von dem Framework ab. Hier mal ein paar
Beispiele wie man direct registern snspricht (der grund aufbau ist immer
gleich):
GPIO Enable Register: (seite 178)
1
AVR32_GPIO.port[0].gper;
ADC Control Register: (seite 708)
1
AVR32_ADC.cr;
PWM Mode Register: (seite 685)
1
AVR32_PWM.mr
Und so ist es mit jedem Register möglich, dafür brauchst du auch kein
Header außer der AVR32/io.h. Wenn das zu schnell war wird das nochmal in
meiner Wiki beschrieben. Die erste Version gibt es dann auch bald.
Ich werde ein neues Thema machen und dann die WIKI erst einmal als PDF
verfassen und sie dann an ausgewählte Tester schicken. Dann hab ich nen
Feedback ob das soweit gut zu verstehen war oder nicht. Und kann sie
verbessern.
So hatte noch vergessen das du es ja schon versucht hast direct
anzusteuern.
Zur info die Bits haben auch spezielle namen:
DIVA = AVR32_PWM_DIVA_OFFSET;
und
PREA = AVR32_PWM_PREA_OFFSET;.
ps: Das MR bei dem PWM register wird kleingeschrieben.
Hi Zippi,
vielen Dank mal wieder für deine kompetente Hilfe!
Ich verabschiede mich dann ab heute vom Framework und machs dann auch
lieber von Grund auf. Genau bei dieser Herangehensweise stellt sich aber
folgendes Problem:
Phil S. schrieb:
> > Zur info die Bits haben auch spezielle namen:> DIVA = AVR32_PWM_DIVA_OFFSET;> und> PREA = AVR32_PWM_PREA_OFFSET;.> ps: Das MR bei dem PWM register wird kleingeschrieben.
Woher bekomme ich genau solche Namen? Im Datenblatt steht z.B. beim
MR-Register (Mode Register) nur DIVA, DIVB usw., sowie darüber Nummern.
Leider aber nichts von AVR32_PWM_DIVA_OFFSET.
Kann ich diese Bits auch einfach über Nummern ansprechen, die evtl. aus
dem Datenblatt ersichtlich sind? So z.B. bei dem DIVA-Bit wie folgt:
anstelle von
1
AVR32_PWM.MR=(1<<AVR32_PWM_DIVA_OFFSET);
2
AVR32_PWM.MR=(0000<<AVR32_PWM_PREA_OFFSET);
nun
1
AVR32_PWM.MR=(1<<0);
2
AVR32_PWM.MR=(0000<<8);
??
Meine ganze Initialisierung sehe dann wie folgt aus:
1
AVR32_PM.pbamask=(1<<12);//Enable PWM clock... although it should already be running
2
AVR32_PWM.mr=(1<<0);//DIVA set, clock selected by PREA
AVR32_PWM.channel[0].cmr=(1<<9);//Polarity of output (cpol)
9
AVR32_PWM.ena=(1<<0);//PWM for channel 0 enabled
Ich könnte mir so die Initialisierung vorstellen, kann ich allerdings
den PWM-Ausgang auf jeden Pin legen? Oder gehen nur bestimmte Pins dafür
und wie schalte ich die an?
In einem anderen Quellcodebeispiel habe ich folgendes gefunden:
> AVR32_GPIO.port[0].pmr0c = Bit(8) | Bit(7); //Function> AVR32_GPIO.port[0].pmr1c = Bit(8) | Bit(7); //0 = PWM.
Im Datenblatt zum Eval-Board steht an Pin 19:
PB19/PWM_PWM[0]/PM_GCLK[0]/EIM_SCAN[4]... allerdings passiert an diesem
Pin nichts :-/
HI,
Also die Namen wie man sie beschreibt stehen nicht direct im datenblatt.
Habe mir das anfangs im Framework angeschaut und kenne den Aufbau jetzt
auswendig.
Du kannst natürlich anstatt den namen AVR32_PWM_PREA_OFFSET Auch ne 8
nehmen. Wenn du mit der Maus über das register gehst siehst du auch,
dass er es als 8 definiert hat. Als Hilfe kannst du aber auch z.b.
AVR32_ eingeben und dann Strg + leertaste drücken dann erscheinen alle
register. Hab hier mal nen bild als beispiel.
Hab grad eben auch nen Servo gesucht, angeschlossen, programmiert und er
läuft schon ;).
Wo die PWM pins sind, steht auf Seite 45. Da steht z.b. PB19 hat als
Function A PWM0.
Die Funktionen Wählt man dann mit dem Peripheral Mux Register 1 u 2 aus.
Da hattest du ja schon den ansatz gezeigt. Wie das genau geht steht auf
Seite 179
Für PB19 auf Funktion A:
> AVR32_GPIO.port[1].pmr0c = 1 << 19; //Function
AVR32_GPIO.port[1].pmr1c = 1 << 19;
Für PB19 auf Funktion D:
> AVR32_GPIO.port[1].pmr0s = 1 << 19; //Function> AVR32_GPIO.port[1].pmr1s = 1 << 19;
Zusätzlich musst du noch den GPIO deaktivieren.
> AVR32_GPIO.port[1].gperc = 1 << 19;
lg Zippi
Wieder einen Schritt weiter und die Mux-Register verstanden!
Damit habe ich es geschafft, den PWM-Ausgang anzuschalten und auch eine
Diode entsprechend blinken zu lassen. Jetzt heißt es nur noch die
Parameter richtig zu verstehen.
Die Funktion sieht wie folgt aus:
>//AVR32_PM.pbamask = (1 << 12); //Enable PWM clock
Musste deaktiviert werden, da danach merkwürdigerweise nichts mehr
passierte (anhand der Blinkschleife ersichtlich gewesen). Irgendwo
weiter oben im Thema wurde erwähnt, das die Masterclock bereits läuft,
doch dann hätte ein weiteres setzen des entsprechenden Registers doch
nichts bewirken dürfen, oder?
Hi,
Ok schon super, dass du verstanden hast wie die PWM funktioniert ;).
Da sind aber noch entscheidende Fehler bei deiner Register Ansteuerung.
Achtung Ganz wichtig:
1. So was wie binäres schreiben in Register geht nicht. z.b.
>>AVR32_PWM.mr = (0000 << 8);>>AVR32_PWM.channel[0].cmr = (0101 << 0);
Das ist für ihn alles Dezimal, das es bei dir grad passt ist Zufall.
Also er schreibt dann in cmr 101 rein. Das ist dann in Hex 0x65
Und würde im Register den Teiler auf 0101 stellen aber das macht nur die
0x5. Die 0x60 schreibt in die oberen Register noch 1010 rein. Was
zurzeit nicht schlimm ist weil dort keine Funktion steckt.
Besser ist da mit hex zu arbeiten:
>>AVR32_PWM.mr = (0x0 << 8);>>AVR32_PWM.channel[0].cmr = (0x5 << 0);
2. Das 2. Problem ist, welches auch verursacht, dass bei dem diesem
Befehl nix mehr geht:
>AVR32_PM.pbamask = (1 << 12);
Du schreibst so quasi 0b00000000000000000001000000000000.
Das Aktiviert den Takt für PWM schon, trozdem(da ja alle taktleitungen
aktive sind) deaktivierst du alle andern in diesem Register wie z.b.
GPIO. Also werden deine LEDs auch nicht mehr gehen ;).
Richtig wäre, das man den alten wert mit übernimmt. Beispiel:
>AVR32_PM.pbamask = AVR32_PM.pbamask | (1 << 12);
Somit wird der alte Wert mit dem neuen verodert.
Das gleiche gilt auch für:
>AVR32_PWM.channel[0].cmr = (0101 << 0); //Pre-scaler 1024>AVR32_PWM.channel[0].cmr = (1 << 8); //period center-aligned (calg)>>>AVR32_PWM.channel[0].cprd = 23030; //visible blinking>>>AVR32_PWM.channel[0].cdty = 5000; //Pulsewidth>AVR32_PWM.channel[0].cmr = (1 << 9); //Polarity of output (cpol)
Als erstes setzt du den Pre-scaler und im 2. Moment wird der Pre-scaler
wirder gelöscht und nur setzt du das CALG bit. Als 3.(an 5. stelle)
löscht du wieder das ganze register und setzt nur das CPOL bit.
Quasi macht dein ganzes Programm in echt:
Oh weh. Danke für die Korrektur solcher grundsätzlicher Fehler!
Wenn mich meine Informatikkenntnisse nicht täuschen, kann ich ja keine 0
verodern. Sprich: Wie ordne ich dann eigentlich eine 0 sauber zu?
>AVR32_PWM.channel[0].cmr = AVR32_PWM.channel[0].cmr | (0 << 8); //period
left-aligned (calg)
dürfte ja eigentlich nicht funktionieren?
Des Weiteren: Ich habe jetzt ein Servosignal mit den richtigen "Abmaßen"
erzeugt. Die typischen Servoanschlüsse sind meist 3-polig und haben
plus, minus und Servosignal. Ich habe Minus mit Mirkocontroller-, bzw.
Boardmasse verbunden und Signal mit dem PWM-Ausgang. Es liegen aber
bereits 5 Volt am Stecker bei plus (des Servoanschlusses)an?!
Daher habe ich mir nicht getraut, diese Leitung mit irgendwas (z.B. bei
Vin des µC-Boards (wenn der über USB versorgt wird, liegen dort 4,8 V))
zu verbinden. Wird ein Servotester angeschlossen, funktionierts (der
wird dann anscheinend über die +-Leitung versorgt), mit dem UC3 aber
nicht.
:-/
Kann ich gefahrlos die 5V des Servoanschlusses auf die 4,8 V von Vin
legen?
Ist das Servosignal vielleicht mit 3,3V zu schwach?
PS: @Zippi: Hurra! Morgen wird die Baustelle ADC aufgerissen. Wir warten
sehnlichst auf deine Wiki :D
HI,
Ja du kannst den Servo auf deine 4,8V legen. Und die Spannung ist die
USB Spannung. Also mein Servo funktioniert. Und ich hab das Kabel an VCC
gemacht, also 3,3V.
Wegen dem verodern. Beim start sind die meisten Register auf 0 gesetzt,
und so musst du eigentlich nur die 1 setzen welche du brauchst.
Wenn du doch ein Register hast welches du auf 0 setzen willst kannst du
es mit einer oder und Invertierung machen.
In dem Beispiel wird das 8bit auf 0 gesetzt.
>AVR32_PWM.channel[0].cmr = AVR32_PWM.channel[0].cmr &(~(1 << 8));
Ich habe eben folgendes ausprobiert:
Vom Servokabel mit Minus auf GND des Mikrocontrollers, mit Plus auf Vin
und mit Signal auf den PWM-Pin. Bei hoch und runter laufendem Signal
(1-2 ms) passiert nichts. Dann habe ich das Signal fest auf 1,53 ms
eingestellt, mit dem Effekt, dass der Motor für ca. 10 s lief, danach
Abschaltung. Tests mit anderen Signalbreiten (1,3 ms; 1,8 ms) ergaben
KEIN Anlaufen.
Weiterer Nebeneffekt: Ich habe einen funktionierenden PWM-Pin weniger
:'-(
Einen Widerstand vergessen? Oder woran könnte es gelegen haben? Wie hast
du deinen Servo richtig angeschlossen?
Ich habe nochmal nachgemessen: auf plus vom Servo liegen 5,8 V an, d.h.
auch am UC3 zwischen Vin und GND 5,8 V.
Retourkutsche: Der PWM-Pin ist nicht hinüber, aber der Motor nun, da ich
durch mein "Vollgas-Signal" das Steuerteil vom Motor in den
Programmiermodus gebracht habe und anscheinend auch etwas umprogrammiert
(YGE 40 von YGE, Motor: 1010er Serie von Lehner-Motoren-Technik, bis
100000 1/min). Der Motor reagiert nur noch mit Zucken.
Trotzdem ist die PWM-Programmiererei dank Zippi erstmal erfolgreich und
zumindest ein PWM-Lüfter lässt sich nun anstandslos regeln.
Damit geht das sorglose Gefrage eines Anfängers aber weiter, denn es
soll ein Temperatursignal eingelesen werden. Daher ist das An- und
Ausschalten und richtige Auslesen des ADC wichtig.
Aus dem Framework lässt leider wieder nicht genau erkennen, wie sich
analog zur PWM auch der ADC bedienen lässt.
Mein ansatzweiser Quellcode sieht daher wie folgt aus:
Ist eigentlich
>AVR32_GPIO.port[0].puers |= (1 << 21);
dasselbe wie
>AVR32_GPIO.port[0].puers = AVR32_GPIO.port[0].puers | (1 << 21);
1
voidADC(void)
2
{
3
intvalue=0;
4
volatileavr32_adc_t*adc=&AVR32_ADC;
5
AVR32_GPIO.port[0].gperc=AVR32_GPIO.port[0].gperc|(1<<21);// Use PA21 as function, disable setting as a periphal pin
6
AVR32_GPIO.port[0].pmr0c=AVR32_GPIO.port[0].pmr0c|(1<<21);//Function A (ADC) selected through setting
Hi,
Ja das ist genau das selbe, nur in kurz vorm geschrieben.
>AVR32_GPIO.port[0].puers |= (1 << 21);
=
>AVR32_GPIO.port[0].puers = AVR32_GPIO.port[0].puers | (1 << 21);
Für ADC gilt dasselbe wie für PWM und alle anderen Peripherien.
Erst Datenblatt teil lesen, dann die Register versuchen zu verstehen und
wenn man nicht weiter kommt kann man mal ins Framework schauen ;).
Ich würde dir aber erstmal Raten die an Die Main clock zu setzen, damit
du mal eine vernünftige CPU clock hast. Dann lässt sich auch PWM genauer
einstellen.
Wegen dem Servo noch mal... Hoch und runter = 1-2ms?
Eine Periode muss immer 20ms haben.
Ich hoffe du weist wie ein Servo richtig funktioniert?
http://www.flugleiter.de/rc/servo
Gruß
Servo wurde soweit verstanden: 20 ms, 1-2 ms davon das Servosignal. Das
Problem war wie gesagt, dass der Motorregler aus dem Modellbau kommt und
so eingestellt ist, dass Vollgas bei Start (2 ms Signal) den
Programmiermodus öffnen.
Wegen der Main Clock: Ich arbeite zur Zeit mit 115kHz. Sind die anderen
Varianten günstiger?
MCSEL: Main Clock Select
0: The slow clock is the source for the main clock
1: Oscillator 0 is source for the main clock
2: PLL0 is source for the main clock
(PS: Bald ist Wochenende, da verschone ich dich mal mit
Löcher-in-den-Bauch-fragen ;-) )
Nur eine letzte Frage noch:
Was bedeutet dieser Befehl:
>volatile avr32_adc_t *adc = &AVR32_ADC;
Es wird ein Objekt der Klasse avr32_adc_t erzeugt, und zwar an der
Adresse von AVR32_ADC? Oder Was bedeuten dort "*" und "&"?
OK,
Ja du arbeitest zurzeit mit 115khz und das sogar sehr ungenaue 115khz.
Dazu kann der AVR32 mehr als 500x so schnell laufen wenn du ihn
einstellst und das auch noch sehr genau.
Wenn du MCSEL auf 1 stellst Hast du den Oszillator. Also dein Quarz auf
dem Board. Der liegt bei 12Mhz wenn ich mich nicht täusche. Das wäre
schon mal ein Anfang.
Beim dem ADC Pointer bin ich mir nicht ganz sicher, da ich wie gesagt
nicht mit dem Framework arbeite. Aber ich denke das er sich da nur die
Adresse von den ADC Register holt.
Gruß
AVR32_GPIO.port[1].oders=0x0F;// GPIO als ausgang.
10
AVR32_GPIO.port[0].ovrc=0xff;
11
AVR32_GPIO.port[0].ovrs=zahl;// GPIO-Zustand
12
for(i=0;i<15000;i++);
13
ADC_INIT();
14
...
An dieser Stelle wird ADC_INIT() aufgerufen. Die for-Schleife ist nur
für ein paar Dioden zur Ausgabe der "zahl".
Wird die Funktion ADC_INIT aufgerufen, steigt der µC aus.
1
voidADC_INIT(void)
2
{
3
AVR32_GPIO.port[0].gperc=AVR32_GPIO.port[0].gperc|(1<<21);// Use PA21 as function, disable setting as a periphal pin
4
AVR32_GPIO.port[0].pmr0c=AVR32_GPIO.port[0].pmr0c|(1<<21);//Function A (ADC) selected through setting
Der Aussteig geschieht schon an der ersten Zeile der Funktion ADC_INIT:
>AVR32_GPIO.port[0].gperc = AVR32_GPIO.port[0].gperc | (1 << 21); // Use PA21 as
function, disable setting as a periphal pin
Habe ich etwas vergessen?
HI,
Also du hast da noch ein Verständnis Problem.
Das
>AVR32_GPIO.port[0].gper
ist das Register an sich.
Mit dem c oder s dahinter macht er quasi die Veroderung automatisch.
Dieses s oder c oder t sind Zusatz Funktionen welche nur die GPIO
bieten, deswegen musst du die Veroderung bei andern Registern machen,
bei den GPIO aber nicht. So steht auch im Datenblatt auf Seite 175, dass
das AVR32_GPIO.port[0].gper ein read/write Register ist.
Aber das AVR32_GPIO.port[0].gperc ein write only Register.
Da du es aber liest stürzt er wohl ab.
Gruß
Erübrigt sich eine Veroderung bei Write-only-Registern generell, d.h.
beispielsweise immer
>AVR32_PWM.ena = (1 << 0); //PWM for channel 0 enabled
anstatt
>AVR32_PWM.ena |= (1 << 0); //PWM for channel 0 enabled?
Ersteres bewirkt auch nicht, dass aus ena: 1101000 danach 0000001 wird?
Hallo,
ich arbeite mich auch gerade in die Welt der 32 Bit Controller. Für den
Anfang war das hier schon einmal gut aber gibt es mittlerweile ein Wiki?
Ich habe nichts gefunden wo drin steht, was z.B. die ganzen Abkürzungen
wie gpers bzw oders bedeuten. Von daher ist die ganze Sache nicht ganz
so trivial und die Beispiele im AVRStudio 5 helfen nur bedingt
weiter....
Markus schrieb:> Ich habe nichts gefunden wo drin steht, was z.B. die ganzen Abkürzungen> wie gpers bzw oders bedeuten.
Na, das sind Abkürzungen für Bits/Register usw. aus den Datenblättern.
Eine kurze Suche im Datenblatt ergab z.B. für ODERS:
0x44 Output Driver Enable Register Set
Ja war mein Fehler. Hatte das falsche Datenblatt....
Hab das soweit auch alles geschafft was ich wollte und nun gehts an SPI.
Hab da auch schon einige Besipiele gefunden aber das ist mir auch wieder
recht unklar. Bei den 8 Bit Controllern fand ich das alles
übersichtlicher....