xmega_Unklarheiten

Gast #3805340
Lesenswert?

Hallo ich setze mich mit dem ATXMEGA32E5 auseinander dabei sind mir ein 
paar Sachen unklar vermute es ist was xmega spezifisches.


Folgendes Programm funktioniert soweit, aber warum muss ich in der main 
den PORTD(4)auf high setzen nachdem ich den als Ausgang definiert habe 
tu ich es nicht leuchtet die LED am PORTD(4) sofort. Dann die zweite 
Sachen das einlesen von dem Taster an PORTD(0) geht nur über 
bitmanipulation nicht über den Direktbefehl PORTD.IN gibt es da einen 
anderen Befehl bei xmega bzw. wie kann ich nur den einen PIN0 an PORTD 
einlesen nicht gleich den ganz PORTD.

Kann mir einer bitte weiter helfen?


#include <avr/io.h>
#define F_CPU 8000000
#include <util/delay.h>



int main(void)
{

  PORTD.DIR |= PIN4_bm;
  PORTD.OUT |= PIN4_bm;



  PORTD.DIR &= ~PIN0_bm;
  PORTD.PIN0CTRL |= PORT_OPC_PULLUP_gc;

  uint8_t tastenwert_vorher = 1,tastenwert_jetzt = 0;
  uint8_t anzahl = 0;
  uint8_t i;

  while(1)
    {
      tastenwert_jetzt = PORTD.IN & 0x01;

    if (tastenwert_jetzt != tastenwert_vorher)
    {
      if(tastenwert_jetzt == 0)
      {
      anzahl++;
      }
        switch (anzahl)
        {
          case 1: PORTD.OUT &= ~PIN4_bm;
              break;

          case 2: PORTD.OUT |= PIN4_bm;
              break;

          case 3: for (i=0; i<= 9; i++)
              {
                _delay_ms(200);
                PORTD.OUTTGL = (1 << PIN4);

              }


          default: anzahl = 0;
        }

    }

  tastenwert_vorher=tastenwert_jetzt;
  _delay_ms(10);

     }
}
(Firma: TravelRec.) Persönliche Seite #3805558
Lesenswert?

xmeganewbe schrieb:
> aber warum muss ich in der main
> den PORTD(4)auf high setzen nachdem ich den als Ausgang definiert habe
> tu ich es nicht leuchtet die LED am PORTD(4) sofort

Schaltung?

xmeganewbe schrieb:
> das einlesen von dem Taster an PORTD(0) geht nur über
> bitmanipulation nicht über den Direktbefehl PORTD.IN gibt es da einen
> anderen Befehl bei xmega bzw. wie kann ich nur den einen PIN0 an PORTD
> einlesen nicht gleich den ganz PORTD.

Sichwort: Virtuelle Ports. Funktionieren wie beim Mega.
#3805695
Lesenswert?

Knut Ballhause schrieb:
> Sichwort: Virtuelle Ports. Funktionieren wie beim Mega.

Ich habe bisher noch nicht mit der Xmega-E-Serie gearbeitet und daher 
die Doku  unter 
http://www.atmel.com/Images/Atmel-42005-8-and-16-bit-AVR-Microcontrollers-XMEGA-E_Manual.pdf 
nach den Virtuellen Ports durchgesucht.
Dabei habe ich keine Register für das Portmapping wie bei den anderen 
Xmegas (VPCTRLA und VPCTRLB) gefunden. Im AVR-Studio 6.2 habe ich dazu 
ebenfalls nichts gefunden.
Nun würde mich interessieren wie hier das Portmapping funktioniert.
#3805741
Lesenswert?

xmeganewbe schrieb:
> Folgendes Programm funktioniert soweit, aber warum muss ich in der main
> den PORTD(4)auf high setzen nachdem ich den als Ausgang definiert habe
> tu ich es nicht leuchtet die LED am PORTD(4) sofort.

Reset-Value von OUT ist "0". Wie ist die LED an dem Pin angeschlossen?

Robert W. schrieb:
> nach den Virtuellen Ports durchgesucht.
> Dabei habe ich keine Register für das Portmapping wie bei den anderen
> Xmegas (VPCTRLA und VPCTRLB) gefunden. Im AVR-Studio 6.2 habe ich dazu
> ebenfalls nichts gefunden.

Liegt wohl daran dass bei der E-Serie die virtuellen Ports nicht 
verstellbar sind, darum steht auch in der Address Map für VPORT0...3 in 
der Description auch Virtual Port A, C, D, R
Gast #3805998
Lesenswert?

Timmo H. schrieb:

