Forum: Mikrocontroller und Digitale Elektronik AVR32: Wie Ausgänge/Eingänge schalten/einlesen


von Eti (Gast)


Lesenswert?

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

von Zippi (Gast)


Lesenswert?

Hi,

les dir ma die beiträge durch, Wenn du dann noch fragen hast schreib 
einfach.
Beitrag "AVR32UC3A Port setzen"

Gruß
Zippi

von Eti (Gast)


Lesenswert?

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

von Phil S. (zippi)


Lesenswert?

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ß

von Eti (Gast)


Lesenswert?

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

von Phil S. (zippi)


Lesenswert?

Hi,

Also hier mal 3 Videos mit meinem AVR32.

http://www.youtube.com/watch?v=EQlz2oFwrJI
http://www.youtube.com/watch?v=OyuSLipXvNk
http://www.youtube.com/watch?v=Lzbz_tU4f3g

An sich hatte ich noch keine Großen Probleme.
Die interrupts sind nur recht komplex.

Hab jetzt AVR32 Studio 2.3 drauf. Seit dem hab ich auch ein Problem mit 
malloc.
Ich bin mir aber nicht sicher ob das nicht vll doch an andern sachen 
liegt.
mal sehen.

Was benutzt du zum flaschen?

gruß

von Eti (Gast)


Lesenswert?

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.

von Phil S. (zippi)


Lesenswert?

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ß

von Eti (Gast)


Lesenswert?

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.

von Lorenz B. (suomi)


Lesenswert?

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

von Phil S. (zippi)


Lesenswert?

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

von Lorenz B. (suomi)


Angehängte Dateien:

Lesenswert?

> 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?

von Phil S. (zippi)


Lesenswert?

Hmm auf anhieb wüsste ich jetzt nichts.

CPP funktionen zu nutzen ist kein Nachteil, mach ich zum teil auch.

Das mit dem VRAM ist schonmal ein Guter ansatz. Das würde ich auch 
weiter benutzen, braucht ja auch nur 10K ram bei dir.
Ich habe auch ein VRAM nur ich brauch da 46kbyte :P.

Als Display hab ich ein S65 Display genommen.
Hier z.B.
http://cgi.ebay.de/LCD-Display-fuer-Siemens-CX65-CX70-M65-S65-CXT70-CXV70-S_W0QQitemZ270512750047QQcmdZViewItemQQptZHandy_Zubeh%C3%B6r?hash=item3efbd0fddf

Hast du schonmal getestet ob sich deine MCU wirklich hochgetaktet hat?
Einfach mal GPIO toggeln und mit Oszi messen.

Gruß

von Lorenz B. (suomi)


Lesenswert?

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.

von Phil S. (zippi)


Lesenswert?

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ß

von Lorenz B. (suomi)


Lesenswert?

Phil S. schrieb:
> Kann sie aber auch gerne nochmal online stellen.

ja das wäre nett!

von Phil S. (zippi)


Lesenswert?

So hier mal der code.

Die musst für Clock einen wert zwischen 24 und 66[overclock up to 96] 
(in 6Mhz schritten) Eingeben.
1
void set_CPU()
2
{
3
  int clock = 24;                                               // CPU Clock in Mhz 24-96
4
  int clockh = (clock/6) - 1;
5
6
  AVR32_PM.oscctrl0 = (AVR32_PM.oscctrl0 | 0x00000407);         // Startup time  /  Oscillator Mode
7
  AVR32_PM.mcctrl = AVR32_PM_OSC0EN_MASK;                       // Enable Oscillator 0
8
  while((AVR32_PM.poscsr & AVR32_PM_POSCSR_OSC0RDY_MASK)== 0);  // Oscillator 0 is ready
9
10
  AVR32_PM.pll[0] =  0 << AVR32_PM_PLLOSC_OFFSET |              // Oscillator 0 is the source for the PLL
11
                     1 << AVR32_PM_PLLDIV_OFFSET |              // div = 1
12
                     clockh << AVR32_PM_PLLMUL_OFFSET |         // multi clock z.b. if clockh = 10 (10+1)*12=132/2Fvc = 66Mhz
13
                     5 << AVR32_PM_PLLOPT_OFFSET;               // 80MHz<fvco<180MHz / fPLL = fvco / Wide Bandwidth Mode disabled
14
15
  AVR32_PM.cksel = 0x80808080;
16
  AVR32_PM.pll[0] |= AVR32_PM_PLLEN_MASK;                       // PLL enable
17
  while(!(AVR32_PM.poscsr & AVR32_PM_POSCSR_LOCK0_MASK));       // PLL 0 is locked, and ready to be selected as clock source
18
19
  AVR32_FLASHC.fcr |= 1 << AVR32_FLASHC_FWS_OFFSET;             // The flash is read with 1 wait state.
20
  AVR32_PM.mcctrl |= 2 << AVR32_PM_MCSEL_OFFSET;                // PLL0 as main oscillator
21
}

