Hallo Leute,
ich brauche etwas mehr Leistung, als meine sonst bevorzugten 8-Bit-AVRs
bieten. Da lag es nahe, einen AVR32 aus der UC3A/B-Serie zu nehmen, weil
die sich auch schön mit dem mk2 debuggen lassen.
Ich habe mich etwas eingelesen, verstanden habe ich aber noch nicht
viel.
Wollte zuerst ein Blinkprogramm schreiben und da fing es schon an:
Wie sage ich dem dem Controller welcher Pin Eingang/Ausgang ist?
Das Framework hat eine gpio-Lib, aus den Kommentaren in der gpio.h werde
ich aber nicht wirklich schlau.
Ich schreib hier einfach mal nieder, wie ich es verstanden habe,
in der Hoffnung, dass es es jemand bestätigen oder korrigieren kann:
gpio_enable_module_x: Ordnet Pins wohl wohl ihren Sonderfunktionen zu,
wie RXD oder TXD
gpio_enable_gpio_x: Deaktiviert die Sonderfunktionen und macht Pins
wieder zu gewöhnlichen IOs.
gpio_set_gpio_pin, gpio_clr_gpio_pin, gpio_tgl_gpio_pin:
Setzt, Löscht und invertiert den Pin.
In dem Beispielprojekt werden Pins mit gpio_enable_gpio_pin wohl zu
Ausgängen geschaltet. Nur wie schalte ich das wieder zurück?
(Die Fkt gpio_disable_gpio_pin gibt es nicht)
Kann mir das jemand erklären oder kennt jemand noch eine andere
Möglichkeit die Ports anzusteuern?
MFg Eti
Hallo Zippi,
danke dir! Damit hast du gleich einen ganzen Haufen von Fragen auf
einmal erschlagen. Ich nehme an, dass es immer noch keine Übersicht
gibt, wie die Register in den Libs genannt werden, oder?
Eti
Hi,
ne, leider nur der editor rechts im AVR32 Studio.
Aber das geht mit etwas übung auch ganz gut.
Irgendwo hab ich auch mal eine bespielcode zum LED blinken gepostet(nur
ein paar zeilen code ohne gpio.h) für die AVR32.
Probier den erstmal aus.
Wenn du ihn nicht findest, dann poste ich den gerne nochmal.
gruß
Hallo Zippi,
danke für das Angebot und den Denkanstoß!
Deinen Beispielcode habe ich gefunden.
Ich denke, ich komme nun mit der Namensgebung zurecht. Ich habe mich mal
durch die structs der gpio_xxx.h gelesen, die ja (indirekt) mit der io.h
eingebunden werden.
Offensichtlich hat sich Atmel an die Registernamen aus dem Datenblatt
exakt gehalten.
Deinen Beitägen entnehme ich, dass du schon länger mit den
AVR32-Controllern zu tun hast. Was ich gerne wissen würde ist, ob sie
sich bewährt haben. Das Errorsheet ist für einen neuen Baustein (für
meinen Geschmack) recht kurz.
Bist du bei deinen Arbeiten vieleicht auf undokumentierte Fehler in den
Controllern selbst oder in der Entwicklungsumgebung gestoßen?
Gab es Stabilitätsprobleme im Betrieb?
Ich würde mich sehr freuen, wenn du ein paar deiner Erfahrungen mit mir
teilst.
Danke und Gruß
Eti
Nice!
Du machst du mich echt neugierig...
Vorallem die Menüs sind echt gut gelungen!
Zu Programmieren nehme ich entweder den JtagIce mk2 oder den Dragon, der
ja nun auch unterstützt wird.
>An sich hatte ich noch keine Großen Probleme.
Höre ich gerne, das ist mein erstes Projekt mit einem AVR32.
>Die interrupts sind nur recht komplex.
Hast du da eine Empfehlung oder Link auf einen Beitrag?
Das Thema kommt noch auf mich zu.
Hast du mal eine USB-Verbindung damit aufgebaut?
Ich überlege, ob ich nicht einen FT2232H dafür nehme.
Weil wenn von den 12MBit brutto netto weniger als 8MBit übrig bleiben,
wird das knapp für meine Anwendung.
Ok, ich nehme auch den JTAG mkII oder den bootloader.
>Hast du mal eine USB-Verbindung damit aufgebaut?>Ich überlege, ob ich nicht einen FT2232H dafür nehme.>Weil wenn von den 12MBit brutto netto weniger als 8MBit übrig bleiben,>wird das knapp für meine Anwendung.
Ne, mit dem USB hab ich mich noch nicht so auseinander gesetzt. Hab nur
mal das example von Atmel als massen-speicher-gerät getestet.
Was hast du denn genau mit dem ding vor, das du 8Mbit brauchst?
gruß
Das Ding soll erst mal Daten aus mehreren AMC1210 (jeder filtert 4
Sigma-Delta-Datenströme) auslesen und übertragen. Wenn das funktioniert,
werde ich versuchen eine Verarbeitung der Daten ans laufen zu kriegen,
damit der AVR selbst Fehler bemerkt und nicht die PC-Software reagieren
muss.
mein respekt Phil S.!
In welcher Programmiersprache hast Du's geschriben?
Wie wird das Display angesteuert (Parallel, Seriell resp. SPI etc.)? Die
frage kommt daher, da ich ebenfalls einen Displaytreiber (jedoch nur
monochrom) am implementieren bin, wobei das Display parallel angesteuert
wird. Dabei habe ich das Problem wenn ich z.B. ein Rechteck ausfülle das
ganze sehr langsam von statten geht, sprich man sieht wie die einzelnen
Zeilen aufgebaut werden.
gruss suomi
Hi
> mein respekt Phil S.!>> In welcher Programmiersprache hast Du's geschriben?
Danke, Ich habe das ganze in C geschrieben ;).
> Wie wird das Display angesteuert (Parallel, Seriell resp. SPI etc.)?
SPI mit DMA, brauche ca. 0,007s um das Display komplett zu updaten.
> Die frage kommt daher, da ich ebenfalls einen Displaytreiber (jedoch nur> monochrom) am implementieren bin, wobei das Display parallel angesteuert> wird. Dabei habe ich das Problem wenn ich z.B. ein Rechteck ausfülle das> ganze sehr langsam von statten geht, sprich man sieht wie die einzelnen> Zeilen aufgebaut werden.
Also normalerweise solltest du mit Parallel und monochrom ein vielfaches
schneller sein.
Was für ein Display ist das?
Was für einen Controller hast du denn genau?
Also bei den AVR32 ist das so, das die standard mäßig auf 115.000 Hz
laufen.
Dann muss du erst die PLL Progamieren.
Gruß
Zippi
> Danke, Ich habe das ganze in C geschrieben ;).
Ich meinerseits bin am C++ lernen. Denke aber dass dies nicht umbedingt
ein nachteil sein muss wenn man Methoden als static inline deklariert.
Was denkst Du?
> Also normalerweise solltest du mit Parallel und monochrom ein vielfaches> schneller sein.
Das dachte ich mir auch! Es gibt da doch gewisse Einschränkungen:
1. Der Displayinterne Controller ist ein RA8835A. Bei diesem Controller
ist es nicht möglich nur einzelnes Pixel zu setzten. Ich verwende in
meinem code oft eine setPix(x, y) Funktion z.B. für Draw Circle etc.
Dies hat folgen Ablauf zur folge:
a) Adresse Berechnen
b) 1Byte auslesen
c) Bit setzten
d) Ursprungsadresse wieder setzten, da der Controller den internen
Adresspointer automatisch inkrementiert
e) 1Byte zurückschreiben.
2. Weiter ist jeder GPIO Port 32Bit breit
-> habe meinen Treiber so geschriben, dass simultan 8 Bits geschrieben
werden können:
AVR32_GPIO_LOCAL.port[pinGroup.port].ovr =
(AVR32_GPIO_LOCAL.port[pinGroup.port].ovr & ~(pinGroup.pinGroupMask))
| ((value << pinGroup.pinOffset) & pinGroup.pinGroupMask))
wobei:
struct GPIO_PIN_GROUP {
GPIO_PORT port; // zu der Pin-Gruppe gehöriger Port
GPIO_FUNCTION pinGroupFunction;
uint32_t pinGroupMask; // z.B. PORTA.1 ... PORTA.4 -> Maske =
//0b11110 \n
uint32_t pinOffset; // Verschiebung anhand pinGroupMask
};
-> was wieder gewisse Performance kostet.
> Was für ein Display ist das?
Es ist ein 320x240 Display inklusive Touch!
(http://ledsee.com/index.php?page=shop.product_details&flypage=flypage.tpl&product_id=129&category_id=23&option=com_virtuemart&Itemid=27)
> Was für einen Controller hast du denn genau?
Ich hab den selben wie Du, den AT32UC3A1512 (Device Revision I)
> Also bei den AVR32 ist das so, das die standard mäßig auf 115.000 Hz> laufen.> Dann muss du erst die PLL Progamieren.
;-)
Was denkst du hab ich als erstes "raufgeschraubt". Nein im ernst, hab
ihn momentan mit fullspeed am laufen (66MHz)
hier die funktion:
pm_freq_param_t conf = {
AVR32_PM_CPU_MAX_FREQ,
AVR32_PM_PBA_MAX_FREQ,
FOSC0,
OSC0_STARTUP
};
pm_configure_clocks(&conf);
Weiter habe ich mal versucht einen Buffer (lcdBuff) zu verwenden
(9600Bytes!) und die setPix Funktion auf diesen Buffer umgebogen.
Danach konnte ich dann z.B. mit GLCDUpdate den ganzen Bildschirminhalt
aktualisieren.
GLCDUpdate hat dann etwa so ausgesehen:
GLCDUpdate(){
writeCmd(CMD_MWRITE);
for (uint32_t i = GR_START_ADR; i <= GR_END_ADR; i++) {
writeData(lcdBuff[i]);
}
}
Hast Du irgendwelche Verbesserungsvorschläge?
Weiter wüsste ich gerne, was für ein Display Du verwendet hast und woher
hast Du es Bekommen?
Phil S. schrieb:
> Als Display hab ich ein S65 Display genommen.> Hier z.B.> http://cgi.ebay.de/LCD-Display-fuer-Siemens-CX65-C...
Cool. Hast Du auch Datenblätter dazu?
> Hast du schonmal getestet ob sich deine MCU wirklich hochgetaktet hat?> Einfach mal GPIO toggeln und mit Oszi messen.
Bin leider noch nicht dazu gekommen. werd ich aber noch tun müssen.
Datenblatt gibt es nicht direct dazu. Nur beispiel code:
http://www.superkranz.de/christian/S65_Display/DisplayIndex.html
Musst du dann umschreiben für den AVR32.
Also ich hab meine CPU set funktion selber geschrieben, müsste auch hier
irgendwo im Forum sein. Kann sie aber auch gerne nochmal online stellen.
Gruß
Du teilst die PLL-Frequenz mit AVR32_PM.cksel = 0x80808080; ich hingegen
indem ich in AVR32_PM.pll[0] PLLOPT[1] auf 1 setzte. Sollte theorisch
keinen unterschied machen. Werde ich aber mal austesteten.
Klar alles getestet.
Bei mir läuft der sogar noch stabiel bei 96Mhz. Mehr geht aber nicht.
Grundsätzlich lass ich meinen aber zwischen 24-36Mhz laufen. Nur wenn er
den Videoplayer startet, dann geht er auf 72Mhz.
Schön wenn man den Takt jederzeit verstellen kann ;).
>Du teilst die PLL-Frequenz mit AVR32_PM.cksel = 0x80808080; ich hingegen>indem ich in AVR32_PM.pll[0] PLLOPT[1] auf 1 setzte. Sollte theorisch>keinen unterschied machen. Werde ich aber mal austesteten.
Ja, dass sollte eigentlich überhaupt keinen unterschied machen.
Geht der Display aufbau eigentlich schon schneller?
Gruß
Zippi
Phil S. schrieb:
> Geht der Display aufbau eigentlich schon schneller?
hab ich noch nicht getestet. möchte zuerst die fclk kontrollieren. hab
aber im moment noch kein oszi zur Verfügung. danach werde ich den
treiber weiter optimieren.
gruss suomi
Hallo Zippi
Konnte nun endlich die CPU Frequenz kontrollieren. Diese ist aus meiner
Sicht ok. Pin toggelte mit fcpu/2.
Weiter habe ich bemerkt, dass mich das Display ausbremst. Vor jeder
übertragung eines Datenbytes muss ein Busyflag überprüft werden. Weiter
ist dies abhängig von der Displayinitialisierung (welche ich nun auch
verbessert habe).
Die aktuallisierung des gesamten Displyinhalts benötigt nun bei mir ca.
7-11ms. Ist aus meiner Sicht nicht wahnsinnig schnell. weiss momentan
nur nicht wie ich es weiter verbessern könnte.
Nochmals vielen Dank für Deine Unterstütung!
gruss suomi
Hi,
Naja 7ms drosselt natürlich schon stark das ganze System. Hab das
gleiche Problem. Ich mache ja 25 Updates Pro sec. Das sind dann fast 20%
der kompletten Leistung, und dann auch nur wenn ich den stark
hochgetaktet habe.
Der Vorteil bei mir ist nur, dass ich das mit DMA mache, und so andere
Sachen in der Zeit machen kann. z.b. Sensoren einlesen oder änliches.
Ich darf nur nicht auf den vram schreiben.
Normalerweise solltest du aber noch schneller werden können.
Gruß
Hallo Lorenz und Zippi,
ich bin an der selben Sache dran, wäre schön wenn wir etwas code
austauschen könnten.
Ich benutze den gleichen Controller und ein Display monochrom 240 x 160
mit RA8822.
Bildschirmaufbau mache ich mit einem Cache.
Zippi kannst Du mir mit dem DMA helfen?
Der Cache wird bei mir so übertragen:
Hi,
Ja das stimmt.
Peripheral DMA Controller
• Transfers from/to peripheral to/from any memory space without
intervention of the processor.
• Next Pointer Support, forbids strong real-time constraints on buffer
management.
• Fifteen channels
– Two for each USART
– Two for each Serial Synchronous Controller
– Two for each Serial Peripheral Interface
– One for each ADC
– Two for each TWI Interface
Wenn du dir ein shiftregister dazwischen baust(am bessten im CPLD
programmieren), dann kannst du dein Display auch über SPI steuern.
Gruß
Guten Abend
Ich bin zur Zeit dabei mich ein bisschen mit dem NGW100-Board zu
beschäftigen(ohne Linux).
Als erstes hab ich mir vorgenommen, eine Usart Verbindung richtung Pc
aufzubauen und bin dabei auf ein Problem gestoßen.
Und zwar habe ich es geschafft mit dem folgenden Code zeichen an den Pc
zu senden.
Das Ganze funktioniert allerdings nur mit 20 MHZ. Wenn ich PLL0 auf 200
MHZ takte kommt nur noch Müll raus. Im Datenblatt steht auch, dass die
Frequenz bei externer Clock 4.5 mal langsamer sein muss als der Interne
Takt.
Trifft das auch zu wenn ich den CPU-Takt nehme und wo kann ich dass
einstellen? Hab bisher diesbezüglich nichts im Datenblatt gefunden!
Vielen Dank schon mal im voraus
Jasper
Hallo zusammen,
ich hab nochmal eine Frage bzgl. dem Auslesen eines Pins bei einem UC3A
AVR32.
Dank Zippi und dem oben beschriebenen Thread (AVR32UC3A Port setzen) hab
ich schon ne Menge bzgl. der GPIO Register gelernt und eine LED blinken
lassen klappt auch schon.
Das Auslesen eines Pins gelingt mir aber immer noch nicht richtig. Ich
hoffe ihr könnt mir weiterhelfen.
Ich möchte Pin PA21 auslesen, welchen ich auf GND oder 3,3V ziehen kann.
Hierfür benutze ich folgenden Code:
1
#include<avr32/io.h>
2
#include"gpio.h"
3
4
intmain(void){
5
6
intpin_status;
7
8
AVR32_GPIO.port[0].gpers=0x00200000;// PA21 als GPIO
9
AVR32_GPIO.port[0].oderc=0x00200000;// als Eingang benutzen
10
// Danach sehen die Register wie folgt aus:
11
// gper = 0xffffffff
12
// oder = 0x0
13
14
while(1){
15
pin_status=gpio_get_pin_value(AVR32_PIN_PA21);
16
}
17
}
Der Wert von PA21 wird zwar richtig ausgegeben, im
AVR32_GPIO.port[0].pvr Register werden bis auf 2 jedoch alle Pins als
High erkannt, obwohl ja nur PA21 auf 3V3 gezogen wurde. (alle anderen
Pins sind offene Klemmen- 0V laut Multimeter). Eine Abfrage welche der
Pins auf high gezogen wurde ist somit natürlich sinnlos, da alle auf
high liegen.
Das AVR32_GPIO.port[0].puer Register zeigt 0x0 an, demnach sind auch
keine Pull-up Widerstände gesetzt. Explizites ausschalten
AVR32_GPIO.port[0]=0x0 hilft auch nicht weiter. Woher kommen die Einsen?
-Mach ich noch irgendwas falsch? (z.B fehlende Clock oder so)
-Ist das ein Anzeichen dafür, dass der Mikrocontroller kaputt ist.
-kann es an meinem AVRDragon liegen, dass Register falsch geschrieben
werden?
Bin für jeden Tipp dankbar.
lg, matthias
Hallo Matthias
Wenn ich Dich richtig verstanden habe:
Anhand Deiner Beschreibung stimmt der Rückgabewert für PA21 mit Deinem
Erwartungswert überein. Nun Fragst Du Dich warum bei den anderen Pins
ein High erkannt wird?
Falls dem so ist:
Bei einem Reset müssen Initial alle Pins auf Eingang geschaltet sein.
Sind keine Pullups/Pulldowns extern bestückt oder nicht im uC aktiviert
sind diese Pins somit auf einem undefinierten Pegel.
--> die Werte können beim Auslesen high oder low sein.
Danke für die schnelle Antwort :)
Den Sachverhalt hast du richtig erkannt.
Für mich ist klar, dass der Mikrocontroller bei einer nicht definierten
Spannung am Pineingang seine Probleme hat. (Z.B wenn sie dann bei 1,4V
liegt oder so)
Wenn ich jedoch die Spannung der einzelnen Pins (ohne festes
Bezugspotential) nachmesse, liegt diese bei 0V. Also wäre es doch
naheliegend sie als 0 und nicht als 1 zu erkennen.
Oder gilt, dass ich niemals Eingänge benutzen darf, die auf keinem
festen Potential liegen (unabhängig von dem gemessenen Wert am Pin?)
Wenn ich also einen von insgesamt 20 Pins durch das anlegen einer
Spannung auswählen will, müssen die verbleibenden 19 trotzdem mit GND
verbunden werden?
Schonmal vielen Dank und lg
matthias
Matthias J. schrieb:> Wenn ich jedoch die Spannung der einzelnen Pins (ohne festes> Bezugspotential) nachmesse, liegt diese bei 0V. Also wäre es doch> naheliegend sie als 0 und nicht als 1 zu erkennen.
Ja da hast Du logischerweise schon recht, zu beachte ist jedoch, dass
das Multimeter auch nicht ideal ist und einen Innenwiderstand hat. Damit
beeinflusst Du die Messung mit dem Multimeter selbst.
> Oder gilt, dass ich niemals Eingänge benutzen darf...
--> Was heisst für dich benutzen?
--> Für mich heißt ein Input-Pin "benutzt": wenn ich diesen in der SW
als solchen konfiguriere und dann auch auslese."Unbenutzte" Input-Pins
werden bei mir in der SW nie eingelesen.
--> Das definieren auf eines "unbenutzen" Pins auf ein festets Potential
hat auch folgende Vorteile:
- Falls du den Pin irgendwann trotzdem mal einliest, weisst Du genau
was zu Erwarten ist.
- Des weiteren kann damit die Stromaufnahme des uC gesenkt werden. (Pin
toggelt nicht wild herum und verursacht Schaltverluste)
- Aus meinem Gefühl heraus würde ich auch sagen das damit die
Störanfälligkeit gesenkt wird.