XMEGA128A1 Pin einlesen

Gast #3490960
Lesenswert?

Hallo Zusammen,

ich arbeite mich gerade in die Welt der µC und habe ein Problem.

Das schalten der Pins als Ausgang hat funktioniert. Jetzt möchte ich den 
Eingang einlesen. Habe dazu folgenden simplen Code geschrieben. Dieser 
wird ausgeführt (ohne Fehler) jedoch funktioniert nichts.


Wo ist der Fehler in meinem Code?
Wenn ich den Taster drücke <--> loslasse sollte sich doch etwas tun?




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

void io_init(void);
void clock_init(void);

int main(void){

  clock_init();
  io_init();

  while(1){
    PORTE.IN = PORTE.OUT;
    }

  return 0;
}
void io_init(void){
  PORTE.DIR = 0xff;
  PORTE.DIR = 0x00;

}


void clock_init(void){
  //Oszillator auf 32Mhz stellen
  OSC.CTRL |= OSC_RC32MEN_bm;
  // Warten bis der Oszillator bereit ist
  while(!(OSC.STATUS & OSC_RC2MEN_bm));
  //Schützt I/O Register, Interrupts werden ignoriert
  CCP = CCP_IOREG_gc;
  //aktiviert den internen Oszillator
  CLK.CTRL = (CLK.CTRL & ~CLK_SCLKSEL_gm) | CLK_SCLKSEL_RC32M_gc;
}




Vielen Dank.

Gruß,
Stefan
Gast #3491080
Lesenswert?

ich habe den Code geändert. Leider ist da scheinbar noch ein Fehler 
drin.

Hat noch jemand ein Idee?




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

void io_init(void);
void clock_init(void);

int main(void){

  clock_init();
  io_init();

  char Taster;

  while(1){

    Taster = PORTD.IN;

    PORTE.OUT = Taster;

    }

  return 0;
}
void io_init(void){
  PORTE.DIR = 0xff;
  PORTE.DIR = 0x00;

}


void clock_init(void){
  //Oszillator auf 32Mhz stellen
  OSC.CTRL |= OSC_RC32MEN_bm;
  // Warten bis der Oszillator bereit ist
  while(!(OSC.STATUS & OSC_RC2MEN_bm));
  //Schützt I/O Register, Interrupts werden ignoriert
  CCP = CCP_IOREG_gc;
  //aktiviert den internen Oszillator
  CLK.CTRL = (CLK.CTRL & ~CLK_SCLKSEL_gm) | CLK_SCLKSEL_RC32M_gc;
}



Danke!
#3491429
Lesenswert?

Hallo Stefan,

wie ist Dein xmega beschaltet?
Leds über Vorwiderstand von Port E an VCC oder GND?
Taster mit Pullup / Pulldownwiderstand an Port D?
Funktioniert das Ein- Ausschalten einzelner LEDS?
Wenn Du z.B. statt
    Taster = PORTD.IN;

    Taster = 0x55;
schreibst, leuchtet dann jede 2. Led?
Hast Du einen Debugger?
Wenn ja, ändert sich das PORTD.IN-Register wenn Du eine Taste drückst?

Grüße, Robert.
Gast #3491750
Lesenswert?

Ich benutze ein Evalboard: Xplained 128A1 mit einem ARV Dragon.

Die Ausgänge sind getestet d.h. mit einem anderen Code schaltbar.


Wo ich leider nicht weiterkomme ist die Taster vom Evalboard einzulesen.
#3491783
Lesenswert?

Beim Xplained 128A1-Board sind die Taster mit Vorwiderständen gegen 
Masse geschaltet. Um definierte Zustände einzulesen musst Du vorher 
interne Pullup-Widerstände zuschalten. z.B.
    PORTD.PIN0CTRL |= PORT_OPC_PULLUP_gc
    PORTD.PIN1CTRL |= PORT_OPC_PULLUP_gc
...

Probier das mal aus.

Grüße,
Robert.
Gast #3493116
Lesenswert?

Danke Robert du hast mir geholfen.

Es war jedoch noch etwas nicht vollständig:

Im Datenblatt steht dass:

"The input is not sampled and cannot be read if the digital input 
buffers are disabled."

Es fehlte also zusätzlich noch die Anweisung:

PORTD.PIN0CTRL |= PORT_ISC_BOTHEDGES_gc;

Danach ging es.

Danke allen die geholfen haben.


Gruß,
Stefan
#3493366
Lesenswert?

Bzw. das Digital Inputbuffer Disable ist für PINs gedacht, die nur für 
Analoge Signale verwendet werden (also die Ports die am ADC hängen, also 
PORTA und PORTB). Damit kann man etwas Strom sparen. Dieser steht nach 
dem Reset eh auf PORT_ISC_BOTHEDGES. Solange du nach dem Reset dort 
nichts gemacht hast, was ja nach deinem geposteten Code nicht der Fall 
ist ändert das also nicht. Alle anderen Werte außer INTPUT_DISABLE haben 
nur Einfluss auf die Interrupt Funktionalität (wenngleich zumindest 
einer davon eingestellt sein muss damit der Pin überhaupt funktioniert)

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