empfangen von char * aus UART des AVR
Möchte ich erhalten einen string(Zeiger auf Zeichen) von UART mit ATMEGA16. Ich brannte Sie diesen code auf das kit dann habe ich hyperterminal (realterm) und machte einen test input ein string ("auf") und wenn es empfangen wird, dann portc (LED) wird auf 1 gesetzt, aber es funktioniert nicht ... jemand!? 😀
Implementierung von Funktionen
#include <avr/io.h>
#define F_CPU 8000000UL
unsigned char *x;
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
void uartinit()
{
UCSRB |= (1 << RXEN) | (1 << TXEN);
//Turn on the transmission and reception circuitry
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
//Use 8-bit character sizes
UBRRL = BAUD_PRESCALE; //Load lower 8-bits of the baud rate value..
//into the low byte of the UBRR register
UBRRH = (BAUD_PRESCALE >> 8); //Load upper 8-bits of the baud rate value..
//into the high byte of the UBRR register
}
void uartsend( unsigned char *data )
{
while(*data != '\0')
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) );
/* Put data into buffer, sends the data */
UDR = *data;
data++;
}
while ( !( UCSRA & (1<<UDRE)) );
UDR = *data;
}
unsigned char * uartrecieve()
{
//unsigned char i=0;
// unsigned char * x;
/* Wait for data to be received */
// char * ptr = &UDR;
while ( !(UCSRA & (1<<RXC)) );
while(UDR != '\0')
{
*x = UDR;
x++;
while ( !(UCSRA & (1<<RXC)) );
}
*x = UDR;
return x;
}
- und das ist eine wichtige Funktion
#include <avr/io.h>
#include "UARTInterface.h"
int main(void)
{
DDRC=0xFF;
uartinit();
while(1)
{
unsigned char *y;
y=uartrecieve();
if(strcmp(y,"on")==0)
{
PORTC=0xff;
}
//uartsend(y);
//TODO:: Please write your application code
}
}
FYI, die gebaut-in Uhr auf dem AVR nicht genau genug für die richtige serial comms. Sollten Sie wirklich verwenden Sie ein ordnungsgemäß abgestimmt Quarz für die Uhr. Ich würde vorschlagen, Lesen Sie die AVR-Freaks und tun einige Recherchen gibt es, wie auch, die Seite ist 100% gewidmet AVR, und hat viele Beispiele, Artikel. Siehe auch diesem Artikel
Erstes problem, Sie muss die Daten in ein array kein pointer.
Die Uhr funktioniert einwandfrei. Auch mocj richtig ist.
Um zu klären, was @mocj ist zu sagen, der string-Vergleich wird garantiert, um auszufallen. x ist Global definiert einen Zeiger irgendwo im Speicher. (Es wird sich wohl zeigen, in die interrupt-Tabelle.) Sie füllen sich, die Lage, der fortschreitenden x, dann wieder die Letzte position x Punkte zu. Diese Position enthält das Zeichen '\0', kein 'n' an. Sie brauchen, um zu reservieren ein array zum speichern der Daten, und legen Sie x, um zu Punkt, um den start der Funktion erhalten. Tun Sie den string-Vergleich mit dem Anfang des Arrays.
Erstes problem, Sie muss die Daten in ein array kein pointer.
Die Uhr funktioniert einwandfrei. Auch mocj richtig ist.
Um zu klären, was @mocj ist zu sagen, der string-Vergleich wird garantiert, um auszufallen. x ist Global definiert einen Zeiger irgendwo im Speicher. (Es wird sich wohl zeigen, in die interrupt-Tabelle.) Sie füllen sich, die Lage, der fortschreitenden x, dann wieder die Letzte position x Punkte zu. Diese Position enthält das Zeichen '\0', kein 'n' an. Sie brauchen, um zu reservieren ein array zum speichern der Daten, und legen Sie x, um zu Punkt, um den start der Funktion erhalten. Tun Sie den string-Vergleich mit dem Anfang des Arrays.
InformationsquelleAutor MGaafar | 2014-02-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es ein paar Probleme mit dem code:
1. Du bist nicht die Zuweisung jeder Platz für die empfangenen Zeichen. Sie haben eine Globale
unsigned char *x
(nicht initialisiert), die Sie dereferenzieren und Werte zuweisen, dann erhöht dies nur überschreiben zufällige Positionen im Speicher.Sollten Sie stattdessen weisen Sie Speicherplatz durch erstellen eines array in der aufrufenden Funktion (
main
in diesem Fall) und übergeben Sie einen Zeiger aufuartreceive
zusammen mit der Größe des PuffersDann (beachten Sie, dies ist nicht getestet)
Jedes mal, wenn Sie diese Funktion aufrufen, überschreiben den vorherigen Inhalt der rx_buffer, so stellen Sie sicher, dass Sie fertig sind mit es zuerst. Lesen Sie auf arrays, Zeiger und strings, wenn Sie sich nicht sicher, was hier passiert.
Besser noch wäre: im einen Zeiger auf
uartreceive
so, dass die aufrufende Funktion liefern können, den Bereich des Speichers2. Es ist unwahrscheinlich, dass Ihre serielle terminal-software wird das senden von NULL-terminierte " strings per default (d.h. mit '\0' am Ende), normalerweise senden Sie eine neue Zeile ('\n') Zeichen. Ich glaube, realterm kann dies tun, aber es lohnt sich.
3. Das Lesen von UDR wird klar, dass das RXC-flag, so dass der AVR zu schreiben, ein anderes Zeichen in UDR, also das Lesen von UDR zweimal in Folge ist wahrscheinlich eine schlechte Idee
InformationsquelleAutor Peter Gibson