飞凌嵌入式
直播中

jf_37860120

5年用户 9经验值
擅长:嵌入式技术
私信 关注
[技术]

飞凌嵌入式OK153-S开发板RS485通信测试

此次发帖描述飞凌嵌入式的OK153-S开发板两路RS485通信测试。

通信测试为使用开发板上的两个RS485结构对接
微信图片_20251124222038_25_28.jpg

其中一个RS485只负责发送数据,另一个RS485负责接收数据,并将接收的数据原路发送回去。
查看原理图:
485.png

RS485_0 由 uart7导出
RS485_1 由 uart5导出

编写两个程序分别打开uart5和uart7,其中uart7导出的RS485_0主动每秒发送数据。uart5导出的RS485_1接收数据,并将接收到的数据发送给RS485_0。
生成的程序如下:

uart57.png

运行结果如下:

uart57read.png

下面附上RS485读写代码:
头文件:

#ifndef CLASS_UART_H
#define CLASS_UART_H

#include <iostream>
#include <cstddef>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/serial.h>
#include <wchar.h>
#include <unistd.h>
#include <cstring>
#include <mutex>
#include <sys/epoll.h>


typedef int(*CallBackFunc_ReadData)(char*,int);

using namespace std;

static std::mutex mtx;

class CLASS_UART
{
public:
    static CLASS_UART* getClassHandle()
    {
        mtx.lock();
        if(handle == nullptr)
        {
            handle = new CLASS_UART();
            mtx.unlock();
            return handle;
        }
        else
        {
            mtx.unlock();
            return handle;
        }
    }
    ~CLASS_UART();

    void registerCallBackFunc(CallBackFunc_ReadData func){
        func_readdata = func;
    }

    void stop_thread(){
        runUart = -1;
        th_work = -1;
    }

    int set_dev_property(const char* dev);
    void run_thread();
    int send_data(char* data,int size);

private:
    CLASS_UART();
    static CLASS_UART* handle;
    CallBackFunc_ReadData func_readdata;

    char* onceBuffer;
    char* allreadBuffer;
    char* sendBuffer;
    int uartFD,th_work,runUart;
    int allreadnumber,sendnumber;

    int fdEp;
    int eventCount = 0;

    int open_dev(const char* dev);

};

#endif // CLASS_UART_H

cpp实现文件:

#include "class_device_uart.h"
#include <thread>

#define MAX_EVENTS 10

CLASS_UART* CLASS_UART::handle = nullptr;

/* 常用波特率
B50
B75
B110
B134
B150
B200
B300
B600
B1200
B1800
B2400
B4800
B9600
B19200
B38400

B57600
B115200
B230400
B460800
B500000
B576000
B921600
B1000000
B1152000
B1500000
B2000000
B2500000
B3000000
B3500000
B4000000
*/

CLASS_UART::CLASS_UART() {
    th_work = 1;
    runUart = -1;
    allreadnumber = 0;
    fdEp = -1;
    uartFD = -1;
    sendnumber = 0;

    onceBuffer = new char[1024];
    for (int r = 0; r < 1024; ++r) {
        onceBuffer[r] = '\0';
    }

    allreadBuffer = new char[8192];
    for (int r = 0; r < 8192; ++r) {
        allreadBuffer[r] = '\0';
    }

    sendBuffer = new char[8192];
    for (int r = 0; r < 8192; ++r) {
        sendBuffer[r] = '\0';
    }
}

CLASS_UART::~CLASS_UART(){
    th_work = -1;
    runUart = -1;
    allreadnumber = 0;
    sendnumber = 0;

    close(uartFD);
    close(fdEp);

    delete[] onceBuffer;
    onceBuffer = nullptr;
    delete[] allreadBuffer;
    allreadBuffer = nullptr;
    delete[] sendBuffer;
    sendBuffer = nullptr;
}

