#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <poll.h>
#define BAUDRATE 500000
#define UART_DEVICE1 "/dev/ttyAMA4"
#define UART_DEVICE2 "/dev/ttyTHS2"
#define UART_POLL_TIMEOUT_5000US 5000
const int speed_arr[] =
{
B500000, B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400,
B1800, B1200, B600, B300
};
const int name_arr[] =
{
500000, 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400,
1800, 1200, 600, 300
};
int set_uart_speed(int fd, int speed)
{
if (fd <= 0)
{
return -1;
}
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for (i = 0; i < (int)(sizeof(speed_arr) / sizeof(int)); i++)
{
if (speed == name_arr[i])
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0)
{
perror("tcsetattr fd1");
return -1;
}
tcflush(fd, TCIOFLUSH);
return 0;
}
}
return -1;
}
int uart_init(const char *uart_port)
{
int fd = -1;
int status ;
struct termios options;
memset(&options, 0, sizeof(struct termios));
if (uart_port)
{
fd = open(uart_port, O_RDWR | O_NOCTTY | O_NDELAY);
}
if (fd <= 0)
{
printf("uart port open failure\n");
return -1;
}
options.c_cflag = HUPCL | CS8 | CREAD | CLOCAL;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
options.c_iflag = IGNPAR;
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 1;
if (tcsetattr(fd, TCSANOW, &options) != 0)
{
printf("error: tcsetattr failed\n");
return -1;
}
ioctl(fd,TIOCMGET,&status);
status |= TIOCM_RTS;//RTS引脚低电平
ioctl(fd,TIOCMSET,&status);
tcflush(fd, TCIOFLUSH);
return fd;
}
int uart_read(int fd, unsigned char *pbuffer, int nlen, int timeout)
{
if (pbuffer == NULL || nlen == 0 || fd < 0)
{
printf("read_uart: buffer is null or invalid uart port.\n");
return -1;
}
int len = 0;
int ret = 0;
fd_set rfds;
int retval = 0;
struct timeval tv;
while (len < nlen)
{
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = timeout / 1000000;
tv.tv_usec = timeout % 1000000;
retval = select(fd + 1, &rfds, NULL, NULL, &tv);
if (retval < 0)
{
return -1;
}
else if (retval == 0)
{
// Translated comment from Chinese:
// Where the return 0 is a bug, because even if the successful read data,
// the last exit is also a timeout to exit
//return 0;
break;
}
else if (FD_ISSET(fd, &rfds))
{
ret = read(fd, pbuffer + len, nlen - len);
//printf("read: ");
//for (int j = 0; j < ret; ++j)
//{
// printf("%02x ", (pbuffer+len)[j]);
//}
//printf("\n");
len += ret > 0 ? ret : 0;
if (len >= nlen)
{
return len;
}
}
else
{
usleep(1);
}
}
return len ;
}
int uart_write(int fd, const unsigned char *pbuffer, int nlen)
{
if (pbuffer == NULL || nlen == 0 || fd < 0)
{
printf("write_uart: buffer (%p: %d) is null or invalid uart fd (%d).\n",
pbuffer, nlen, fd);
return -1;
}
int ret = 0;
int len = 0;
fd_set wfds;
int retval = 0;
struct timeval tv;
//printf("write: ");
while (len < nlen)
{
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
tv.tv_sec = 0;
tv.tv_usec = 30000;
retval = select(fd + 1, NULL, &wfds, NULL, &tv);
if (retval < 0)
{
perror("uart write ");
break;
}
else if (retval == 0)
{
break;
}
else if (FD_ISSET(fd, &wfds))
{
ret = write(fd, pbuffer + len, nlen - len);
//printf("%02x %02x", (unsigned char)(*(pbuffer + len)),
//(unsigned char)(*(pbuffer + len + 1)));
len += ret > 0 ? ret : 0;
}
else
{
usleep(1);
}
}
//printf("\n");
if (len != nlen)
{
printf("can't write %d bytes from %d just len = %d \n", nlen, fd, len);
}
//int nwrite_len =write(fd,pbuffer,nlen);
//if(nwrite_len<=0)
//{
// printf("write data to uart error\n");
// return -1;
//}
return len;
}
void *proc_uart_write_thread(void *arg)
{
unsigned char buf[100]={0};
int uart_fd = *((int *)arg);
int len = 0;
char *str = NULL;
while(true){
printf("please input the string:\n");
scanf("%s",buf);
str = (char*)buf;
len = strlen(str);
printf("len:%d\n",len);
uart_write(uart_fd,buf,len);
str = NULL;
}
return ((void*)0);
}
int main(int argc, char *argv[])
{
int fd;
pthread_t thread_uart_id;
int ret;
if(argc != 2){
printf("Usage: uart_test [ttyS2/ttyS1]\n");
exit(1);
}
if(strcmp("ttyS1",argv[1]) == 0){
fd = uart_init(UART_DEVICE1);
if (fd < 0){
printf("init uart (%s) fail\n",UART_DEVICE1);
exit(1);
}
}else if(strcmp("ttyS2",argv[1]) == 0){
fd = uart_init(UART_DEVICE2);
if (fd < 0){
printf("init uart (%s) fail\n",UART_DEVICE2);
exit(1);
}
}else{
printf("Usage: uart_test [ttyS2/ttyS1]\n");
exit(1);
}
set_uart_speed(fd, BAUDRATE);
ret = pthread_create(&thread_uart_id, NULL, proc_uart_write_thread, &fd);
while(1){
sleep(5);
}
close(fd);
return 0;
}
uart 485串口 write 实现
最新推荐文章于 2024-08-16 22:19:35 发布