首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与RPi的RS-232通信

与RPi的RS-232通信
EN

Stack Overflow用户
提问于 2013-10-05 01:34:30
回答 1查看 269关注 0票数 0

这是这个原始帖子的后续问题:

RaspberryPi RS-232 trouble

我根据接受的答案对我的代码进行了更改,现在终端已设置为阻塞和规范输入。read()现在可以正常工作了,除了第一次读取(通常是一些额外的随机符号和一些好的数据),我从激光测距仪得到的单行数据恰好代表了我期望看到的东西。

然而,我现在有一个问题,如果我进行了太多的读取,激光测距仪将进入非工作状态,停止通信,并且只能通过重新启动电源来重置。这发生在设备上只有4次读取的情况下,而我一直无法进行超过8次的读取。无论是一次读取所有数据,还是跨多个程序启动读取数据,都没有关系。

代码语言:javascript
复制
int main(){
    int uart0_filestream = -1;
    int loop, i, sentBytes;
    int isError, rx_length;
    unsigned char rx_buffer[256];

    uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);
    fcntl(uart0_filestream, F_SETFL, 0);

    if(uart0_filestream == -1){
        printf("ERROR: Unable to open UART\n");
        checkError(errno);
        exit(1);
    }

    struct termios options;

    isError = tcgetattr(uart0_filestream, &options);

    if(isError < 0){
        printf("ERROR: tcgetattr failed.\n");
        checkError(errno);
        exit(1);
    }

    //set c ontrol options and baud
    options.c_cflag |= (CLOCAL | CREAD);
    cfsetispeed(&options, B19200);
    cfsetospeed(&options, B19200);

    //set 8 data bits, 1 stop bit, no parity
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    //set input options
    options.c_iflag |= (INPCK | ISTRIP);        //strip parity
    options.c_iflag &= ~(IXON | IXOFF | IXANY); //turn off software flow control

    //set canonical input processing
    options.c_lflag |= (ICANON | ECHO | ECHOE);

    tcflush(uart0_filestream, TCIFLUSH);
    isError = tcsetattr(uart0_filestream, TCSANOW, &options);

    if(isError < 0){
        printf("ERROR: tcsetattr failed.\n");
        checkError(errno);
        exit(1);
    }

    //read() successfully returns expected data, with the exception of the first 
    //read. Reading more than 6-8 times, regardless of same session or restarting
    //program puts LRF in non-working state which requires a power cycle to fix
    for(i=0; i<4;i++ ){
        rx_length = read(uart0_filestream, (void*)rx_buffer, 255);

        if(rx_length < 0){
            printf("ERROR: read() failed.\n");
            checkError(errno);
        }

        if(rx_length > 0){
            printf("rx_lentgh = %i:\t ", rx_length);
            for(loop=0; loop<rx_length; loop++){
                printf("%c", rx_buffer[loop]);
            }
            printf("\n");
        }
    }

    //writing once has no affect, sending command has no affect
    //looping the write, eventually 'something' gets to the LRF
    //but it puts it in the same state as when reading too many
    //times and have to power cycle
    for(i = 0; i<8; i++){
        sentBytes = write(uart0_filestream, "o\n", 2);

        if(sentBytes < 2){
            printf("ERROR: write() failed.\n");
            checkError(errno);
        }   
    }

    close(uart0_filestream);
}

我不相信它是测距仪,因为我可以运行minicom,它会连续成功地显示输出。

正如我的代码注释中所指出的,我在向激光测距仪写入任何命令时也遇到了问题。每个命令都包含一个字符,后跟一个新行。一次写入没有任何影响,但多次循环可能会使设备处于与读取过多次相同的状态。

我已经阅读了Posix Serial Programming Guide,并尝试了不同的标志组合,我认为这些组合可能会影响读取或写入,但都没有成功。

EN

回答 1

Stack Overflow用户

发布于 2013-10-05 02:18:31

编辑这个引导建议是我的尴尬--我认为字符串是"o/n“。

发送的数据量少了1。

代码语言:javascript
复制
// sentBytes = write(uart0_filestream, "o\n", 2);
// if(sentBytes < 2){
sentBytes = write(uart0_filestream, "o\n", 3);
if(sentBytes < 3){

次要:不清楚为什么读缓冲区减少1( rx_buffer的大小是256)。read()不会追加\0,这段代码也不会。代码很好地将传入数据作为字节数组处理。虽然在printf("%c"...中,如果使用!isgraph(rx_bufferloop)`,则可以执行某些操作。

代码语言:javascript
复制
// rx_length = read(uart0_filestream, (void*)rx_buffer, 255)
rx_length = read(uart0_filestream, (void*)rx_buffer, sizeof rx_buffer)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19187418

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档