int CLASS_UART::open_dev(const char *dev){
    uartFD = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
    if (uartFD == -1)
    {
        cout<<"open_dev : "<<dev<<" faild !"<<endl;
        return -1;
    }
    else {
        cout<<"open_dev : "<<dev<<" OK !"<<endl;
        struct serial_struct serial;
        int ret = ioctl(uartFD, TIOCGSERIAL, &serial);
        if (ret != 0) {
            close(uartFD);
            cout<<"error : "<<dev<<" TIOCGSERIAL !"<<endl;
            return -2;
        }
        cout<<"ioctl : "<<dev<<" TIOCGSERIAL !"<<endl;
        serial.xmit_fifo_size = 8192; //8K
        ret = ioctl(uartFD, TIOCSSERIAL, &serial);
        if(ret != 0) {
            close(uartFD);
            cout<<"error : "<<dev<<" TIOCSSERIAL !"<<endl;
            return -8192;
        }
        cout<<"ioctl : "<<dev<<" TIOCSSERIAL !"<<endl;
    }


    fdEp = -1;
    fdEp = epoll_create(MAX_EVENTS);
    epoll_event eve;
    eve.data.fd = uartFD;
    eve.events = EPOLLIN ;
    func_readdata = nullptr;
    int ret = epoll_ctl(fdEp, EPOLL_CTL_ADD, uartFD, &eve);
    if(ret == -1) {
        close(uartFD);
        cout<<"epoll_ctl ERROR:EPOLL_CTL_ADD"<<std::endl<<std::flush;
        fdEp = -1;
    }
    else{
        runUart = 1;
        return 1;
    }

    return -1;
}

int CLASS_UART::set_dev_property(const char* dev ){
    int speed=115200;

    if(open_dev(dev) < 0){
        return -1;
    }


    struct termios options;
    if(tcgetattr(uartFD, &options) != 0){
        std::cout<<"tcgetattr :uart  ERROR"<<std::endl;
        close(uartFD);
        return -1;
    }
    else{
        std::cout<<"tcgetattr : uart  OK"<<std::endl;
    }

    if(cfsetispeed(&options, B115200) == 0){
        std::cout<<"cfsetispeed : "<<speed<<" OK"<<std::endl;
    }
    else{
        std::cout<<"cfsetispeed : "<<speed<<" ERROR"<<std::endl;
        close(uartFD);
        return -1;
    }

    if(cfsetospeed(&options, B115200) == 0){
        std::cout<<"cfsetospeed : "<<speed<<" OK"<<std::endl;
    }
    else{
        std::cout<<"cfsetospeed : "<<speed<<" ERROR"<<std::endl;
        close(uartFD);
        return -1;
    }


    options.c_cflag |= (CLOCAL | CREAD); // 允许接收器和本地模式设置串口工作在本地模式
    cfmakeraw(&options);

    options.c_cflag &= ~CSIZE;      // 清除当前数据位大小设置/用数据位掩码清空数据位设置
    options.c_cflag |= CS8;         // 设置数据位为8位
    options.c_cflag &= ~CSTOPB;     // 设置停止位为1位
    options.c_cflag &= ~CRTSCTS;    // 禁用硬件流控制
    options.c_cflag &= ~PARENB;     // 无奇偶校验
    options.c_cc[VTIME] = 0;//超时 以0.1秒为单位
    options.c_cc[VMIN] = 1;//设置最小读取字符数

    tcflush(uartFD, TCIOFLUSH);// 刷新串口

    if(tcsetattr(uartFD, TCSANOW, &options) == 0){

        std::cout<<"tcsetattr :uart OK"<<std::endl;
        runUart = 1;
        return 1;
    }
    else {
        perror("tcsetattr fd");
        close(uartFD);
        return -1;
    }
    return -1;
}