Gruß

von Lorenz B. (suomi)


Lesenswert?

Phil S. schrieb:
> Die musst für Clock einen wert zwischen 24 und 66[overclock up to 96]
Hast Du das getestet?

1
> AVR32_PM.pll[0] =  0 << AVR32_PM_PLLOSC_OFFSET |              // Oscillator 0 is the source for the PLL
2
>                      1 << AVR32_PM_PLLDIV_OFFSET |              // div = 1
3
>                      clockh << AVR32_PM_PLLMUL_OFFSET |         // multi clock z.b. if clockh = 10 (10+1)*12=132/2Fvc = 66Mhz
4
>                      5 << AVR32_PM_PLLOPT_OFFSET;               // 80MHz<fvco<180MHz / fPLL = fvco / Wide Bandwidth Mode disabled
5
> 
6
>   AVR32_PM.cksel = 0x80808080;
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.

von Phil S. (zippi)


Lesenswert?

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

von Lorenz B. (suomi)


Lesenswert?

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

von Lorenz B. (suomi)


Lesenswert?

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

von Phil S. (zippi)


Lesenswert?

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ß

von Lorenz B. (suomi)


Lesenswert?

Phil S. schrieb:
> Normalerweise solltest du aber noch schneller werden können.

habs nun auf 4.08ms-5.4ms gebracht.

gruss suomi

von Michael (Gast)


Lesenswert?

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:
1
void Cache2Lcd(void)
2
{
3
  unsigned short pos;
4
5
  
6
  for( pos = 0; pos < 4800; pos++ ) LCDWriteData(lcdcache[pos]);
7
8
  SwitchPage();
9
  
10
}

von Michael (Gast)


Lesenswert?

Ich habe mal angefangen den DMA zu initialisieren, jedoch ist mir nicht 
alles klar.
1
void pdca_set_irq(void)
2
{
3
  // Disable all interrupt/exception.
4
  Disable_global_interrupt();
5
6
  INTC_init_interrupts();
7
8
  // Register the compare interrupt handler to the interrupt controller
9
  // and enable the compare interrupt.
10
  // (__int_handler) &pdca_int_handler The handler function to register.
11
  // AVR32_PDCA_IRQ_0 The interrupt line to register to.
12
  // AVR32_INTC_INT0  The priority level to set for this interrupt line.
13
  // INTC_register_interrupt(__int_handler handler, int line, int priority);
14
  INTC_register_interrupt( (__int_handler) &pdca_int_handler, AVR32_PDCA_IRQ_0, AVR32_INTC_INT0);
15
16
  // Enable all interrupt/exception.
17
  Enable_global_interrupt();
18
}
19
20
__attribute__((__interrupt__)) static void pdca_int_handler(void)
21
{
22
    // Set PDCA channel reload values with address where data to load are stored, and size of the data block to load.
23
    pdca_reload_channel(0, (void *)lcdcache, sizeof( lcdcache ));
24
}
25
26
// PDCA channel options
27
     static const pdca_channel_options_t PDCA_OPTIONS =
28
     {
29
       .addr = (void *)lcdcache,                // memory address
30
       .pid = 0,                // Was muß da rein?
31
       .size = sizeof(lcdcache),               // transfer counter
32
       .r_addr = NULL,                          // next memory address
33
       .r_size = 0,                             // next transfer counter
34
       .transfer_size = PDCA_TRANSFER_SIZE_WORD // select size of the transfer
35
     };
