一、设置uart的例子,测试uart,发出方波,或去读数据
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <string.h>
int main()
{
char *filename1 = NULL;
char buf1[100]={0x55,0x55,0x55,0x55};
char buf2[100]={0x55,0x55,0x55,0x55};
int ret = -1;
int Oflags = 0;
int fd1 = -1;
int len = 0;
filename1 = "/dev/ttyAMA2";
struct termios options;
fd1 = open(filename1, O_RDWR);
if (fd1 < 0) {
printf("app open %s fail\n", filename1);
return 0;
} else {
printf("app open %s success\r\n",filename1);
}
//int flags = fcntl(fd1, F_GETFL, 0);
//fcntl(fd1, F_SETFL, flags | O_NONBLOCK);
if(tcgetattr(fd1,&options) != 0)
{
printf("get serial attibute fail");
return(-1);
}
else{
printf("get serial attibute success");
printf("control model options.c_cflag : %d\n",options.c_cflag);
printf("data bit options.c_cflag : %d\n",options.c_cflag);
printf("parity bit options.c_cflag : %d\n",options.c_cflag);
printf("raw data output options.c_oflag : %d\n",options.c_oflag);
}
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
//set control model
options.c_cflag |= CLOCAL;
options.c_cflag |= CREAD;
options.c_cflag &= ~CRTSCTS;
//select data bit
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//select parity bit
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
// set stopbit
options.c_cflag &= ~CSTOPB;
//set raw data output
options.c_oflag &= ~OPOST;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//options.c_lflag &= ~(ISIG | ICANON);
//set wait time
options.c_cc[VTIME] = 1;
options.c_cc[VMIN] = 1;
tcflush(fd1,TCIFLUSH);
//set the attribute to HiSerial device
if (tcsetattr(fd1,TCSANOW,&options) != 0)
{
printf("set serial attibute fail");
return (-1);
}
else
{
printf("set serial attibute success");
printf("control model options.c_cflag : %d\n",options.c_cflag);
printf("data bit options.c_cflag : %d\n",options.c_cflag);
printf("parity bit options.c_cflag : %d\n",options.c_cflag);
printf("raw data output options.c_oflag : %d\n",options.c_oflag);
}
printf("\r\n");
memset(buf1,0x0,sizeof(buf1));
memset(buf2,0x0,sizeof(buf2));
buf2[0]= 0x55;
buf2[1]= 0x55;
buf2[2]= 0x55;
buf2[3]= 0x55;
buf2[4]= 0x55;
while(1)
{
#if 1
len = 0;
len = read(fd1, buf1,10);
if(len < 0)
{
printf("app read serial fail\n");
}
else
{
printf("app read serial success %d byte\r\n",len);
printf("app read serial success: ASCLL ");
for(int i = 0; i < len; i++)
printf(" %c ",buf1[i]);
}
printf("\r\n");
#endif
//len = 0;
len = write(fd1,buf1,len);
if(len < 0)
{
printf("app write serial fail\r\n");
}
else
{
printf("app write buf1 serial success %d byte\r\n",len);
}
memset(buf1,0,sizeof(buf1));
sleep(1);
//len = 0;
len = write(fd1,buf2,len);
if(len < 0)
{
printf("app write serial fail\n");
}
else
{
printf("app write buf2 serial success %d byte\r\n",len);
}
printf("app is run ......\r\n");
}
close(fd1);
return 0;
}
二、第二种改进,方便
tty_uart_test.c 测试程序
#include <fcntl.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <termios.h>
#include <pthread.h>
#if 1
static const char *device = "/dev/ttyTHS1";
#define DEFAULT_BR B115200
#else
static const char *device = "/dev/ttyTHS0";
#define DEFAULT_BR B9600
#endif
int uart_open(void)
{
int fd;
fd = open(device, O_RDWR|O_NOCTTY);
if(fd < 0){
printf("error on open\n");
return -1;
}
return fd;
}
int uart_cfg(int fd)
{
int ret;
struct termios tm;
speed_t ispeed = DEFAULT_BR;
speed_t ospeed = DEFAULT_BR;
if(tcgetattr(fd, &tm) < 0) {
printf("error on tcgetattr\n");
return -1;
}
cfsetispeed(&tm, ispeed);
cfsetospeed(&tm, ospeed);
//8 bit
tm.c_cflag &= ~CSIZE;
tm.c_cflag |= CS8; //8bit stop
//no ODD/EVEN
tm.c_cflag &= ~PARENB;
tm.c_iflag &= ~INPCK;
//1 bit stop
tm.c_cflag &= ~CSTOPB;
//no flow control
tm.c_cflag &= ~CRTSCTS;
tm.c_iflag &= ~(IXON | IXOFF | IXANY);
/* 忽略modem(调制解调器)控制线 */
tm.c_cflag |= CLOCAL;
//enable receive
tm.c_cflag |= CREAD; //
/* 禁能执行定义(implementation-defined)输出处理,意思就是输出的某些特殊数
据会作特殊处理,如果禁能的话那么就按原始数据输出 */
tm.c_oflag &= ~OPOST;
/**
* 设置本地模式位原始模式
* ICANON:规范输入模式,如果设置了那么退格等特殊字符会产生实际动作
* ECHO:则将输入字符回送到终端设备
* ECHOE:如果ICANON也设置了,那么收到ERASE字符后会从显示字符中擦除一个字符
* 通俗点理解就是收到退格键后显示内容会往回删一个字符
* ISIG:使终端产生的信号起作用。(比如按ctrl+c可以使程序退出)
*/
tm.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/**
* 设置等待时间和最小接收字符
* 这两个值只有在阻塞模式下有意义,也就是说open的时候不能传入O_NONBLOCK,
* 如果经过了c_cc[VTIME]这么长时间,缓冲区内有数据,但是还没达到c_cc[VMIN]个
* 数据,read也会返回。而如果当缓冲区内有了c_cc[VMIN]个数据时,无论等待时间
* 是否到了c_cc[VTIME],read都会返回,但返回值可能比c_cc[VMIN]还大。如果将
* c_cc[VMIN]的值设置为0,那么当经过c_cc[VTIME]时间后read也会返回,返回值
* 为0。如果将c_cc[VTIME]和c_cc[VMIN]都设置为0,那么程序运行的效果与设置
* O_NONBLOCK类似,不同的是如果设置了O_NONBLOCK,那么在没有数据时read返回-1,
* 而如果没有设置O_NONBLOCK,那么在没有数据时read返回的是0。
*/
tm.c_cc[VTIME] = 0; //wait time
tm.c_cc[VMIN] = 1; //read 1 byte at least
/* 清空读缓冲区 */
tcflush(fd, TCIFLUSH);
if(tcsetattr(fd, TCSANOW, &tm) < 0) {
printf("error on tcsetattr\n");
return -1;
}
return 0;
}
static void print_usage(const char *prog)
{
printf("Usage: %s [-hDrw]\n", prog);
printf("usage: uart_test\n"
" -h --help print usage\n"
" -D --device device to use (eg /dev/ttyTHS1)\n"
" -r --read loop fore read\n"
" -w --write str\n"
);
printf("\n");
exit(1);
}
int fd = -1;
uint8_t buf[1024];
void *soc_update_nor_pthread(void *arg)
{
uint8_t data = 0;
printf("start uart rx thread\n");
while (1)
{
read(fd, buf, 1);
printf("%d\n", buf[0]);
}
printf("Thread_1 over\n");
pthread_exit((void *)1);
}
int main(int argc, char **argv)
{
int opt;
uint8_t val;
while (1)
{
static const struct option lopts[] =
{
{ "help", 0, 0, 'h' },
{ "device", 1, 0, 'D' },
{ "read", 0, 0, 'r' },
{ "write", 1, 0, 'w' },
{ NULL, 0, 0, 0 },
};
int c;
c = getopt_long(argc, argv, "hD:rw:", lopts, NULL);
if (c == -1)
break;
switch (c) {
case 'h':
print_usage(argv[0]);
break;
case 'D':
device = optarg;
fd = uart_open();
if(fd < 0) {
printf("open %s error : %d\n", device, fd);
return -1;
}
if(uart_cfg(fd) < 0) {
printf("setting %s error : %d\n", device, fd);
return -1;
}
printf("open %s : %d\n", device, fd);
break;
case 'r':
if(fd < 0) {
printf("error: open device first\n");
print_usage(argv[0]);
return -1;
}
while(1){
read(fd, buf, sizeof(1024));
printf("%s", buf);
}
break;
case 'w':
if(fd < 0) {
printf("error: open device first\n");
print_usage(argv[0]);
return -1;
}
memset(buf, 0, sizeof(buf));
strncpy(buf, optarg, strlen(optarg));
buf[strlen(optarg)] = '\n';
write(fd, buf, strlen(buf));
printf("\nwrite %d : %s\n", strlen(buf), buf);
int rtv1;
pthread_t tid1, tid2, tid3;
pthread_attr_t attr;
pthread_attr_init(&attr);
// pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //设置线程的分离属性为分离状态
rtv1 = pthread_create(&tid1, &attr, soc_update_nor_pthread, (void *)0);
if (0 != rtv1)
{
printf("create thread failed\n");
return -1;
}
while(1){
write(fd, buf, strlen(buf));
sleep(1);
}
pthread_join(tid1, NULL);
break;
default:
print_usage(argv[0]);
break;
}
}
if(fd > 0)
close(fd);
else if(argc < 2)
print_usage(argv[0]);
return 0;
}
编译成二进制可执行文件后
在开发板终端 输入指令, ./tty_uart_test -D /dev/ttyTHS1 -w 0x55 ,输出方波,即可测试uart是否发送数据,用示波器看是否有收到方波