串口收发数据与一个字符帧数据位的关系

在串口通信当中
一个字符帧发送需要四部分组成:
1位起始位+8位数据位+1位校验位+1位停止位
需区分我们所需要传输的数据和一个字符帧中数据位的关系。
所需要传输的数据位:通常是由一个个char buffer组成,即每个buffer为8位。
当我们要传输和数据的时候,即将buffer放在数据位当中,然后加上1位起始位+1位校验位+1位停止位,组成一个字符帧,进行传输。
如以下代码中,要传输的sendBuff是一个大小为16的char类型的数组,即由16个buffer组成。将每一个buffer轮流放在数据位当中,然后加上1位起始位+1位校验位+1位停止位,组成一个字符帧,进行传输。共需要传输16的字符帧。

int uMtData::set(uint8_t id) {
    uint8_t i = 0;
    uint8_t sum = 0x00;
    uint8_t sendBuff[16] = {
            0xAA, 0x55, 0x55, 0x55, // 帧头:0XAA | CM:目标控制模式 | uIE:电机方向x电机减速比 | pZero
            0x55, 0x55, 0x55, 0x55, //           |             | 
            0x55, 0x55, 0x55, 0x55, //           |             | Tao:热保护时间 | wDog:通信超时看门狗时间
            0x55, 0x55, 0x55, 0x2F, // 帧尾:0X2F
    }; // 提前定义好数据帧,后面根据目标控制模式,往数据帧中写入数据(如pack)进行打包,注意:真正的数据为sendBuff[1]-sendBuff[13]
    // org mc0 data
    pack(id, &sendBuff[1]);//去掉帧头,从1开始
    // calculation check sum
    for (i = 1; i < 14; i++)
        sum += sendBuff[i]; // 将前面1-13位数据累加
    sendBuff[14] = sum; // 校验和:将sendBuff[1]-sendBuff[13]中的数据进行累加。
    int ret = writeBytes(sendBuff, 16);//发送定长度16bytes数据
    return ret;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的串口收发数据的C语言代码,可以用于Windows和Linux系统。 ```c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> int set_serial(int fd, int baudrate, int databits, int stopbits, char parity) { struct termios options; tcgetattr(fd, &options); // 设置波特率 switch (baudrate) { case 2400: cfsetispeed(&options, B2400); cfsetospeed(&options, B2400); break; case 4800: cfsetispeed(&options, B4800); cfsetospeed(&options, B4800); break; case 9600: cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); break; case 19200: cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); break; case 38400: cfsetispeed(&options, B38400); cfsetospeed(&options, B38400); break; case 57600: cfsetispeed(&options, B57600); cfsetospeed(&options, B57600); break; case 115200: cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); break; default: fprintf(stderr, "Unsupported baudrate.\n"); return -1; } // 设置数据位 options.c_cflag &= ~CSIZE; switch (databits) { case 5: options.c_cflag |= CS5; break; case 6: options.c_cflag |= CS6; break; case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr, "Unsupported data size.\n"); return -1; } // 设置停止 switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr, "Unsupported stop bits.\n"); return -1; } // 设置奇偶校验 switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; options.c_iflag &= ~INPCK; break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); options.c_iflag |= INPCK; break; case 'e': case 'E': options.c_cflag |= PARENB; options.c_cflag &= ~PARODD; options.c_iflag |= INPCK; break; default: fprintf(stderr, "Unsupported parity.\n"); return -1; } // 设置输入输出流控制 options.c_cflag &= ~CRTSCTS; // 设置非规范模式 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 设置字符间隔和超时时间 options.c_cc[VTIME] = 0; options.c_cc[VMIN] = 1; // 清空串口缓冲区 tcflush(fd, TCIFLUSH); // 设置串口属性 if (tcsetattr(fd, TCSANOW, &options) != 0) { fprintf(stderr, "Set serial attributes error.\n"); return -1; } return 0; } int open_serial(const char* portname) { int fd = open(portname, O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { perror("Open serial port error"); return -1; } // 设置串口为阻塞模式 fcntl(fd, F_SETFL, 0); return fd; } int close_serial(int fd) { close(fd); return 0; } int send_data(int fd, const char* data, int len) { int n = write(fd, data, len); if (n < 0) { perror("Write data error"); return -1; } return n; } int recv_data(int fd, char* data, int len) { int n = read(fd, data, len); if (n < 0) { perror("Read data error"); return -1; } return n; } int main() { int fd = open_serial("/dev/ttyUSB0"); if (fd < 0) return -1; if (set_serial(fd, 115200, 8, 1, 'N') < 0) { close_serial(fd); return -1; } char sendbuf[] = "Hello, world!"; if (send_data(fd, sendbuf, strlen(sendbuf)) < 0) { close_serial(fd); return -1; } char recvbuf[1024] = {0}; if (recv_data(fd, recvbuf, sizeof(recvbuf)) < 0) { close_serial(fd); return -1; } printf("Received: %s\n", recvbuf); close_serial(fd); return 0; } ``` 这个代码中,`set_serial()`函数用于设置串口的属性,包括波特率、数据位、停止、奇偶校验等等。`open_serial()`函数用于打开串口设备,`close_serial()`函数用于关闭串口设备。`send_data()`和`recv_data()`函数分别用于发送和接收数据。 在`main()`函数中,我们首先打开串口设备`/dev/ttyUSB0`,然后设置串口属性,接着发送一个字符串,最后接收一个字符串并打印出来。你可以根据自己的需要修改这个代码,例如更改串口设备名称、波特率、发送和接收的数据等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值