C语言 从 AVR 的 UART 接收字符 *
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21560230/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
receiving char * from UART of AVR
提问by MGaafar
I want to receive a string(pointer to characters) by UART using ATMEGA16. I burned this code on the kit then I used hyperterminal (realterm) and made a test to input a string ("on") and if it is received then portc (LEDS) will be set to 1 but it doesn't work ... anyone!? :D
我想使用 ATMEGA16 通过 UART 接收一个字符串(指向字符的指针)。我在套件上刻录了这段代码,然后我使用了超级终端(realterm)并进行了测试以输入一个字符串(“on”),如果接收到它,那么 portc(LEDS)将被设置为 1,但它不起作用.. 。 任何人!?:D
Implementation of functions
功能的实现
#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 != '#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
}
}
')
{
/* 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 != 'unsigned char y[20]; // in main
unsigned char len;
len = uartreceive(y, 20);
...
')
{
*x = UDR;
x++;
while ( !(UCSRA & (1<<RXC)) );
}
*x = UDR;
return x;
}
and this is main function
这是主要功能
unsigned char uartrecieve(unsigned char *x, unsigned char size)
{
unsigned char i = 0;
if (size == 0) return 0; // return 0 if no space
while (i < size - 1) { // check space is available (including additional null char at end)
unsigned char c;
while ( !(UCSRA & (1<<RXC)) ); // wait for another char - WARNING this will wait forever if nothing is received
c = UDR;
if (c == '##代码##') break; // break on NULL character
x[i] = c; // write into the supplied buffer
i++;
}
x[i] = 0; // ensure string is null terminated
return i + 1; // return number of characters written
}
回答by Peter Gibson
There are a few problems with your code:
您的代码存在一些问题:
1.You're not allocating any space for the received characters. You have a global unsigned char *x(which is not initialised) that you dereference and assign values to, then increment - this is just overwriting random positions in memory.
1.您没有为接收到的字符分配任何空间。您有一个全局unsigned char *x(未初始化),您可以取消引用并为其分配值,然后递增 - 这只是覆盖内存中的随机位置。
You should instead assign some space by creating an array from the calling function (mainin this case) and passing a pointer to uartreceivealong with the size of the buffer
您应该通过从调用函数创建一个数组(main在本例中)并传递一个指针uartreceive以及缓冲区的大小来分配一些空间
Then (note this is untested)
然后(注意这是未经测试的)
##代码##Each time you call this function, it will overwrite the previous contents of rx_buffer so make sure you are finished using it first. Read up on arrays, pointers and strings if you're not certain what's happening here.
每次调用此函数时,它都会覆盖 rx_buffer 之前的内容,因此请确保先使用完毕。如果您不确定这里发生了什么,请阅读数组、指针和字符串。
Better yet would be to pass in a pointer to uartreceiveso that the calling function can supply the area of memory
更好的是传入一个指针,uartreceive以便调用函数可以提供内存区域
2.It is unlikely that your serial terminal software will be sending NULL terminated strings by default (i.e. with '\0' at the end), normally it would send a new-line ('\n') character. I believe realterm can do this, but it's worth checking.
2.默认情况下,您的串行终端软件不太可能发送以NULL 结尾的字符串(即以'\0' 结尾),通常它会发送一个换行符('\n')。我相信 realterm 可以做到这一点,但值得一试。
3.Reading from UDR will clear the RXC flag, allowing the AVR to write another character into UDR, so reading from UDR twice in a row is probably a bad idea
3.从 UDR 读取会清除 RXC 标志,允许 AVR 将另一个字符写入 UDR,因此连续两次从 UDR 读取可能是个坏主意