> Reset-Value von OUT ist "0". Wie ist die LED an dem Pin angeschlossen?
>
die LED ist an vcc angeschloßen und wird mit dem pin vom µcontroller zur 
gnd geschaltet.

Die Frage warum reicht es schon aus wenn ich nur den Befehl PORTD.DIR |= 
PIN4_bm; ausführe das die LED sofort leuchtet normalerweise müsste es 
doch erst leuchten wenn ich PORTD.OUT &= ~ PIN4_bm; so kenne ich das von 
der mega Reihe oder ist es bei der xmega Reihe anders?

xmeganewbe schrieb:
> wie kann ich nur den einen PIN0 an PORTD
> einlesen nicht gleich den ganz PORTD.

gibt es da spezielle Befehle?

mittlerweile bin ich bei Timern angekommen und habe nun folgendes 
Problem der Befehl TCC0.CTRLA = TC_CLKSEL_DIV256_gc;

funktioniert auch nicht bekomme folgende Fehlermeldung im Atmel Studio:

Error  3  'TC_CLKSEL_DIV256_gc' undeclared (first use in this function)

warum?
#3806083
Lesenswert?

Hallo,

soweit ich im Datenblatt nachgelesen habe, gibt es beim E5 keinen TCC0.
Du kannst den TCC4 oder den TCC5 verwenden und der korrekte Befehl 
lautet:
TCC4.CTRLA = TC45_CLKSEL_DIV256_gc;

Das virtuelle Port D (=VPORT2), Pin 0 müsstest Du wie folgt einlesen 
können:
  if(VPORT2_IN && PIN0_bm){
    ... Code
  }
#3806163
Lesenswert?

xmeganewbe schrieb:
> Timmo H. schrieb:
>
>> Reset-Value von OUT ist "0". Wie ist die LED an dem Pin angeschlossen?
>>
> die LED ist an vcc angeschloßen und wird mit dem pin vom µcontroller zur
> gnd geschaltet.
>
> Die Frage warum reicht es schon aus wenn ich nur den Befehl PORTD.DIR |=
> PIN4_bm; ausführe das die LED sofort leuchtet normalerweise müsste es
> doch erst leuchten wenn ich PORTD.OUT &= ~ PIN4_bm; so kenne ich das von
> der mega Reihe oder ist es bei der xmega Reihe anders?
Das Bit im OUT.Register ist nach einem Reset schon 0, wenn du mit DIR 
auf Ausgang schaltest geht der Ausgang logischer weise auf GND und deine 
nach Vcc geschaltet LED leuchtet. Willst du das vermeinden, dann musst 
du erst mal das Bit im OUT.Register auf 1 setzen und dann erst auf 
Ausgang schalten.
Im übrigen ist dieses Verhalten bei allen AVRs so!

Sascha
Gast #3814275
Lesenswert?

Hallo versuche mich grad am Timer des xmega32E5 leider wird nicht so wie 
erwartet im 500ms takt der PORTD.4 getoggelt.


Sieht einer den Fehler?



#include <avr/io.h>
#include <avr/interrupt.h>

void timer_init (void); /* Funktionsprototyp */

uint16_t timerzeit = 500;

int main(void)
{
    PORTD.DIR |= PIN4_bm;
  timer_init();

  while(1)
    {
        if (timerzeit <= 0)
    {
      PORTD.OUTTGL = (1 << PIN4);
      timerzeit = 500;
    }
    }
return 0;
}

ISR(TCC4_OVF_vect)
{
  timerzeit--;
  if(timerzeit <= 0)
  {
    timerzeit = 0;
  }
}


void timer_init (void)
{
  cli();
  TCC4.CTRLA = TC45_CLKSEL_DIV256_gc;    /* Vorteiler auf 256 
eingestellt */
  TCC4.CTRLB = 0x00;    /* Mode normal top hochzählen */
  TCC4.PER = 31;    /* Timertopwert 31 ergibt 1 ms */
  TCC4.INTCTRLA = 0x03; /* Interrupt Modus aktiv */
  PMIC.CTRL = 0x07;    /* Interrupt Priorität festgelegt */
  TCC4.CNT = 0x00; /* Zählerstartwert auf 0 gesetzt */
  sei();
}
#3814381
Lesenswert?

Hallo,

nachdem Du die Variable uint16_t timerzeit in der main() und der ISR() 
verwendest, solltest Du sie als volatile deklarieren:
volatile uint16_t timerzeit= 500;

und ein uint16_t kann nicht kleiner als 0 werden, daher ist die Abfrage 
in der ISR unnötig. Evtl könntest Du den Überlauf prüfen indem Du die 
Abfrage auf :
  if(timerzeit >500)
  {
    timerzeit = 0;
  }
änderst.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren