【EmbeddedDev】C中UART的数据读写

来源:互联网 发布:网上抓娃娃软件 编辑:程序博客网 时间:2024/06/06 07:13

当两个控制子系统之间需要进行一些比较复杂的数据交互时, UART接口可以提供帮助。
UART(Universal Asynchronous Receiver Transmitter:通用异步收发器), 一对一数据交互,以byte为单位发送信息。


假设现在要完成一次握手请求:首先主控一方从UART读取握手请求信息, 然后分析/组装确认信息并返回。
假设握手规则如下:
请求数据: 0xa5 0x01 0x01 0x04 0x00 0x00 0x00 0xa5 0x00 0x00 0x00 0xb0
    (其中最后一个字节为校验码, 忽略第二个字节, 校验码=~(0xa5+0x01+0x04+0x00+0x00+0x00+0xa5+0x00+0x00+0x00)&0xff)
需回复确认数据: 0xa5 0x01 0xff 0x04 0x00 0x00 0x00 0xa5 0x00 0x00 0x00 0xb2
    (首先把第三个字节改为0xff,  忽略第二个字节,  然后修改校验码=~(0xa5+0xff+0x04+0x00+0x00+0x00+0xa5+0x00+0x00+0x00)&0xff)


以下为具体代码示例:

// author: xiaomo, at 2016/08/31#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <termios.h>#define BUF_LEN 1024void print_hex_array(int len, unsigned char* arr){    int i =0;    for (; i<len; ++i)    {        printf("0x%02x ", *(arr+i));    }    printf("\n");}int init_uart(){    //-------------------------    //----- SETUP UART 0 -----    //-------------------------    int uart_fs = -1;    //OPEN THE UART    uart_fs = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY ); // | O_NDELAY);    if (uart_fs == -1)    {        //ERROR - CAN'T OPEN SERIAL PORT        printf("Error - Unable to open UART.  Ensure it is not in use by another application\n");    }    else    {        printf("Opend UART port OK, number: %d\n", uart_fs);    }    //CONFIGURE THE UART    struct termios options;    tcgetattr(uart_fs, &options);    options.c_cflag = B115200 | CS8 | CLOCAL | CREAD;    options.c_iflag = IGNPAR;    options.c_oflag = 0;    options.c_lflag = 0;    tcflush(uart_fs, TCIFLUSH);    tcsetattr(uart_fs, TCSANOW, &options);    return uart_fs;}void do_transmit(int uart_fd, int send_bytes, unsigned char *p_tx_buffer){    if (uart_fd < 0)    {        return;    }    //Filestream, bytes to write, number of bytes to write    int count = write(uart_fd, p_tx_buffer, send_bytes);    if (count < 0)    {        printf("UART transmit error\n");    }}int checksum(int size, unsigned char* cur_line){    int i =0, checksum=0;    for (; i<size; ++i)    {        if (i!=1 && i!=size-1)        {            checksum += *(cur_line+i);        }    }    return ~checksum & 255;}void on_receive(int uart_fd){    if (uart_fd < 0)        return;    unsigned char rx_buf[BUF_LEN] = {0};    int rx_length = read(uart_fd, (void*)rx_buf, BUF_LEN-1);    if (rx_length < 3)    {        //An error will occur if there are not enough bytes        printf("Error occured, read_res: %d\n", rx_length);        return;    }    printf("ON RECEIVE: ");    print_hex_array(rx_length, rx_buf);    int checkres = checksum(rx_length, rx_buf);    *(rx_buf+2) = 0xff;    *(rx_buf+rx_length-1) = checksum(rx_length, rx_buf);    printf("TO RESPOND: ");    print_hex_array(rx_length, rx_buf);    do_transmit(uart_fd, rx_length, rx_buf);}void close_uart(int uart_fs){    close(uart_fs);}int main(){    int uart = init_uart();    while (1)    {        on_receive(uart);        sleep(0.2);    }    close_uart(uart);    return 0;}

运行效果:

root@beaglebone:/data/apps/UART# ./handshake Opend UART port OK, number: 3ON RECEIVE: 0xa5 0x01 0x01 0x04 0x00 0x00 0x00 0xa5 0x00 0x00 0x00 0xb0 TO RESPOND: 0xa5 0x01 0xff 0x04 0x00 0x00 0x00 0xa5 0x00 0x00 0x00 0xb2 

========================

这里还有一个疑问未解决, 当我尝试以O_NDELAY非阻塞打开串口的时候, 程序在read时一直返回-1; 待继续探究。



1 0
原创粉丝点击