PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : XMega UART funktioniert nicht



Kampi
30.03.2012, 20:32
Hallo Forum,

ich versuche gerade den UART meines XMegas zum laufen zu bringen.
An den Pins C2 und C3 befindet sich ein XBee welches über Funk die Daten an einen PC senden soll. Die Kommunikation zwischen den XBees funktioniert auch. Das XBee ist direkt an den XMega128 angeschlossen und beides wird mit 3,3V betrieben.
Nun versuche ich, wie gesagt, Daten an den PC zu senden aber am Terminal erscheint nichts.
Das ganze soll über 19200 Baud laufen.
Ich verwende folgenden Code:



/*
* XMega.c
*
* Timer C0 wird ist auf 1 Sekunde eingestellt. Jede Sekunde wird die Ausgangsspannung des DACB um 1 erhöht.
* Timer D0 generiert eine PWM.
*
* Created: 22.03.2012 19:42:07
* Author: Daniel
*/

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stddef.h>
#include <avr/pgmspace.h>

// Makros
#define nop() asm volatile ("nop") // "NOP" als Makro definieren

// Peripherie
unsigned char ADCA_Conversion(char Channel);
void DACB_Conversion(int Voltage);

// Variablen
volatile char ADC_Value = 0x00;
volatile int Voltage = 0x00;
volatile int Compare = 0x0064;
volatile int ADC_Calibrationbyte; // Buffer für ADC Kalibrationswert
volatile int Zaehler = 0x47;

int main(void)
{
Clock_init(); // Konfiguriert die Clock
//PLL_init(); // PLL konfigurieren
Int_init(); // Interrupts konfigurieren
DACA_Cal(); // DACA kalibrieren
DACB_init(); // DACA konfigurieren
ADCA_Cal(); // ADCA kalibrieren
ADCA_init(); // ADCA konfigurieren
TimerC0_init(); // Timer C0 konfigurieren
TimerD0_init(); // Timer D0 konfigurieren
Port_init(); // Ports konfigurieren
UART_init(); // UART konfigurieren
DMA_init(); // DMA Controller initialisieren

while(1)
{
// ADC_Value = ADCA_Conversion(0);
// DACB_Conversion(Voltage);
// TimerD0_Compare(Compare);
// TimerC0_Freq(0XB719);
PORTA.OUT ^= 0x01;
Send_UART(&Zaehler);
}
}


void DACB_init()
{
DACB.CTRLC = ~(DAC_REFSEL_gm | DAC_LEFTADJ_bm); // Interne 1V Referenz, right adjust (12 Bit);
DACB.CTRLA = (DAC_CH0EN_bm | DAC_ENABLE_bm); // 1CLK Takt, Refresh 16CLKs
// DACB.TIMCTRL = 0x00;
// DAC aktivieren
}

void ADCA_init()
{
ADCA.CTRLA = 0x01; // ADC Enable
ADCA.CTRLB = 0x04; // Unsigned Mode / 8 Bit
ADCA.REFCTRL = 0x00; // Interne 1.0V Referenz
}

void Clock_init(void)
{
OSC.CTRL |= OSC_RC32MEN_bm; // Oszillator auf 32Mhz stellen
while(!(OSC.STATUS & OSC_RC32MRDY_bm)); // Warten bis der Oszillator bereit ist
CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_RC32M_gc; // Clock auf 32MHz stellen
//CLK.PSCTRL = 0x02; // Prescaler A = CLK/2, Prescaler B/C = CLK/1
}

void PLL_init(void)
{
OSC.PLLCTRL = OSC_PLLSRC_RC32M_gc | 0x06; // PLL auf internen 32MHz Takt stellen und den Multiplikator festlegen
OSC.CTRL |= OSC_PLLEN_bm; // PLL-Enable Bit setzen
while (!(OSC.STATUS & OSC_PLLRDY_bm)); // Warten bis PLL bereit ist
CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_PLL_gc; // PLL als Clock auswählen
}

void Int_init(void)
{
PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; // Interrupts (Highlevel,Mediumlevel und Lowlevel freigeben)
sei(); // Globale Interruptfreigabe
}

