【EmbeddedDev】C中UART的数据读写

当两个控制子系统之间需要进行一些比较复杂的数据交互时, 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 1024

void 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: 3
ON 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; 待继续探究。



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值