TX2通过串口或CAN和其他设备通信(一)--- 串口通信

TX2通过串口或CAN和其他设备通信(一)— 串口通信

背景介绍

Jetson TX2是NVIDIA推出的一款嵌入式开发平台,TX2所提供的性能为早前版本的两倍,即能够以两倍以上的功效运行,且功率低于7.5瓦。这使得Jetson TX2能够在终端应用上运行更庞大、更深度的神经网络,让设备更加智能,具有更高的精度和更快的响应时间,以执行如图像分类、导航和语音识别等任务

需求分析

TX2应用在机器人领域通常需要和其他设备进行通信来实现对机器人的控制
本文主要介绍TX2通过串口和CAN总线和其他设备进行通信
参考之前的经验,串口通信较为普遍,相对简单,所以从串口做起

串口通信

1. 首先搞清楚TX2的接口

这个网站有TX2的配置和外设信息
但是要结合具体的载板,这里我用的是瑞泰科技的TX2 9003,可查看《RTSO-9003用户手册V1.1》
瑞泰科技只留出来两路串口,UART0为调试口,UART1为普通串口,所以咱们使用UART1

管脚功能管脚功能
 3 |  UART0_TX |  4  |  UART0_RX 
 5 |  UART1_TX |  6  |  UART1_RX   

这里需注意在linux下串口是一个文件,UART0为"/dev/ttyS0"",UART1为"/dev/ttyTHS2"

2.接下来进行代码部分的编写

主要参考这篇博客
分为三个部分:打开串口、串口初始化、读写串口

  • 打开串口
/**
 * openUart
 * @param  comport 想要打开的串口号
 * return  失败返回-1
 */
int openUart( int comport)
{
    const char *dev[]  = {"/dev/ttyS0", "/dev/ttyTHS2"};
    //瑞泰科技只留出来两路串口,UART0为调试口,UART1为普通串口,所以咱们使用UART1
    if(comport == 0)
    {
        fd = open(dev[0], O_RDWR | O_NOCTTY | O_NDELAY);
        if(-1 == fd)
        {
            perror("Can't Open Serial Port");
            return (-1);
        }
    }
    else if(comport == 1)
    {
        fd = open(dev[1], O_RDWR | O_NOCTTY | O_NDELAY);
        if(-1 == fd)
        {
            perror("Can't Open Serial Port");
            return (-1);
        }
    }
    printf("fd-open=%d\n", fd);
    return fd;
}
  • 初始化串口
/**
 * uartInit
 * @param  nSpeed 波特率  nBits 停止位 nEvent 奇偶校验位 nStop 停止位
 * @return  返回-1为初始化失败
 */
int uartInit(int nSpeed, int nBits, char nEvent, int nStop)
{
    struct termios newtio, oldtio;
    /*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/
    if  ( tcgetattr( fd, &oldtio)  !=  0) {
        perror("SetupSerial 1");
        printf("tcgetattr( fd,&oldtio) -> %d\n", tcgetattr( fd, &oldtio));
        return -1;
    }
    bzero( &newtio, sizeof( newtio ) );
    /*步骤一,设置字符大小*/
    newtio.c_cflag  |=  CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;
    /*设置停止位*/
    switch( nBits )
    {
    case 7:
        newtio.c_cflag |= CS7;
        break;
    case 8:
        newtio.c_cflag |= CS8;
        break;
    }
    /*设置奇偶校验位*/
    switch( nEvent )
    {
    case 'o':
    case 'O': //奇数
        newtio.c_cflag |= PARENB;
        newtio.c_cflag |= PARODD;
        newtio.c_iflag |= (INPCK | ISTRIP);
        break;
    case 'e':
    case 'E': //偶数
        newtio.c_iflag |= (INPCK | ISTRIP);
        newtio.c_cflag |= PARENB;
        newtio.c_cflag &= ~PARODD;
        break;
    case 'n':
    case 'N':  //无奇偶校验位
        newtio.c_cflag &= ~PARENB;
        break;
    default:
        break;
    }
    /*设置波特率*/
    switch( nSpeed )
    {
    case 2400:
        cfsetispeed(&newtio, B2400);
        cfsetospeed(&newtio, B2400);
        break;
    case 4800:
        cfsetispeed(&newtio, B4800);
        cfsetospeed(&newtio, B4800);
        break;
    case 9600:
        cfsetispeed(&newtio, B9600);
        cfsetospeed(&newtio, B9600);
        break;
    case 115200:
        cfsetispeed(&newtio, B115200);
        cfsetospeed(&newtio, B115200);
        break;
    case 460800:
        cfsetispeed(&newtio, B460800);
        cfsetospeed(&newtio, B460800);
        break;
    default:
        cfsetispeed(&newtio, B9600);
        cfsetospeed(&newtio, B9600);
        break;
    }
    /*设置停止位*/
    if( nStop == 1 )
        newtio.c_cflag &=  ~CSTOPB;
    else if ( nStop == 2 )
        newtio.c_cflag |=  CSTOPB;
    /*设置等待时间和最小接收字符*/
    newtio.c_cc[VTIME]  = 0;
    newtio.c_cc[VMIN] = 0;
    /*处理未接收字符*/
    tcflush(fd, TCIFLUSH);
    /*激活新配置*/
    if((tcsetattr(fd, TCSANOW, &newtio)) != 0)
    {
        perror("com set error");
        return -1;
    }
    printf("set done!\n");
    return 0;
}
  • 读写串口