void Port_init(void)
{
PORTA.DIR = 0xFF; // Kompletten Port A auf Ausgang stellen
PORTB.DIR = 0xFF; // Kompletten Port B auf Ausgang stellen
PORTC.DIR = 0xFF; // Kompletten Port C auf Ausgang stellen
PORTD.DIR = 0xFF; // Kompletten Port D auf Ausgang stellen
PORTCFG.CLKEVOUT = 0x01; // Takt auf einem Pin ausgeben. 0x01 = C.7
// 0x02 = D.7
// 0x03 = E.7
// UART
PORTC.DIRSET = PIN3_bm; // PC3 (TXD0) Output
PORTC.DIRCLR = PIN2_bm; // PC2 (RXD0) Input
}

void TimerC0_init()
{
TCC0.CTRLA = TC_CLKSEL_DIV1024_gc; // Vorteiler einstellen
TCC0.CTRLB = 0x00; // Timer in Normalmodus stellen
TCC0.INTCTRLA = 0x03; // Interrupt konfigurieren
}

void TimerC0_Freq(int TTW)
{
TCC0.PER = TTW; // Timer-Topwert(TTW) einstellen
}

void TimerD0_init(void)
{
TCD0.PER = 0xffff; // Timertopwert
TCD0.CTRLA = 0x03; // Prescaler 4
TCD0.CTRLB = 0x83; // BIT0/1 = Single Slope PWM
// BIT7 = OCD
}

void TimerD0_Compare(int Compare)
{
TCD0.CCD = Compare; // Compare Register laden
}

void UART_init(void)
{
USARTC0_CTRLB = USART_TXEN_bm | USART_RXEN_bm; // Sender und Empfänger aktivieren
USARTC0_CTRLC = USART_CHSIZE_8BIT_gc | USART_CMODE_SYNCHRONOUS_gc | USART_PMODE_DISABLED_gc;; // 8 Bit, 1 Stopbit, keine Parität, Synchroner USART
USARTC0_BAUDCTRLA = 0x42; // Baudrate 19200; Bitmuster 0011 0100 0010 oder 0x0342
USARTC0_BAUDCTRLB = 0x03;
}

void DMA_init(void)
{

}

void Send_UART(char *data)
{
while ((USARTC0.STATUS & USART_DREIF_bm) == 0);
USARTC0.DATA= data;
}

unsigned char ADCA_Conversion(char Channel)
{
ADCA_CH0_MUXCTRL = Channel; // Kanal auswählen
ADCA.CH0.CTRL = 0x81; // Messung starten und Input-Mode auf Singleended stellen
return ADCA_CH0RES;
}

void DACB_Conversion(int Voltage)
{
DACB.CH0DATA = Voltage;
while (!DACB.STATUS & DAC_CH0DRE_bm) ;
}

void Read_Calibrationbyte(void)
{
}

void ADCA_Cal(void)
{
}

void DACA_Cal(void)
{

}

ISR(TCC0_OVF_vect)
{
Voltage = Voltage + 100;
Compare = Compare + 100;
}


Das Unterprogramm zum senden der Daten wird auch erfolgreich durchgearbeiter. Ich habs mittels Pin togglen und mittels Oszi geprüft.
Danke für die Hilfe.

ePyx
31.03.2012, 08:53
Hast du mal den Code von das AVR-AppNote ausprobiert ? Ist denke ich der einfachste Weg um zu schauen, ob es an deinem Code liegt.

Kampi
31.03.2012, 18:17
Hey,

danke für den Tipp. Ich probier den mal aus.

Happy Jack
01.04.2012, 22:55
Hallo,

mir sind zwei Sachen aufgefallen:

die Übertragung ist asynchron, CTRLB = 0b00000011; // 8N1

die Baudrate ist falsch eingestellt. Für 32MHz CPU-Takt ist BAUDCTRLA = 103 und BAUDCTRLB = 0

Hans

Kampi
02.04.2012, 05:53
Hi,

danke für den Hinweis. Ich probier das heute mittag mal. Ich hab derweil auch nen Fehler gefunden. Anscheinend wird ein XBee nicht mehr über UART angesprochen. Ich hab aber keine Ahnung ob ich es falsch konfiguriert habe und wie ich die Konfiguration rausfinden kann oder ob es kaputt ist :/