Select Language!
XMegaXMega

XMega

Mit der XMega Reihe hat Atmel einen würdigen Nachfolger der ATMegas geschaffen. Die technischen Daten lassen das Bastlerherz höher schlagen. Zahlreiche Timer, priorisierbare Interrupts, viele USARTs und Einstellmöglichkeiten lassen keine Wünsche offen. Jedoch birgt das auch einen Nachteil. Die Anzahl der Register hat zugenommen und dadurch geht ohne Blick ins Datasheet beim Programmieren nichts mehr.

Den Hardwareeinstieg macht Atmel durch das XPlain recht einfach. Erste Schritte mit der Software gelingen mit Hilfe der Seite von Florian. http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial

Der Quellcode wertet das Poti auf dem Modul aus und sendet die Daten über die USB-Buchse zum PC. Dort können die Daten mit einem Terminalprogramm angesehen werden.

 

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>

static int uart_putchar(char c, FILE *stream);
static void uart_init (void);
static void clock_init (void);
static void dir_init (void);
static void timer1_init (void);
static void adc_init(void);
static FILE mystdout = FDEV_SETUP_STREAM (uart_putchar, NULL, _FDEV_SETUP_WRITE);
       
int main (void) {            

clock_init();
dir_init();
timer1_init();
uart_init();
adc_init();
stdout = &mystdout;
PORTB.PIN1CTRL = 0x18;
uint16_t temp;
   while(1) {                

                        ADCB.CH1.CTRL |= 0x80;
                        while(!(ADCB.CH1.INTFLAGS && 0x01));
                        temp = ADCB.CH1.RES;
                        ADCB.CH1.INTFLAGS = 0x01;
                        _delay_ms(200);
                printf("\n%i",temp);
                        }
                        return 0;                
}


static int uart_putchar (char c, FILE *stream)
{
    if (c == '\n')
        uart_putchar('\r', stream);
    // Wait for the transmit buffer to be empty
    while ( !( USARTC0.STATUS & USART_DREIF_bm) );
    // Put our character into the transmit buffer
    USARTC0.DATA = c;  
    return 0;
}

static void uart_init (void)
{
    // Set the TxD pin high - set PORTC DIR register bit 3 to 1
    PORTC.OUTSET = PIN3_bm;
 
    // Set the TxD pin as an output - set PORTC OUT register bit 3 to 1
    PORTC.DIRSET = PIN3_bm;
 
    // Set baud rate & frame format
    USARTC0.BAUDCTRLB = 0;                      // BSCALE = 0 as well
    USARTC0.BAUDCTRLA = 215;
 
    // Set mode of operation
    USARTC0.CTRLA = 0;                          // no interrupts please
    USARTC0.CTRLC = 0x03;                       // async, no parity, 8 bit data, 1 stop bit
 
    // Enable transmitter only
    USARTC0.CTRLB = USART_TXEN_bm;
}
 
void clock_init(void){
        /*Oscillator auf 32Mhz einstellen*/
   OSC.CTRL = OSC_RC32MEN_bm;
   // Warten bis Oszillator stabil ist
   while ((OSC.STATUS & OSC_RC32MRDY_bm) == 0);
   // System Clock selection
   CCP = CCP_IOREG_gc;
   CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
   // DFLL ein (Auto Kalibrierung)
   DFLLRC32M.CTRL = DFLL_ENABLE_bm;
}

void dir_init(void){

        PORTE.DIR |= (1<<PIN4);
}



void timer1_init(void){
   //BIT0/1 = Single Slope PWM //
   //BIT4 = OCA BIT5 = OCB Enable//
   TCE1.CTRLB = 0x13;
   /*Timerstartwert*/
   TCE1.PER = 0xff;
   /*4 Vorteiler*/
   TCE1.CTRLA = 0x01;
}

void adc_init(void){
                ADCB.CTRLA = 0x01;
                ADCB.CTRLB = 0x00;
                ADCB.REFCTRL = 0x10;
                ADCB.PRESCALER = 0x02;
                ADCB.CH1.CTRL = 0x01;
                ADCB.CH1.MUXCTRL = 0x08;
                ADCB.CH1.INTCTRL = 0x00;
}