void CLASS_UART::run_thread(){
    th_work = 1;
    while(th_work > 0){
        if(runUart < 0){
            std::this_thread::sleep_for(std::chrono::milliseconds(50));
        }
        else{
            int packetIndex = 0;
            epoll_event events[MAX_EVENTS];
            memset(events, 0, sizeof(events));
            while (runUart > 0) {
                eventCount = epoll_wait(fdEp, events, MAX_EVENTS,5);
                if (eventCount == -1) {
                    cout << "exit : eventCount == -1 "<<std::endl<<std::flush;
                    stop_thread();
                    break;
                }else if (eventCount == 0) {
                    if(sendnumber > 0){
                        int w = write(uartFD,sendBuffer,sendnumber);
                        cout <<"sendnumber="<<sendnumber<<std::endl;
                        cout <<"write num="<<w<<std::endl;
                        sendnumber = 0;
                    }
                    if(packetIndex > 0){
                        cout <<" "<<endl;
                        std::cout << "All read number: " << allreadnumber << std::endl;
                        std::cout << "All read data:  "<<endl;
                        std::cout << allreadBuffer << std::endl;
                        packetIndex = write(uartFD,allreadBuffer,allreadnumber);
                        allreadnumber = 0;
                        packetIndex = 0;
                        for (int r = 0; r < 8192; ++r) {
                            allreadBuffer[r] = '\0';
                        }
                        std::cout << endl;
                    }

                }else{
                    // std::cout<<std::endl<<"get events ,eventCount = "<< eventCount<< std::endl;
                    for (int i = 0; i < eventCount; i++) {
                        if (events[i].data.fd == uartFD) {
                            if(events[i].events & EPOLLIN){
                                for (int r = 0; r < 1024; ++r) {
                                    onceBuffer[r] = '\0';
                                }
                                int readnumber = read(uartFD,onceBuffer,1024);
                                if (readnumber < 0) {
                                    perror("read");
                                    break;
                                } else if (readnumber == 0) {
                                    continue;
                                } else {
                                    if(packetIndex > 0){
                                        int s = 0;
                                        for (int r = allreadnumber; r < allreadnumber+readnumber; ++r) {
                                            allreadBuffer[r] = onceBuffer[s];
                                            s++;
                                        }

                                        allreadnumber += readnumber;
                                        // std::cout << "PacketIndex = " <<packetIndex<< std::endl;
                                        // std::cout << "readnumber = " <<readnumber<< std::endl;
                                        // std::cout << "Read data: " <<onceBuffer << std::endl;
                                        // std::cout << "allreadnumber = " << allreadnumber << std::endl;
                                        // std::cout << "allreadBuffer: " << allreadBuffer << std::endl;

                                        packetIndex++;
                                    }
                                    else{
                                        for (int r = 0; r < readnumber; ++r) {
                                            allreadBuffer[r] = onceBuffer[r];
                                        }
                                        allreadnumber += readnumber;
                                        // std::cout << "PacketIndex = " <<packetIndex<< std::endl;
                                        // std::cout << "readnumber = " <<readnumber<< std::endl;
                                        // std::cout << "Read data: " << onceBuffer << std::endl;
                                        // std::cout << "allreadnumber = " << allreadnumber << std::endl;
                                        // std::cout << "allreadBuffer: " << allreadBuffer << std::endl;

                                        packetIndex++;
                                    }
                                    // if(func_readdata != nullptr){
                                    //     func_readdata(readBuffer,n);
                                    // }

                                    //sendData(readBuffer,n,0,500,1);
                                    // 注意:如果数据中包含空字符,std::cout将只打印到第一个空字符之前
                                }
                            }
                            else if(events[i].events & EPOLLERR){

                            }
                        }
                    }
                    if(sendnumber > 0){
                        int w = write(uartFD,sendBuffer,sendnumber);
                        cout <<"sendnumber="<<sendnumber<<std::endl;
                        cout <<"write num="<<w<<std::endl;
                        sendnumber = 0;
                    }
                }
            }

            struct epoll_event event;
            event.events = EPOLLIN; // 假设我们要监听的是输入事件
            event.data.fd = uartFD;
            // 清除监听的文件描述符
            event.events = 0; // 清除事件
            if (epoll_ctl(fdEp, EPOLL_CTL_DEL,uartFD, &event) == -1) {
                std::cerr << "Failed to remove file uartFD from epoll" << std::endl;
            }

            close(fdEp); // 关闭epoll文件描述符
            close(uartFD);   // 关闭被监听的文件描述符
        }
    }

}


int CLASS_UART::send_data(char *data, int size) {
    cout << "UART send_data:"<<data<<std::endl;
    sendnumber = size;
    for (int r = 0; r < 8192; ++r) {
        sendBuffer[r] = '\0';
    }
    for (int r = 0; r < size; ++r) {
        sendBuffer[r] = data[r];
    }
    return sendnumber;
}












更多回帖

发帖
×
20
完善资料,
赚取积分