diff --git a/.vscode/settings.json b/.vscode/settings.json index 37cb76e..309d800 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,61 @@ "stdlib.h": "c", "sstream": "cpp", "ostream": "cpp", - "iostream": "cpp" + "iostream": "cpp", + "string": "cpp", + "*.tcc": "cpp", + "fstream": "cpp", + "array": "cpp", + "atomic": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "set": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp" } } \ No newline at end of file diff --git a/c/main.c b/c/main.c index b79879e..f4c36b7 100644 --- a/c/main.c +++ b/c/main.c @@ -18,8 +18,45 @@ typedef struct serial_data { } ser_Data; -void *sersend(void *arg); -void *serrecv(void *arg); +void *sersend(void *arg) // 串口发送线程函数 +{ + ser_Data *snd = (ser_Data *)arg; + int ret; + while (1) { + ret = write(snd->serfd, snd->databuf, strlen(snd->databuf)); + if (ret > 0) { + printf("send success, data is %s\r\n", snd->databuf); + } else { + printf("send error!\r\n"); + } + usleep(300000); + /* + if(发生中断) + break;//退出 + */ + } +} + +void *serrecv(void *arg) // 串口发送线程函数 +{ + ser_Data *rec = (ser_Data *)arg; + int ret; + while (1) { + ret = read(rec->serfd, rec->databuf, 1024); + if (ret > 0) { + printf("recv success,recv size is %d,data is %s\r\n", ret, rec->databuf); + } else { + /* + 什么也不做 + */ + } + usleep(1000); + /* + if(发生中断) + break;//退出 + */ + } +} int main(int argc, char *argv[]) { pthread_t pid1, pid2; @@ -97,43 +134,3 @@ int main(int argc, char *argv[]) { free(ter_s); return 0; } - -void *sersend(void *arg) // 串口发送线程函数 -{ - ser_Data *snd = (ser_Data *)arg; - int ret; - while (1) { - ret = write(snd->serfd, snd->databuf, strlen(snd->databuf)); - if (ret > 0) { - printf("send success, data is %s\r\n", snd->databuf); - } else { - printf("send error!\r\n"); - } - usleep(300000); - /* - if(发生中断) - break;//退出 - */ - } -} - -void *serrecv(void *arg) // 串口发送线程函数 -{ - ser_Data *rec = (ser_Data *)arg; - int ret; - while (1) { - ret = read(rec->serfd, rec->databuf, 1024); - if (ret > 0) { - printf("recv success,recv size is %d,data is %s\r\n", ret, rec->databuf); - } else { - /* - 什么也不做 - */ - } - usleep(1000); - /* - if(发生中断) - break;//退出 - */ - } -} diff --git a/cpp/a.out b/cpp/a.out index 16c4770..c69e1f3 100755 Binary files a/cpp/a.out and b/cpp/a.out differ diff --git a/cpp/main.cpp b/cpp/main.cpp index e18388f..f32fc57 100644 --- a/cpp/main.cpp +++ b/cpp/main.cpp @@ -11,126 +11,24 @@ #include #include -typedef struct serial_data { - char databuf[100]; // 发送/接受数据 - int serfd; // 串口文件描述符 +#include "uart.hpp" -} ser_Data; - -void *sersend(void *arg); -void *serrecv(void *arg); +using namespace iflytop; +class Uart g_uart; int main(int argc, char *argv[]) { pthread_t pid1, pid2; pthread_attr_t *pthread_arr1, *pthread_arr2; pthread_arr1 = NULL; pthread_arr2 = NULL; - int serport1fd; - - /* 进行串口参数设置 */ - termios *ter_s = (termios *)malloc(sizeof(*ter_s)); - - serport1fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY); // 不成为控制终端程序,不受其他程序输出输出影响 - if (serport1fd < 0) { - printf("%s open faild\r\n", argv[1]); - return -1; - } - - bzero(ter_s, sizeof(*ter_s)); - - ter_s->c_cflag |= CLOCAL | CREAD; // 激活本地连接与接受使能 - - ter_s->c_cflag &= ~CSIZE; // 失能数据位屏蔽 - ter_s->c_cflag |= CS8; // 8位数据位 - - ter_s->c_cflag &= ~CSTOPB; // 1位停止位 - - ter_s->c_cflag &= ~PARENB; // 无校验位 - - ter_s->c_cc[VTIME] = 0; - ter_s->c_cc[VMIN] = 0; - - /*1 VMIN> 0 && VTIME> 0 - VMIN为最少读取的字符数,当读取到一个字符后,会启动一个定时器,在定时器超时事前,如果已经读取到了VMIN个字符,则read返回VMIN个字符。如果在接收到VMIN个字符之前,定时器已经超时,则read返回已读取到的字符,注意这个定时器会在每次读取到一个字符后重新启用,即重新开始计时,而且是读取到第一个字节后才启用,也就是说超时的情况下,至少读取到一个字节数据。 - 2 VMIN > 0 && VTIME== 0 - 在只有读取到VMIN个字符时,read才返回,可能造成read被永久阻塞。 - 3 VMIN == 0 && VTIME> 0 - 和第一种情况稍有不同,在接收到一个字节时或者定时器超时时,read返回。如果是超时这种情况,read返回值是0。 - 4 VMIN == 0 && VTIME== 0 - 这种情况下read总是立即就返回,即不会被阻塞。----by 解释粘贴自博客园 - */ - cfsetispeed(ter_s, B115200); // 设置输入波特率 - cfsetospeed(ter_s, B115200); // 设置输出波特率 - - tcflush(serport1fd, TCIFLUSH); // 刷清未处理的输入和/或输出 - - if (tcsetattr(serport1fd, TCSANOW, ter_s) != 0) { - printf("com set error!\r\n"); - } - char buffer[] = {"hello my world!\r\n"}; - char recvbuf[100] = {}; + g_uart.open(argv[1]); - ser_Data snd_data = { - .databuf = {0}, - .serfd = serport1fd, - }; - ser_Data rec_data = { - .databuf = {0}, - .serfd = serport1fd, - }; - - memcpy(snd_data.databuf, buffer, strlen(buffer)); // 拷贝发送数据 - - pthread_create(&pid1, pthread_arr1, sersend, (void *)&snd_data); - pthread_create(&pid2, pthread_arr2, serrecv, (void *)&rec_data); + char buffer[128]; while (1) { - usleep(100000); - } - - pthread_join(pid1, NULL); - pthread_join(pid2, NULL); - free(ter_s); - return 0; -} - -void *sersend(void *arg) // 串口发送线程函数 -{ - ser_Data *snd = (ser_Data *)arg; - int ret; - while (1) { - ret = write(snd->serfd, snd->databuf, strlen(snd->databuf)); - if (ret > 0) { - printf("send success, data is %s\r\n", snd->databuf); - } else { - printf("send error!\r\n"); - } - usleep(300000); - /* - if(发生中断) - break;//退出 - */ - } -} - -void *serrecv(void *arg) // 串口发送线程函数 -{ - ser_Data *rec = (ser_Data *)arg; - int ret; - while (1) { - ret = read(rec->serfd, rec->databuf, 1024); - if (ret > 0) { - printf("recv success,recv size is %d,data is %s\r\n", ret, rec->databuf); - } else { - /* - 什么也不做 - */ - } + g_uart.receive(buffer, sizeof(buffer)); usleep(1000); - /* - if(发生中断) - break;//退出 - */ } + return 0; } diff --git a/cpp/uart.cpp b/cpp/uart.cpp new file mode 100644 index 0000000..8007cb7 --- /dev/null +++ b/cpp/uart.cpp @@ -0,0 +1,103 @@ +#include "uart.hpp" + +#include +#include +#include +#include + +#include + +using namespace iflytop; +using namespace std; + +Uart::Uart() {} +Uart::~Uart() {} + +static map s_baundmap = { + {"0", 0000000}, {"50", 0000001}, {"75", 0000002}, {"110", 0000003}, // + {"134", 0000004}, {"150", 0000005}, {"200", 0000006}, {"300", 0000007}, // + {"600", 0000010}, {"1200", 0000011}, {"1800", 0000012}, {"2400", 0000013}, // + {"4800", 0000014}, {"9600", 0000015}, {"19200", 0000016}, {"38400", 0000017}, // + {"57600", 0010001}, {"115200", 0010002}, {"230400", 0010003}, {"460800", 0010004}, // + {"500000", 0010005}, {"576000", 0010006}, {"921600", 0010007}, {"1000000", 0010010}, // + {"1152000", 0010011}, {"1500000", 0010012}, {"2000000", 0010013}, {"2500000", 0010014}, // + {"3000000", 0010015}, {"3500000", 0010016}, {"4000000", 0010017}, +}; + +int Uart::open(string path) { + int rc; + + m_name = path; + + m_fd = ::open(path.c_str(), O_RDWR | O_NOCTTY); + if (m_fd < 0) { + cout << "open " << path << " failed" << endl; + return -1; + } + + memset(&m_tty, 0, sizeof(m_tty)); + + m_tty.c_cflag |= CLOCAL | CREAD; // 激活本地连接与接受使能 + + m_tty.c_cflag &= ~CSIZE; // 失能数据位屏蔽 + m_tty.c_cflag |= CS8; // 8位数据位 + + m_tty.c_cflag &= ~CSTOPB; // 1位停止位 + + m_tty.c_cflag &= ~PARENB; // 无校验位 + + m_tty.c_cc[VTIME] = 0; + m_tty.c_cc[VMIN] = 0; + + cfsetispeed(&m_tty, B115200); // 设置输入波特率 + cfsetospeed(&m_tty, B115200); // 设置输出波特率 + + tcflush(m_fd, TCIFLUSH); // 刷清未处理的输入和/或输出 + + /* Apply attributes */ + rc = tcsetattr(m_fd, TCSANOW, &m_tty); + if (rc) { + cout << "tcsetattr failed" << endl; + return -3; + } + return 0; +} + +int Uart::send(char *data, int size) { + int sent = 0; + sent = write(m_fd, data, size); + if (sent > 0) { + printf("send success, data is %s\r\n", data); + } else { + printf("send error!\r\n"); + } + return sent; +} + +int Uart::receive(char *data, int size_max) { + int received = 0; + received = read(m_fd, data, size_max); + if (received > 0) { + printf("recv success,recv size is %d,data is %s\r\n", received, data); + Uart::send(data, received); + } + return received; +} + +int Uart::close() { + ::close(m_fd); + m_fd = -1; + return 0; +} + +bool Uart::flush_rx() { + if (m_fd < 0) return false; + int rc = tcflush(m_fd, TCIFLUSH); + return rc == 0; +} + +bool Uart::flush_tx() { + if (m_fd < 0) return false; + int rc = tcflush(m_fd, TCOFLUSH); + return rc == 0; +} diff --git a/cpp/uart.hpp b/cpp/uart.hpp new file mode 100644 index 0000000..5915501 --- /dev/null +++ b/cpp/uart.hpp @@ -0,0 +1,40 @@ +#pragma once +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace iflytop { +using namespace std; +class Uart { + private: + int m_fd = 0; + string m_name; + int m_rate = B115200; + struct termios m_tty; + + public: + Uart(); + ~Uart(); + + int open(string path); + int send(char *data, int size); + int receive(char *data, int size_max); + int close(); + + bool flush_rx(); + bool flush_tx(); + + int get_m_fd(void) { return m_fd; }; +}; + +} // namespace iflytop \ No newline at end of file