当前位置:   article > 正文

linux下,PC机串口通信开发

linux下,PC机串口通信开发
 1、查看电脑的串口
  1. ~/share/bin/PC$ dmesg | grep tty
  2. [ 0.083244] printk: console [tty0] enabled
  3. [ 0.329145] 00:02: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
  4. [ 0.351177] 00:03: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200) is a 16550A
  5. [ 0.420781] tty tty48: hash matches

从回复信息中可以看出电脑有两个串口,分别是ttyS0,ttyS1

USB口的话,信息显示是ttyUSB0

 2、添加串口调试代码

简单实现控制灯开的函数

  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <sys/fcntl.h> /*文件控制定义*/
  9. #include <termios.h> /*PPSIX 终端控制定义*/
  10. #include <sys/ioctl.h>
  11. #include <errno.h>
  12. #include <sys/select.h>
  13. #include <sstream>
  14. #include <iomanip>
  15. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  16. using namespace std;
  17. static int lightOn();
  18. static int sendRecv(uint8_t *sBuf, uint16_t sSize, uint8_t *rBuf, uint16_t rSize);
  19. static int Open(const char* device, int baudrate, char parity = 'N', int bytesize = 8, int stopbits = 1);
  20. static int set_parity(int fd,int databits,int stopbits,int parity,int baudrate);
  21. int Read(void* buf, size_t maxLen);
  22. int Write(const void* buf, size_t len);
  23. std::string toHex(uint8_t *buf, uint16_t size);
  24. int m_fd;
  25. int main()
  26. {
  27. Open("/dev/ttyS0", 9600);
  28. lightOn();
  29. return 0;
  30. }
  31. int Open(const char* device, int baudrate, char parity/* = 'N'*/, int bytesize/* = 8*/, int stopbits/* = 1*/)
  32. {
  33. printf("enter %s\n", __func__);
  34. m_fd = ::open(device, O_RDWR | O_NOCTTY | O_NDELAY);
  35. if (m_fd < 0){
  36. perror("打开COM口时出错");
  37. return -1;
  38. }
  39. //if( set_parity(m_fd,8,1,'N') < 0)
  40. if( set_parity(m_fd, bytesize, stopbits, parity, baudrate) < 0){
  41. perror("Set Parity Error\n");
  42. return -1;
  43. }
  44. tcflush(m_fd, TCIOFLUSH);
  45. printf("leave %s\n", __func__);
  46. return 0;
  47. }
  48. int set_parity(int fd,int databits,int stopbits,int parity,int baudrate)
  49. {
  50. struct termios optnew;
  51. speed_t speed = B19200;
  52. if ( fd >0 ) {
  53. /* Read with blocking behavior */
  54. fcntl(fd, F_SETFL, 0);
  55. /* Get current option */
  56. tcgetattr(fd, &optnew);
  57. /* initialize new option to raw input/output */
  58. // memset(&optnew, 0, sizeof(optnew));
  59. cfmakeraw(&optnew);
  60. optnew.c_cc[VMIN ] = 0;
  61. optnew.c_cc[VTIME] = 2*10;
  62. /* set baudrate */
  63. switch (baudrate) {
  64. case 1200: speed = B1200; break;
  65. case 1800: speed = B1800; break;
  66. case 4800: speed = B4800; break;
  67. case 9600: speed = B9600; break;
  68. case 19200: speed = B19200; break;
  69. case 38400: speed = B38400; break;
  70. case 57600: speed = B57600; break;
  71. case 115200: speed = B115200; break;
  72. default: speed = B19200; break;
  73. }
  74. cfsetispeed(&optnew, speed);
  75. cfsetospeed(&optnew, speed);
  76. /* Set data bits */
  77. optnew.c_cflag &= ~CSIZE;
  78. optnew.c_cflag &= ~CRTSCTS;
  79. optnew.c_iflag &= ~(ICRNL|IXON);
  80. optnew.c_cflag |= CLOCAL | CREAD;
  81. optnew.c_oflag &= ~OPOST;
  82. switch (databits) {
  83. case 5: optnew.c_cflag |= CS5; break;
  84. case 6: optnew.c_cflag |= CS6; break;
  85. case 7: optnew.c_cflag |= CS7; break;
  86. default :
  87. optnew.c_cflag |= CS8; break;
  88. }
  89. /* Set parity checking */
  90. optnew.c_cflag |= PARENB;
  91. switch (parity) {
  92. case 'e':
  93. case 'E': optnew.c_cflag &= ~PARODD; break;
  94. case 'o':
  95. case 'O': optnew.c_cflag &= PARODD; break;
  96. default :
  97. optnew.c_cflag &= ~PARENB; break;
  98. }
  99. /* Set stop bit(s) */
  100. if (stopbits == 2)
  101. optnew.c_cflag &= CSTOPB;
  102. else
  103. optnew.c_cflag &= ~CSTOPB;
  104. optnew.c_lflag &= ~( ICANON | ECHO | ECHOE | ISIG );
  105. /* Apply new option */
  106. tcsetattr(fd, TCSANOW, &optnew);
  107. }
  108. return fd;
  109. }
  110. int lightOn()
  111. {
  112. uint8_t send[] = {0x2A, 0x4B, 0x0D};
  113. uint8_t right[] = {0x2A, 0x4B, 0x00, 0x0D};
  114. int retry = 2;
  115. while(retry--){
  116. uint8_t recv[sizeof(right)];
  117. memset(recv, 0, sizeof(right));
  118. printf("send %s\n", toHex((uint8_t *)send, sizeof(send)).c_str());
  119. const int recvCount = sendRecv(send, sizeof(send), recv, sizeof(recv));
  120. if(recvCount != sizeof(recv)){
  121. if(recvCount){
  122. printf("recv %s\n", toHex((uint8_t *)recv, sizeof(recv)).c_str());
  123. }
  124. continue;
  125. }
  126. if(0 != memcmp(right, recv, sizeof(right))){
  127. printf("recv %s\n", toHex((uint8_t *)recv, sizeof(recv)).c_str());
  128. continue;
  129. }
  130. //success
  131. printf("recv %s\n", toHex((uint8_t *)recv, sizeof(recv)).c_str());
  132. retry = 0;
  133. break;
  134. }
  135. return retry;
  136. }
  137. int sendRecv(uint8_t *sBuf, uint16_t sSize, uint8_t *rBuf, uint16_t rSize)
  138. {
  139. printf("enter %s\n", __func__);
  140. // m_mutex.lock();
  141. int ret = Write(sBuf, sSize);
  142. if (ret != 0){
  143. printf("%s Write error, Buf:%s\n", __func__, sBuf);
  144. goto _RET;
  145. }
  146. ret = Read(rBuf, rSize);
  147. if (ret != rSize){
  148. printf("%s read:%s ret:%d\n", __func__, rBuf, ret);
  149. goto _RET;
  150. }
  151. _RET:
  152. // m_mutex.unlock();
  153. return ret;
  154. }
  155. int Write(const void* buf, size_t len)
  156. {
  157. printf("enter %s\n", __func__);
  158. int ret = 0;
  159. int n = ::write(m_fd, buf, len);
  160. if(n != len){
  161. ret = -2;
  162. }
  163. // printf("send to uart result:%i\n", ret);
  164. return ret;
  165. }
  166. /*
  167. * return 接受到的字节数
  168. */
  169. int Read(void* buf, size_t maxLen)
  170. {
  171. printf("enter %s\n", __func__);
  172. int offset = 0;
  173. while(offset < maxLen){
  174. fd_set rd;
  175. FD_ZERO(&rd);
  176. FD_SET(m_fd, &rd);
  177. timeval timeout;
  178. timeout.tv_sec = 1;
  179. int ready = select(m_fd+1, &rd, NULL, NULL, &timeout);
  180. if (ready == 0){ //timeout
  181. // offset = SER_TO;
  182. printf("timeout\n");
  183. break;
  184. }else if (ready == -1 && (errno != EINTR) ){ //error
  185. offset = -2;
  186. printf("error\n");
  187. break;
  188. }else if(ready == 1){
  189. if (FD_ISSET(m_fd, &rd)){
  190. int n = ::read(m_fd, buf + offset, maxLen - offset);
  191. if(n > 0){
  192. offset += n;
  193. }
  194. }
  195. }
  196. }
  197. return offset;
  198. }
  199. std::string toHex(uint8_t *buf, uint16_t size)
  200. {
  201. std::stringstream hexSS;
  202. for (int i = 0; i < size; i++){
  203. hexSS << std::setw(2) << std::setfill('0') << std::hex << (int)buf[i] << " ";
  204. }
  205. std::string hexStr = hexSS.str();
  206. return hexStr;
  207. }
3、遇到open函数出错

在::open() 出错时,已经通过perror函数打印出出错信息,可以根据信息修改

1)比如报错信息提示权限不对,修改权限

chmod 666 /dev/ttyS0

或者以root权限运行可执行文件

  1. // 假如可执行文件是a.out
  2. sudo ./a.out

 

2)检查串口波特率

  1. ~/share/bin/PC$ stty -F /dev/ttyS0
  2. speed 9600 baud; line = 0;
  3. min = 0; time = 20;
  4. -brkint -icrnl -imaxbel
  5. -opost
  6. -isig -icanon -iexten -echo -echoe

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/40129
推荐阅读
相关标签
  

闽ICP备14008679号