PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART Problem, mittlere verzweiflung



Ceos
11.10.2008, 13:40
folgender code zur initialisierung

Mega 8 @ 8Mhz intern


//****** Initialisierung (38400 8N1)
UBRRH = 0;
// UBRRL = 13; //nach der formel ausm datasheet isses 13, nach der tabelle weiter unten allerdings 12 !!!!!!!!! was stimmt da nicht ?
UBRRL = 12; // formel falsch interpretiert >_< punkt vor strichrechnung ...
UCSRB = (1<<TXEN);
UCSRC = (1<<UCSZ1) | (1<<UCSZ0);
//****** Sendeteil (in der UDRE ISR)
UDR = 100; //klar definierter wert zum testen


das UDRIE flag wird nach einem timer gesteuert um sendepausen zu erzwingen

ergebnis am comport 38400Baud 8N1

0x00
0x00
0x00
...

loopback hab ich auch schon getestet am com-programm liegts nicht (selbst geschrieben, terminal kommt mit nicht-char werten nich klar)

markusj
11.10.2008, 14:13
Du kannst die Zuweisung des Wertes direkt auf UBRR machen, ohne H und L.
Außerdem ist der interne Oszillator recht ungenau, ohne eine vorherige Kalibrierung (Es gibt auch Tricks, um den Oszi während des Betriebs anhand einer vorgegebenen Zeichenfolge von der seriellen Schnittstelle zu kalibrieren).
Deine Probleme kommen vermutlich vom internen Oszi, als Grundregel gilt eigentlich, dass man einen Quarz benötigt, wenn man den USART nutzen möchte.
Du kannst aber auch versuchen, die Geschwindigkeit extrem zu reduzieren, um die Frequenzfehler zu minimieren.

mfG
Markus

Ceos
11.10.2008, 14:17
naja .... es hat aber BISHER immer auf anhieb funktioniert , aber selbst auf 9600Baud gehts nicht!!! ich versuch mal das proggi zu kopieren, aber mein laptop mag meinen memostick nicht



#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned char TmOt1A;
volatile unsigned char TmOt1B;
volatile unsigned char Settings[2];
volatile unsigned char* Pos;
volatile unsigned char* End;
volatile unsigned int Time32k;
volatile unsigned char ServoVal;
volatile unsigned int ImpVal;


#define ADC0 0
#define ADC1 1
#define ADC2 2
#define ADC3 3
#define ADC4 4
#define ADC5 5
#define ADC6 6
#define ADC7 7

ISR(SIG_UART_DATA)
{
UDR = 100;//*(Pos); //nach dem nur 0 rauskam hab ich mal 100 verwendet
Pos++;
if (Pos > End) {
UCSRB &= ~(1<<UDRIE);
Time32k = 0;
TCNT0 = 0;
TIMSK |= (1<<TOIE0);
}
}

ISR(SIG_OVERFLOW0)
{
if(Time32k++ > 17 && ~(PIND & (1<<PD2))) // 18 Timerclocks sind etwas mehr als UART 2 Byte (sendepause für das easyradio-modul) ausserdem Busy-leitung an PD2
{
TIMSK &= ~(1<<TOIE0);
Pos = Settings;
*(Pos) = ServoVal;
Pos++;
*(Pos) = (unsigned char)(ImpVal>>2);
Pos = Settings;
UCSRB |= (1<<UDRIE);
}
}

//****
ISR(SIG_OUTPUT_COMPARE1A)
{
switch(TmOt1A){
case(1): TCCR1A |= (1<<COM1A1); break;//DDRB |= (1<<PB1); break;
case(2): TCCR1A &= ~(1<<COM1A1); break;//DDRB &= ~(1<<PB1); break;
case(4): TmOt1A = 0; break;
}
TmOt1A++;
}

ISR(SIG_OUTPUT_COMPARE1B)
{
switch(TmOt1B){
case(1): TCCR1A |= (1<<COM1B1); break;
case(2): TCCR1A &= ~(1<<COM1B1); break;
case(4): TmOt1B = 0; break;
}
TmOt1B++;
}

void Timeout32k(unsigned int Tout)
{
Time32k = 0;
while (Time32k < Tout);
return;
}

//*****

int main(void)
{
Time32k = 0;
End = &(Settings[1]);
Pos = Settings;
TmOt1A = 0;
TmOt1B = 0;
ICR1 = 999;
OCR1A = 200;
OCR1B = 200;
DDRB = (1<<PB2) | (1<<PB1);
ADMUX = (1<<REFS0);
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
TCCR1A = (1<<WGM11);// | (1<<COM1A1) | (1<<COM1B1);
TCCR1B = (1<<CS10) | (1<<CS11) | (1<<WGM13) | (1<<WGM12);
TCCR0 = (1<<CS02);
TIMSK = (1<<OCIE1A);// | (1<<OCIE1B);

TCCR1A |= (1<<COM1B1) | (1<<COM1B0);

PORTD |= (1<<PD2);

UBRRH = 0;
UBRRL = 51; // 51 ist 9600, was auch nciht geht sonst 12 für 38400
UCSRB = (1<<TXEN);
UCSRC = (1<<UCSZ1) | (1<<UCSZ0);

//*********** Init ADC circuitry
ADCSRA |= (1<<ADSC) | (1<<ADIF); // start conversion (init ADC)
while (!(ADCSRA & (1<<ADIF))); // wait for very 1st conversion
//*********** Enable Interrupt
sei();
//*********** Start Timing Routine
TCNT0 = 0;
Time32k = 0;
TIMSK |= (1<<TOIE0);
//*********** Main Loop
while(1) {
//*********** Conversion A
ADMUX = (ADMUX & 0xF0) + ADC0; // set ADMUX
ADCSRA |= (1<<ADSC) | (1<<ADIF); // start conversion
while (!(ADCSRA & (1<<ADIF))); // wait for 1st conversion
ADCSRA |= (1<<ADSC) | (1<<ADIF); // discard 1st result
while (!(ADCSRA & (1<<ADIF))); // wait for 2nd conversion
ServoVal = ((unsigned int)(ADC>>2)*200/255);
OCR1A = 120 + ServoVal; // write channel A result
//*********** Conversion B
ADMUX = (ADMUX & 0xF0) + ADC1;
ADCSRA |= (1<<ADSC) | (1<<ADIF);
while (!(ADCSRA & (1<<ADIF)));
ADCSRA |= (1<<ADSC) | (1<<ADIF);
while (!(ADCSRA & (1<<ADIF)));
ImpVal = ADC;
OCR1B = ImpVal; // write channel B result
}
return 0;
}



EDIT: selbst mit 16Mhz Quarz passiert nix, UBBR hab ich auf 103 geändert um 9600 Baud beizubehalten immernoch 0x00

Ceos
11.10.2008, 14:58
..... ohhhhhhhh wie ich das hasse ..... schon wieder (1<<URSEL) beim UCSRC vergessen ..... MANNMANNMANN ... problem gelöst ...