问题描述
我是用我的皮的RS-232线路用激光测距仪进行通信。我已经测试使用的Minicom在19200波特率(因为这是LRF的波特率和不能改变),并能正常工作两者之间的通信。虽然写下来到LRF任何命令(其中包括单个字符和pressing'进入')的可能需要尝试多次才能生效,在两个方向通信的伟大工程。
然而,当我开始C code编程阅读和RS-232的写,一半的作品。这里是code我使用的:
的#include<&stdlib.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&fcntl.h GT;
#包括LT&;&termios.h GT;//设置UART0诠释主(){
INT uart0_filestream = -1;
INT回路;
INT I;
INT ISERROR = 1,rx_length;
unsigned char型RX_BUFFER [256];
useconds_t微= 3000; uart0_filestream =打开(/开发/ ttyAMA0,O_RDWR | O_NOCTTY | O_NDELAY); 如果(uart0_filestream == -1)
的printf(错误:无法打开UART \\ n \\ n);
其他
的printf(UART开放\\ n \\ n); 结构termios的选择; tcgetattr(uart0_filestream,&安培;期权);
options.c_cflag = B19200 | CS8 | CLOCAL | CREAD;
options.c_iflag = IGNPAR | ICRNL;
options.c_oflag = 0;
options.c_lflag = 0; tcflush(uart0_filestream,TCIFLUSH);
tcsetattr(uart0_filestream,TCSANOW,&安培;期权); unsigned char型TX_BUFFER [20];
无符号字符* p_tx_buffer; p_tx_buffer =安培; TX_BUFFER [0];
* p_tx_buffer ++ ='O';
* p_tx_buffer ++ ='\\ n'; / *
如果(uart0_filestream!= -1){
对于(i = 0; I< 100;我++){
诠释计数=写(uart0_filestream,&安培; TX_BUFFER [0],(p_tx_buffer - &安培; TX_BUFFER [0]));
如果(计数℃,)
的printf(\\ n \\ n错误:没有写\\ n \\ n字节);
其他
的printf(%I字节写:%S \\ n,(p_tx_buffer - &安培; TX_BUFFER [0]),TX_BUFFER);
}
}
* /
如果(uart0_filestream!= -1){
对于(I = 0; I&下; 50;){
rx_length =读(uart0_filestream,(无效*)RX_BUFFER,255); 如果(rx_length大于0){
的printf(rx_lentgh =%I:\\ t的,rx_length);
为(循环= 0;环小于30;环++){
//检查NULL和新的生产线,方便易读
如果(RX_BUFFER [循环] == NULL)
RX_BUFFER [循环] ='$';
如果(RX_BUFFER [循环] =='\\ n')
RX_BUFFER [循环] ='%';
的printf(%C,RX_BUFFER [循环]);
}
的printf(\\ n);
我++;
}
}
} 关闭(uart0_filestream);
}
当我尝试从设备读取,它总是返回一个错误。我开始循环,看是否连续阅读方面给了不同的结果。 100试,一般4-5个返回数据,其余的[I] rx_length [/ I]回来-1。返回应该像数据:
where the number depends on the distance the LRF is measuring. But instead, I get output like this:
**The above is edited in my code for readability. A NULL character is replaced with '$' and a '\n' is replaced with '%'
You can see that every time it gets data, it at least gets part of a good read, and occasionally the whole thing. But there is a lot of junk in there. You can see in my code I have filtered out all reads that returned in an error. It would probably take over 1000 reads to get this many "good" reads. I really think it has to do with timing, but even if it was timing, wouldn't shouldn't I still be getting [i]some[/i] data back?
Writing has the same issue. A single write does nothing. Looping the write code 100 times may end up getting the code down to the LRF, but the LRF pretty much doesn't work at all after running that code and I haven't to cut power to get it to work and view data in minicom again.
The LRF has can send packets at 200Hz or 10Hz, depending on the mode. All data retrieved above was done with the LRF sending packets at 200Hz.
Any help at all would be greatly appreciated! I have been working on this for several weeks between my other classes and work.
There are several issues with your code.
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);
You have setup the port for non-blocking I/O.
This is probably not what you want. Add the following after the return code checking:
fcntl(uart0_filestream, F_SETFL, 0);
in order to configure blocking I/O.
if(uart0_filestream == -1)
printf("ERROR: Unable to open UART\n\n");
When there is a fatal error the program should exit, rather than continue on.
You also need to examine the value of errno when a syscall returns -1.
tcgetattr(uart0_filestream, &options);
...
tcsetattr(uart0_filestream, TCSANOW, &options);
Return codes from syscalls should always be checked.
options.c_cflag = B19200 | CS8 | CLOCAL | CREAD;
options.c_iflag = IGNPAR | ICRNL;
options.c_oflag = 0;
options.c_lflag = 0;
This is improper modification of termios members.
Only proper macros and bit-wise operations should be performed.Refer to the Posix Guide of Serial Programing.
You have disabled canonical input processing, which is probably not what you want to do.
The input you are trying to read is ASCII text with line termination, so use canonical mode to have the system parse for the end of each line.
You now have the port configured for raw mode, which is intended for binary data or to ignore ASCII control characters.
For sample code to configure canonical mode see this answer.
rx_length = read(uart0_filestream, (void*)rx_buffer, 255);
Again, you need to examine the value of errno when a syscall return -1.
When read()
returns -1 for your code, errno is probably EAGAIN to indicate that there was no data available.
If blocking I/O is specified and canonical I/O instead of raw I/O, then each read()
will return with a complete line of input.
这篇关于树莓派RS-232的麻烦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!