Ik heb een vrij basic opstelling: Atmega328P een MaxSonar uitlezen via UART.
Deze Sonar sensoren spugen non stop data uit in de vorm R234\r

Maar mijn UDR0 register blijft vage waarden geven, terwijl op de scope alle berichten wel leesbaar zijn.

Mijn gestripte ISR ziet er nu als volgt uit.


ISR (USART_RX_vect)
{
	cli();
	
	//rx_buffer[4] = UDR0;

	// Valid reading
	if (UDR0 == 'y') {
		
		_STATUS_LED_TOGGLE();
	}
	
	sei();
}

De led toggled inderdaad omdat hij character "y" steeds ziet, wat een total random waarde is.

Ik zie vooral char waarden. 30, 0 en 121 voorbij komen.

Mijn UART is als volgt geconfigureerd:


void UART_Init( unsigned int ubrr)
{
	// Set baud rate 
	UBRR0H = ubrr>>8;
	UBRR0L = ubrr;
	
	// Enable receiver and transmitter 
	//UCSR0A = (0<<U2X0);
	UCSR0A |= (1 << RXC0);
	UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
	
	// Set frame format: 8 bit, no parity, 1 stop bit,   
	UCSR0C |= (1<<UCSZ00)|(1<<UCSZ01);
	
	stdout = &mystdout; //Required for printf init
	//stdin = &mystdin;
	
}

[Bericht gewijzigd door spruce op (27%)]

Lijkt of foute baudrate?

Wordt ingesteld met ubrr. De waarde is afhankelijk van de snelheid van de processor klok en de gewenste baudrate.

Bij foute waarde krijg je foute data in udr.

Klinkt als ergens een incorrecte bitrate.

Verder erg tricky om in een ISR nog een keer met de IRQenable flag aan de gang te gaan. Beetje vragen om ellende, maar dat staat los van je huidige probleem (hoop ik).

Een open deur (ik ken de IRQ vectoren niet uit m'n hoofd, dus waarschijnlijk is het onzin wat hier staat): Je hebt wel de juiste vector te pakken? Ik zou in die vectornaam ook een '0' verwachten. Ik kan me zo voorstellen als je op wat anders triggert, je braaf garbage staat te lezen.

De bitrate zou goed moeten zijn 9600 8N1
Dit heeft voorheen ook braaf gewerkt toen ik nog een stdin FILE stream liet echoen naar stdout.

Sinds de ISR constructie werkt het niet meer.
Het lijkt erop alsof UDR0 al word overschreven of iets dergelijks?

De stdin stream maakt gebruik van de volgende functie:


char uart_getchar(FILE *stream) {
	loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
	return UDR0;
}

Daarmee lees ik wel de juiste data uit, via ISR lukt het niet.

Da's spannend. Dan lijkt het er toch op dat je ISR op iets verkeerds triggert.

Nou loop je lang genoeg mee in C-land, maar ik trap de deur toch nog maar een keer in:

  • Weet jij hoe vaak je UDR0 mag lezen zonder het ding 'stuk' te maken? (waarschijnlijk net zo lang tot er een volgende byte binnen komt, maar ik ken de documentatie niet uit m'n hoofd)
  • rx_buffer heb je natuurlijk als volatile gedeclareerd

Verder geen antwoord op de vraag of je de juiste ISR te pakken hebt. Kijk eens bij je compiler documentatie. Ik *denk* dat het wel goed zit, maar iets met assumptions & fuck-ups.

En geheel terzijde, iirc ging op zijn minst die cli automatisch aan het begin van een ISR. (Maargoed, dat scheel 1 asm instructie, 2 mocht de sei ook automagisch al door de compiler worden toegevoegd bij het eind-} van een ISR.)

[edit]Hier stond onzin; verkeerde controller in gedachten[/edit]
Kwaad kan het zo op het eerste gezicht niet. Zinnig is het ook niet.

[Bericht gewijzigd door EricP op (15%)]

Het verhaal dat ik vertelde dat stdin -> stdout echo wel heeft gewerkt gaat niet op. De echo is zogoed als zeker een typ actie in de terminal zelf.

Dus lang een character indrukken op je toetsenbord geeft in dit geval geen garanties dat het een echo vanuit de microcontroller betrof.

Neem een terminal programma dat onderscheid maakt tussen verzonden en ontvangen karakters...

De bevindingen tot nu toe:

Device: ATmega328P
F_CPU: 8000000
Fuse CKDIV8 = unset

- Laat ik een LED toggelen in een voor de rest lege while loop, dan meet ik op de scope 808kHz!

- RS232 data vanaf de sonar sensor is 9600n8 data en leesbaar op de scope, maar garbage voor de UART read code. Maar logisch omdat de baud rate settings uit gaan van 8Mhz.

- Wonderbaarlijk genoeg is UART uit op de microntroller pin ook onleesbaar, maar nadat hij en FTDI chip is gepasseerd is het leesbaar op een 9600n8 terminal. :p

Waar ik vooral naar op zoek moet is waarom de microcontroller op zijn interne 8Mhz crystal maar rond 800kHz draait.

Wazig verhaal...
Als de clock niet goed is kan ook de UART Tx niet werken (op de juiste baudrate), en dat doet íe wel volgens jou...

Stiekem toch CKDIV8 geset (CKDIV8=0 moet 1 zijn), dat zou misschien die 800kHz kunnen verklaren.

Super vreemd inderdaad.
Zou de FTDI driver soms bij benadering zichzelf aanpassen?

[edit]
Clock meten via een led toggle is niet heel erg accuraat, als ik via een CKOUT meet kom ik wel op 8MHz. Dus nu weer focus op baud rate calculatie

Inmiddels BAUD naar 1200 verlaagd.
Leesbaar op de terminal via een FTDI chip.
Op de scope vrijwel onleesbaar, je ziet wel flarden van juiste data, maar een hele hoop framing errors en onleesbare character tussendoor.

Instabiele interne clock? En dat de FTDI chip slimmer is dan de Tektronix analyse om er nog wat leesbaars van te maken?

TX output van micro moet gewoon stabiel zijn. Als dat zwabbert dan is de chip kapot (misschien de driver opgeblazen?)

Ik geloof dat ik het probleem heb gevonden.
De fabrikant van Sonar module gebruikt rs232 maar op TTL niveau :P

Nu een hardware inverter tussen gezet en rechtstreeks op de UART