230 lines
6.5 KiB
C++
230 lines
6.5 KiB
C++
|
#include <stdio.h>
|
|||
|
#include <fcntl.h>
|
|||
|
#include <string.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <sys/times.h>
|
|||
|
#include <sys/types.h>
|
|||
|
#include <termios.h>
|
|||
|
#include <unistd.h>
|
|||
|
#include <sys/ioctl.h>
|
|||
|
#include<iostream>
|
|||
|
|
|||
|
#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2) //接收超时
|
|||
|
#define TIMEOUT_USEC 0
|
|||
|
|
|||
|
#include "../include/dyp-a05/uart-ctrl.h"
|
|||
|
|
|||
|
|
|||
|
/*******************************************
|
|||
|
* 波特率转换函数(请确认是否正确)
|
|||
|
********************************************/
|
|||
|
static int convBaudRate(unsigned long int baudrate)
|
|||
|
{
|
|||
|
switch(baudrate){
|
|||
|
case 2400:
|
|||
|
return B2400;
|
|||
|
case 4800:
|
|||
|
return B4800;
|
|||
|
case 9600:
|
|||
|
return B9600;
|
|||
|
case 19200:
|
|||
|
return B19200;
|
|||
|
case 38400:
|
|||
|
return B38400;
|
|||
|
case 57600:
|
|||
|
return B57600;
|
|||
|
case 115200:
|
|||
|
return B115200;
|
|||
|
default:
|
|||
|
return B9600;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*******************************************
|
|||
|
* Setup serial attr
|
|||
|
* fdcom: 串口文件描述符,pportinfo: 待设置的端口信息(请确认)
|
|||
|
*
|
|||
|
********************************************/
|
|||
|
int uart_set(int fdcom, const pPortInfo_t pportinfo)
|
|||
|
{
|
|||
|
struct termios termios_old, termios_new;
|
|||
|
int baudrate, tmp;
|
|||
|
char databit, stopbit, parity, fctl;
|
|||
|
|
|||
|
bzero(&termios_old, sizeof(termios_old));
|
|||
|
bzero(&termios_new, sizeof(termios_new));
|
|||
|
cfmakeraw(&termios_new);
|
|||
|
tcgetattr(fdcom, &termios_old); //get the serial port attributions
|
|||
|
/*------------设置端口属性----------------*/
|
|||
|
//baudrates
|
|||
|
baudrate = convBaudRate(pportinfo -> baudrate);
|
|||
|
cfsetispeed(&termios_new, baudrate); //填入串口输入端的波特率
|
|||
|
cfsetospeed(&termios_new, baudrate); //填入串口输出端的波特率
|
|||
|
termios_new.c_cflag |= CLOCAL; //控制模式,保证程序不会成为端口的占有者
|
|||
|
termios_new.c_cflag |= CREAD; //控制模式,使能端口读取输入的数据
|
|||
|
|
|||
|
// 控制模式,flow control
|
|||
|
fctl = pportinfo-> fctl;
|
|||
|
switch(fctl){
|
|||
|
case 0:{
|
|||
|
termios_new.c_cflag &= ~CRTSCTS; //no flow control
|
|||
|
}break;
|
|||
|
case 1:{
|
|||
|
termios_new.c_cflag |= CRTSCTS; //hardware flow control
|
|||
|
}break;
|
|||
|
case 2:{
|
|||
|
termios_new.c_iflag |= IXON | IXOFF |IXANY; //software flow control
|
|||
|
}break;
|
|||
|
}
|
|||
|
|
|||
|
//控制模式,data bits
|
|||
|
termios_new.c_cflag &= ~CSIZE; //控制模式,屏蔽字符大小位
|
|||
|
databit = pportinfo -> databit;
|
|||
|
switch(databit){
|
|||
|
case 5:
|
|||
|
termios_new.c_cflag |= CS5;
|
|||
|
case 6:
|
|||
|
termios_new.c_cflag |= CS6;
|
|||
|
case 7:
|
|||
|
termios_new.c_cflag |= CS7;
|
|||
|
default:
|
|||
|
termios_new.c_cflag |= CS8;
|
|||
|
}
|
|||
|
|
|||
|
//控制模式 parity check
|
|||
|
parity = pportinfo -> parity;
|
|||
|
switch(parity){
|
|||
|
case 0:{
|
|||
|
termios_new.c_cflag &= ~PARENB; //no parity check
|
|||
|
}break;
|
|||
|
case 1:{
|
|||
|
termios_new.c_cflag |= PARENB; //odd check
|
|||
|
termios_new.c_cflag &= ~PARODD;
|
|||
|
}break;
|
|||
|
case 2:{
|
|||
|
termios_new.c_cflag |= PARENB; //even check
|
|||
|
termios_new.c_cflag |= PARODD;
|
|||
|
}break;
|
|||
|
}
|
|||
|
|
|||
|
//控制模式,stop bits
|
|||
|
stopbit = pportinfo -> stopbit;
|
|||
|
if(stopbit == 2){
|
|||
|
termios_new.c_cflag |= CSTOPB; //2 stop bits
|
|||
|
}
|
|||
|
else{
|
|||
|
termios_new.c_cflag &= ~CSTOPB; //1 stop bits
|
|||
|
}
|
|||
|
|
|||
|
//other attributions default
|
|||
|
termios_new.c_oflag &= ~OPOST; //输出模式,原始数据输出
|
|||
|
termios_new.c_cc[VMIN] = 1; //控制字符, 所要读取字符的最小数量
|
|||
|
termios_new.c_cc[VTIME] = 5; //控制字符, 读取第一个字符的等待时间 unit: (1/10)second
|
|||
|
|
|||
|
tcflush(fdcom, TCIFLUSH); //溢出的数据可以接收,但不读
|
|||
|
tmp = tcsetattr(fdcom, TCSANOW, &termios_new); //设置新属性,TCSANOW:所有改变立即生效 tcgetattr(fdcom, &termios_old);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
return(tmp);
|
|||
|
}
|
|||
|
|
|||
|
/*******************************************
|
|||
|
* Open serial port
|
|||
|
* tty: 端口号 ttyS0, ttyS1, ....
|
|||
|
* 返回值为串口文件描述符
|
|||
|
********************************************/
|
|||
|
int uart_init(const char* dev)
|
|||
|
{
|
|||
|
return(open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK));
|
|||
|
}
|
|||
|
|
|||
|
/*******************************************
|
|||
|
* Close serial port
|
|||
|
********************************************/
|
|||
|
void uart_deinit(int fdcom)
|
|||
|
{
|
|||
|
close(fdcom);
|
|||
|
}
|
|||
|
|
|||
|
/********************************************
|
|||
|
* send data
|
|||
|
* fdcom: 串口描述符,data: 待发送数据,datalen: 数据长度
|
|||
|
* 返回实际发送长度
|
|||
|
*********************************************/
|
|||
|
int uart_txd(int fdcom, const unsigned char *data, int datalen)
|
|||
|
{
|
|||
|
int len = 0;
|
|||
|
|
|||
|
len = write(fdcom, data, datalen);
|
|||
|
if(len == datalen){
|
|||
|
return (len);
|
|||
|
}
|
|||
|
else{
|
|||
|
tcflush(fdcom, TCOFLUSH);
|
|||
|
return -1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*******************************************
|
|||
|
* receive data
|
|||
|
* 返回实际读入的字节数
|
|||
|
*
|
|||
|
********************************************/
|
|||
|
int uart_rxd(int fdcom, unsigned char *data, int datalen, int baudrate)
|
|||
|
{
|
|||
|
int readlen, fs_sel;
|
|||
|
|
|||
|
fd_set fs_read;
|
|||
|
struct timeval tv_timeout;
|
|||
|
|
|||
|
FD_ZERO(&fs_read);
|
|||
|
FD_SET(fdcom, &fs_read);
|
|||
|
tv_timeout.tv_sec = TIMEOUT_SEC(datalen, baudrate);
|
|||
|
tv_timeout.tv_usec = TIMEOUT_USEC;
|
|||
|
|
|||
|
fs_sel = select(fdcom+1, &fs_read, NULL, NULL, &tv_timeout);
|
|||
|
if(fs_sel){
|
|||
|
// tcflush(fdcom, TCIFLUSH);
|
|||
|
// ms
|
|||
|
usleep(300000);
|
|||
|
readlen = read(fdcom, data, datalen);
|
|||
|
// unsigned char bit = data[0];
|
|||
|
return readlen;
|
|||
|
}
|
|||
|
else{
|
|||
|
return (-1);
|
|||
|
}
|
|||
|
// return -1
|
|||
|
|
|||
|
return (readlen);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifdef TEST
|
|||
|
int fdcom = 0;
|
|||
|
/**
|
|||
|
* @brief
|
|||
|
* @param
|
|||
|
* @retval
|
|||
|
*/
|
|||
|
int main(int argc, char**argv)
|
|||
|
{
|
|||
|
fdcom = uart_init("/dev/COM0");
|
|||
|
if(fdcom > 0)
|
|||
|
{
|
|||
|
PortInfo_t portinfo = {115200, 8, 2, 0, 1, 0};
|
|||
|
uart_set(fdcom, &portinfo);
|
|||
|
printf("[PARAM]: 115200, 8, 2, 0, 1, 0\n");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf("[ERROR]: open serial port error.\n");
|
|||
|
}
|
|||
|
uart_deinit(fdcom);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|