/**
 *uartSend
 *@param send_buf[] 要发送的数据 length 发送的数据长度
 */
void uartSend(char send_buf[], int length)
{
    int w;
    w = write(fd, send_buf, length);
    if(w == -1)
    {
        printf("Send failed!\n");
    }
    else
    {
        printf("Send success!\n");
    }
}
/**
 *uartSend
 *@param send_buf[] 要接收的数据 length 接收的数据长度
 */
void uartRead(char receive_buf[], int length)
{
    int r;
    r = read(fd, receive_buf, strlen(receive_buf));
    for(int i = 0; i < r; i++)
    {
        printf("%c", receive_buf[i]);
    }

}

3. 测试

这里测试为TX2通过USB-TTL向我电脑的上位机发送数据
上位机为任意串口助手
RX接PORT_5,TX接PORT_6
波特率统一设置为115200

  • 测试代码
int main(int argc , char **argv) {
    fd = openUart(1);              //打开串口
    char test [6] = "Hello";       //用来测试
    uartInit(115200, 8, 'n' , 1) ; //波特率为115200,无奇偶校验,波特率需与下位机相匹配
    for(int i = 10; i > 0; i--) {
        uartSend(test, strlen(test));
    }
    close(fd);
    return 0;
}

经过测试,上位机可以成功接收数据

 date : 2018.12.25
  • 6
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
好的,以下是一个基本的C++代码示例,用于在TX2和STM32之间进行串口通信。需要注意的是,串口通信的具体参数可能因设备而异,需要根据实际情况进行调整。 ```c++ #include <iostream> #include <unistd.h> #include <fcntl.h> #include <termios.h> using namespace std; int main() { int fd; struct termios options; fd = open("/dev/ttyTHS1", O_RDWR | O_NOCTTY | O_NDELAY); // 打开TX2串口设备文件 if (fd == -1) { cout << "无法打开串口设备文件!" << endl; return -1; } tcgetattr(fd, &options); // 获取串口参数 cfsetispeed(&options, B115200); // 设置波特率 cfsetospeed(&options, B115200); // 设置波特率 options.c_cflag |= (CLOCAL | CREAD); // 本地连接,接收使能 options.c_cflag &= ~PARENB; // 没有校验位 options.c_cflag &= ~CSTOPB; // 1个停止位 options.c_cflag &= ~CSIZE; // 字符长度掩码 options.c_cflag |= CS8; // 8位数据长度 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 非规范模式 options.c_oflag &= ~OPOST; // 原始输出 options.c_cc[VTIME] = 0; // 等待时间 options.c_cc[VMIN] = 1; // 最小字符数 tcsetattr(fd, TCSANOW, &options); // 设置串口参数 // 以下代码用于向STM32发送数据 char send_buf[] = "Hello, STM32!\n"; int send_len = write(fd, send_buf, sizeof(send_buf)); // 以下代码用于接收STM32发送的数据 char recv_buf[1024]; int recv_len = read(fd, recv_buf, sizeof(recv_buf)); // 打印接收到的数据 if (recv_len > 0) { cout << "接收到的数据:" << recv_buf << endl; } close(fd); // 关闭串口设备文件 return 0; } ``` 需要注意的是,以上代码仅供参考,具体的串口通信实现可能因设备而异,需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值