赞
踩
- ~/share/bin/PC$ dmesg | grep tty
- [ 0.083244] printk: console [tty0] enabled
- [ 0.329145] 00:02: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
- [ 0.351177] 00:03: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200) is a 16550A
- [ 0.420781] tty tty48: hash matches
从回复信息中可以看出电脑有两个串口,分别是ttyS0,ttyS1
USB口的话,信息显示是ttyUSB0
简单实现控制灯开的函数
- #include <iostream>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/fcntl.h> /*文件控制定义*/
- #include <termios.h> /*PPSIX 终端控制定义*/
- #include <sys/ioctl.h>
- #include <errno.h>
- #include <sys/select.h>
- #include <sstream>
- #include <iomanip>
-
- #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
- using namespace std;
-
- static int lightOn();
- static int sendRecv(uint8_t *sBuf, uint16_t sSize, uint8_t *rBuf, uint16_t rSize);
- static int Open(const char* device, int baudrate, char parity = 'N', int bytesize = 8, int stopbits = 1);
- static int set_parity(int fd,int databits,int stopbits,int parity,int baudrate);
- int Read(void* buf, size_t maxLen);
- int Write(const void* buf, size_t len);
- std::string toHex(uint8_t *buf, uint16_t size);
-
- int m_fd;
-
- int main()
- {
- Open("/dev/ttyS0", 9600);
-
- lightOn();
-
- return 0;
- }
-
- int Open(const char* device, int baudrate, char parity/* = 'N'*/, int bytesize/* = 8*/, int stopbits/* = 1*/)
- {
- printf("enter %s\n", __func__);
-
- m_fd = ::open(device, O_RDWR | O_NOCTTY | O_NDELAY);
- if (m_fd < 0){
- perror("打开COM口时出错");
- return -1;
- }
-
- //if( set_parity(m_fd,8,1,'N') < 0)
- if( set_parity(m_fd, bytesize, stopbits, parity, baudrate) < 0){
- perror("Set Parity Error\n");
- return -1;
- }
-
- tcflush(m_fd, TCIOFLUSH);
-
- printf("leave %s\n", __func__);
-
- return 0;
- }
-
- int set_parity(int fd,int databits,int stopbits,int parity,int baudrate)
- {
- struct termios optnew;
- speed_t speed = B19200;
-
- if ( fd >0 ) {
- /* Read with blocking behavior */
- fcntl(fd, F_SETFL, 0);
-
- /* Get current option */
- tcgetattr(fd, &optnew);
-
- /* initialize new option to raw input/output */
- // memset(&optnew, 0, sizeof(optnew));
- cfmakeraw(&optnew);
- optnew.c_cc[VMIN ] = 0;
- optnew.c_cc[VTIME] = 2*10;
-
- /* set baudrate */
- switch (baudrate) {
- case 1200: speed = B1200; break;
- case 1800: speed = B1800; break;
- case 4800: speed = B4800; break;
- case 9600: speed = B9600; break;
- case 19200: speed = B19200; break;
- case 38400: speed = B38400; break;
- case 57600: speed = B57600; break;
- case 115200: speed = B115200; break;
- default: speed = B19200; break;
- }
- cfsetispeed(&optnew, speed);
- cfsetospeed(&optnew, speed);
-
- /* Set data bits */
- optnew.c_cflag &= ~CSIZE;
- optnew.c_cflag &= ~CRTSCTS;
- optnew.c_iflag &= ~(ICRNL|IXON);
- optnew.c_cflag |= CLOCAL | CREAD;
- optnew.c_oflag &= ~OPOST;
-
- switch (databits) {
- case 5: optnew.c_cflag |= CS5; break;
- case 6: optnew.c_cflag |= CS6; break;
- case 7: optnew.c_cflag |= CS7; break;
- default :
- optnew.c_cflag |= CS8; break;
- }
-
- /* Set parity checking */
- optnew.c_cflag |= PARENB;
- switch (parity) {
- case 'e':
- case 'E': optnew.c_cflag &= ~PARODD; break;
- case 'o':
- case 'O': optnew.c_cflag &= PARODD; break;
- default :
- optnew.c_cflag &= ~PARENB; break;
- }
-
- /* Set stop bit(s) */
- if (stopbits == 2)
- optnew.c_cflag &= CSTOPB;
- else
- optnew.c_cflag &= ~CSTOPB;
-
- optnew.c_lflag &= ~( ICANON | ECHO | ECHOE | ISIG );
-
- /* Apply new option */
- tcsetattr(fd, TCSANOW, &optnew);
- }
- return fd;
- }
-
- int lightOn()
- {
- uint8_t send[] = {0x2A, 0x4B, 0x0D};
- uint8_t right[] = {0x2A, 0x4B, 0x00, 0x0D};
-
- int retry = 2;
- while(retry--){
- uint8_t recv[sizeof(right)];
- memset(recv, 0, sizeof(right));
-
- printf("send %s\n", toHex((uint8_t *)send, sizeof(send)).c_str());
-
- const int recvCount = sendRecv(send, sizeof(send), recv, sizeof(recv));
-
- if(recvCount != sizeof(recv)){
- if(recvCount){
- printf("recv %s\n", toHex((uint8_t *)recv, sizeof(recv)).c_str());
- }
- continue;
- }
-
- if(0 != memcmp(right, recv, sizeof(right))){
- printf("recv %s\n", toHex((uint8_t *)recv, sizeof(recv)).c_str());
- continue;
- }
-
- //success
- printf("recv %s\n", toHex((uint8_t *)recv, sizeof(recv)).c_str());
- retry = 0;
- break;
- }
-
- return retry;
- }
-
- int sendRecv(uint8_t *sBuf, uint16_t sSize, uint8_t *rBuf, uint16_t rSize)
- {
- printf("enter %s\n", __func__);
-
- // m_mutex.lock();
- int ret = Write(sBuf, sSize);
- if (ret != 0){
- printf("%s Write error, Buf:%s\n", __func__, sBuf);
- goto _RET;
- }
- ret = Read(rBuf, rSize);
- if (ret != rSize){
- printf("%s read:%s ret:%d\n", __func__, rBuf, ret);
- goto _RET;
- }
-
- _RET:
- // m_mutex.unlock();
- return ret;
- }
-
- int Write(const void* buf, size_t len)
- {
- printf("enter %s\n", __func__);
-
- int ret = 0;
- int n = ::write(m_fd, buf, len);
- if(n != len){
- ret = -2;
- }
- // printf("send to uart result:%i\n", ret);
- return ret;
- }
-
- /*
- * return 接受到的字节数
- */
- int Read(void* buf, size_t maxLen)
- {
- printf("enter %s\n", __func__);
-
- int offset = 0;
- while(offset < maxLen){
- fd_set rd;
- FD_ZERO(&rd);
- FD_SET(m_fd, &rd);
- timeval timeout;
- timeout.tv_sec = 1;
- int ready = select(m_fd+1, &rd, NULL, NULL, &timeout);
- if (ready == 0){ //timeout
- // offset = SER_TO;
- printf("timeout\n");
- break;
- }else if (ready == -1 && (errno != EINTR) ){ //error
- offset = -2;
- printf("error\n");
- break;
- }else if(ready == 1){
- if (FD_ISSET(m_fd, &rd)){
- int n = ::read(m_fd, buf + offset, maxLen - offset);
- if(n > 0){
- offset += n;
- }
- }
- }
- }
- return offset;
- }
-
- std::string toHex(uint8_t *buf, uint16_t size)
- {
- std::stringstream hexSS;
- for (int i = 0; i < size; i++){
- hexSS << std::setw(2) << std::setfill('0') << std::hex << (int)buf[i] << " ";
- }
- std::string hexStr = hexSS.str();
- return hexStr;
- }

在::open() 出错时,已经通过perror函数打印出出错信息,可以根据信息修改
1)比如报错信息提示权限不对,修改权限
chmod 666 /dev/ttyS0
或者以root权限运行可执行文件
- // 假如可执行文件是a.out
- sudo ./a.out
2)检查串口波特率
- ~/share/bin/PC$ stty -F /dev/ttyS0
- speed 9600 baud; line = 0;
- min = 0; time = 20;
- -brkint -icrnl -imaxbel
- -opost
- -isig -icanon -iexten -echo -echoe
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。