36
37
     // Init PDCA channel with the pdca_options.
38
     pdca_init_channel(0, &PDCA_OPTIONS); // init PDCA channel with options.
39
40
     // Register PDCA IRQ interrupt.
41
     pdca_set_irq();
42
43
     // Enable pdca interrupt each time the reload counter reaches zero, i.e. each time
44
     pdca_enable_interrupt_reload_counter_zero(0);
45
46
47
48
     // Enable now the transfer.
49
     pdca_enable(0);

von Lorenz B. (suomi)


Lesenswert?

Hallo

sorry den DMA bisweilen noch nicht verwendet, da für normal GPIO's 
meines wissens keine DMA funktionalität besitzten.

gruess Lorenz

von Phil S. (zippi)


Lesenswert?

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ß

von jasper (Gast)


Lesenswert?

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.
1
#include <avr32/io.h>
2
3
int main(void)
4
{
5
  volatile avr32_pio_t *portA = &AVR32_PIOA;
6
  volatile avr32_usart_t *usart = &AVR32_USART1;
7
  unsigned int cd = 0;
8
  unsigned int baud = 115200;
9
  unsigned int cpuFreq = 20000000;
10
  
11
  portA->per |= (1<<19);
12
  portA->oer |= (1<<19);
13
  portA->idr |= (1<<19);
14
  portA->pudr |= (1<<19);
15
  portA->sodr |= (1<<19);
16
  
17
  AVR32_PM.pll0 = (1<<AVR32_PM_PLL0_PLLEN_OFFSET) 
18
          | (0<<AVR32_PM_PLL0_PLLOSC_OFFSET) 
19
          | (4<<AVR32_PM_PLL0_PLLOPT_OFFSET) 
20
          | (1<<AVR32_PM_PLL0_PLLDIV_OFFSET) 
21
          | (1<<AVR32_PM_PLL0_PLLMUL_OFFSET) 
22
          | (16<<AVR32_PM_PLL0_PLLCOUNT_OFFSET);
23
  
24
  AVR32_PM.mcctrl = (1<<AVR32_PM_MCCTRL_PLLSEL_OFFSET);
25
  AVR32_PM.cksel = 0;
26
27
  
28
  portA->pdr |= (1<<18);
29
  portA->pudr |= (1<<18);
30
  portA->asr |= (1<<18);
31
  
32
  //RESET USART1
33
  usart->idr = 0xffffffff;
34
  usart->cr = 0;                    //Set Control Register 0
35
  usart->mr = 0;                    //Set Mode Register 0
36
  usart->thr = 0;                    //Set Transmit Holding Register 0
37
  
38
  //CONFIG USART1
39
  usart->cr |= (1<<AVR32_USART_CR_TXEN_OFFSET);    //Enable TXE
40
  usart->mr |= (3<<AVR32_USART_MR_CHRL_OFFSET)    //Set Charlength to 8 Bit
41
          | (4<<AVR32_USART_MR_PAR_OFFSET);  //Set No Parity Bit
42
43
  if(baud < (cpuFreq/16))
44
  {
45
    cd = cpuFreq/(8*baud);
46
    usart->mr |= (1<<AVR32_USART_MR_OVER_OFFSET);
47
  }
48
  else
49
  {
50
    cd = cpuFreq/(16*baud);
51
    usart->mr &= ~(1<<AVR32_USART_MR_OVER_OFFSET);
52
  }
53
  
54
  usart->brgr = (cd<<AVR32_USART_BRGR_CD_OFFSET);
55
  
56
  while(1)
57
  {
58
    if((usart->csr & (1<<AVR32_USART_CSR_TXRDY_OFFSET)) != 0)
59
    {
60
      usart->thr |= 0x58;
61
    }
62
  }
63
  
64
  return 0;
65
}

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

von Matthias J. (Gast)


Lesenswert?

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
int main(void){
5
6
  int pin_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

von Lorenz B. (suomi)


Lesenswert?

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.

von Matthias J. (Gast)


Lesenswert?

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

von Lorenz B. (suomi)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.