平顶山建设局网站,做电商网站用什么软件开发,网站建设月流量,网络培训机构目录
概述
1 Linux环境下UART设备
2 轮询方式操作UART功能实现
2.1 打开串口函数#xff1a;usr_serial_open
2.2 关闭串口函数#xff1a; usr_serial_close
2.3 发送数据函数#xff1a; usr_serial_sendbytes
2.4 接收数据函数#xff1a; usr_serial_readinterr…目录
概述
1 Linux环境下UART设备
2 轮询方式操作UART功能实现
2.1 打开串口函数usr_serial_open
2.2 关闭串口函数 usr_serial_close
2.3 发送数据函数 usr_serial_sendbytes
2.4 接收数据函数 usr_serial_readinterrupt
3 完整代码
3.1 usr_serial.c 文件内容
3.1 usr_serial.h 文件内容
4 编写测试代码
4.1 编写测试代码
4.2 编写测试代码的Makefile
5 测试中断模式下串口数据的发送和接收功能 源代码下载地址Linux环境下使用interrupt方式操作UART资源-CSDN文库
概述
本文介绍Linux环境下使用interrupt方式操作UART的方法实现了串口打开关闭发送数据接收数据功能还编写测试代码验证该功能。
1 Linux环境下UART设备
在linux环境下,UART作为一个终端设备存在可使用命令 系统会罗列出该目录下所有的device,其中以tty开头的设备为终端设备。串口也是这些设备之一。
ls /dev/ -l
执行该命令后可以看见许多以tty开头的设备 user根据板卡的信息找到对应的端口然后才能使用这些串口笔者使用是基于iMX6ull芯片的板卡板卡上COM1被用于调试终端COM3可作为用户终端。 2 轮询方式操作UART功能实现
2.1 打开串口函数usr_serial_open
函数参数
参数描述port终端设备: /dev/tty0baudrate波特率 1200/2400/4800 ... /115200databit数据bit位 /5/6/7/8stopbit停止位1 / 1.5 / 2parity奇偶位使能 N / E / O
函数实现方法
代码 43行 打开端口
代码 49行 保存termios数据结构中旧的参数
代码 51行设置当前用户参数 源代码
int usr_serial_open( char *port, unsigned int baudrate, unsigned int databit, const char *stopbit, char parity)
{int err;fd open (port, O_RDWR | O_NOCTTY | O_NDELAY);if (-1 fd) {fprintf(stderr, cannot open port %s\n, port);return (-1);}tcgetattr (fd, termios_old); /* save the form termios value */err set_portattr (baudrate, databit, stopbit, parity);if ( err ) {fprintf ( stderr, \nport %s cannot set baudrate at %d\n,port, baudrate);}usr_baudrate baudrate;return fd;
}
2.2 关闭串口函数 usr_serial_close
函数实现方法
代码 64行 恢复termios default参数
代码 65行关闭fd端口 void usr_serial_close( void )
{/* flush output data before close and restore old attribute */tcsetattr(fd, TCSADRAIN, termios_old);close(fd);
} 2.3 发送数据函数 usr_serial_sendbytes
函数参数
参数描述*data存贮数据的数组datalength发送的数据长度
函数实现方法
代码 72行 使用write函数发送数据 2.4 接收数据函数 usr_serial_readinterrupt
函数参数
参数描述*data存贮数据的数组datalength接收的数据长度
函数实现方法
代码 100~102行 配置接收中断
代码 104行 使用read函数写数据 unsigned int usr_serial_readinterrupt (void *data, unsigned int datalength)
{int total_len 0;/*** caculate the time of 5 characters and get the maxim* with 3ms and 5 chs time*/tv_timeout.tv_sec 0;tv_timeout.tv_usec ( (CH_TO_WAIT * CH_BITS) * (1000000/usr_baudrate));while(1){FD_ZERO (fs_read);FD_SET (fd, fs_read);select (fd 1, fs_read, NULL, NULL, tv_timeout);total_len read(fd, data, datalength);if (total_len 0) {printf(Receive %d bytes: %.*s\n, total_len, (char*)data);return total_len;}}return total_len;}
3 完整代码
代码文件命名为usr_serial 包含两个文件
usr_serial.c
usr_serial.h3.1 usr_serial.c 文件内容
/***************************************************************
Copyright 2024-2029. All rights reserved.
文件名 : 01_usr_serial.c
作者 : tangmingfei2013126.com
版本 : V1.0
描述 : linux 串口应用程序接口
其他 : 无
日志 : 初版V1.0 2024/03/01***************************************************************/
#include usr_serial.h/* Private define ------------------------------------------------------------*/
#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud2)
#define TIMEOUT_USEC 0#define CH_TO_WAIT 5
#define CH_BITS 11/* Private variables ---------------------------------------------------------*/
static unsigned int fd; static struct timeval tv_timeout;
static struct termios termios_old;
static struct termios termios_new;static fd_set fs_read;
static unsigned int usr_baudrate;/* Private function prototypes -----------------------------------------------*/
static speed_t baudrate_to_Bxx (unsigned int baudrate);
static void set_data_bit (unsigned int databit);
static unsigned int set_portattr ( unsigned int baudrate,unsigned int databit, const char *stopbit,char parity);int usr_serial_open( char *port, unsigned int baudrate, unsigned int databit, const char *stopbit, char parity)
{int err;fd open (port, O_RDWR | O_NOCTTY | O_NDELAY);if (-1 fd) {fprintf(stderr, cannot open port %s\n, port);return (-1);}tcgetattr (fd, termios_old); /* save the form termios value */err set_portattr (baudrate, databit, stopbit, parity);if ( err ) {fprintf ( stderr, \nport %s cannot set baudrate at %d\n,port, baudrate);}usr_baudrate baudrate;return fd;
}void usr_serial_close( void )
{/* flush output data before close and restore old attribute */tcsetattr(fd, TCSADRAIN, termios_old);close(fd);
}unsigned int usr_serial_sendbytes (void * data, unsigned int datalength)
{unsigned int total_len 0;total_len write(fd, data, datalength);return (total_len);
}int usr_serial_readbytes (void *data, unsigned int datalength)
{unsigned int total_len 0;total_len read(fd, data, datalength);if (total_len 0) {printf(Receive %d bytes: %.*s\n, total_len, (char*)data);}return (total_len);
}unsigned int usr_serial_readinterrupt (void *data, unsigned int datalength)
{int total_len 0;/*** caculate the time of 5 characters and get the maxim* with 3ms and 5 chs time*/tv_timeout.tv_sec 0;tv_timeout.tv_usec ( (CH_TO_WAIT * CH_BITS) * (1000000/usr_baudrate));while(1){FD_ZERO (fs_read);FD_SET (fd, fs_read);select (fd 1, fs_read, NULL, NULL, tv_timeout);total_len read(fd, data, datalength);if (total_len 0) {printf(Receive %d bytes: %.*s\n, total_len, (char*)data);return total_len;}}return total_len;}static void set_data_bit (unsigned int databit)
{termios_new.c_cflag ~CSIZE;switch (databit) {default:case 8:termios_new.c_cflag | CS8;break;case 7:termios_new.c_cflag | CS7;break;case 6:termios_new.c_cflag | CS6;break;case 5:termios_new.c_cflag | CS5;break;}
}static void set_stopbit (const char *stopbit)
{if (0 strcmp (stopbit, 1)) {termios_new.c_cflag ~CSTOPB; /* 1 stop bit */}else if (0 strcmp (stopbit, 1.5)) {termios_new.c_cflag ~CSTOPB; /* 1.5 stop bits */}else if (0 strcmp (stopbit, 2)) {termios_new.c_cflag | CSTOPB; /* 2 stop bits */}else {termios_new.c_cflag ~CSTOPB; /* 1 stop bit */}
}static void set_parity (char parity)
{switch (parity) {case N: /* no parity check */termios_new.c_cflag ~PARENB;break;case E: /* even */termios_new.c_cflag | PARENB;termios_new.c_cflag ~PARODD;break;case O: /* odd */termios_new.c_cflag | PARENB;termios_new.c_cflag | ~PARODD;break;default: /* no parity check */termios_new.c_cflag ~PARENB;break;}
}static speed_t baudrate_to_Bxx (unsigned int baudrate)
{switch (baudrate) {case 0:return (B0);case 50:return (B50);case 75:return (B75);case 110:return (B110);case 134:return (B134);case 150:return (B150);case 200:return (B200);case 300:return (B300);case 600:return (B600);case 1200:return (B1200);case 2400:return (B2400);case 9600:return (B9600);case 19200:return (B19200);case 38400:return (B38400);case 57600:return (B57600);case 115200:return (B115200);default:return (B9600);}
}static void set_baudrate (unsigned int baudrate)
{speed_t speed;speed baudrate_to_Bxx (baudrate); /* set baudrate */cfsetispeed(termios_new, speed); // set input speedcfsetospeed(termios_new, speed); // set output speed
}static unsigned int set_portattr ( unsigned int baudrate, // 1200 2400 4800 9600 .. 115200unsigned int databit, // 5, 6, 7, 8const char *stopbit, // 1, 1.5, 2char parity) // N(o), O(dd), E(ven)
{bzero(termios_new, sizeof (termios_new));cfmakeraw (termios_new);set_baudrate (baudrate);termios_new.c_cflag | CLOCAL | CREAD; /* | CRTSCTS */set_data_bit (databit);set_parity (parity);set_stopbit (stopbit);termios_new.c_cc[VTIME] 1; /* unit: 1/10 second. */termios_new.c_cc[VMIN] 255; /* minimal characters for reading */return (tcsetattr (fd, TCSANOW, termios_new));
}/* End of this file */3.1 usr_serial.h 文件内容
#ifndef __USR_SERIAL_H
#define __USR_SERIAL_H#include termios.h /* tcgetattr, tcsetattr */
#include stdio.h /* perror, printf, puts, fprintf, fputs */
#include unistd.h /* read, write, close */
#include fcntl.h /* open */
#include sys/signal.h
#include sys/types.h
#include string.h /* bzero, memcpy */
#include limits.h /* CHAR_MAX */#ifdef __cplusplus
extern C {
#endifint usr_serial_open( char *port, unsigned int baudrate, unsigned int databit, const char *stopbit, char parity);
void usr_serial_close( void );unsigned int usr_serial_sendbytes (void * data, unsigned int datalength);
int usr_serial_readbytes (void *data, unsigned int datalength);
unsigned int usr_serial_readinterrupt (void *data, unsigned int datalength);#ifdef __cplusplus
}
#endif#endif /* __USR_SERIAL_H */4 编写测试代码
4.1 编写测试代码
代码实现功能介绍
代码 39行初始化串口设备设置baud数据位停止位等参数
代码 48行从串口读取数据
代码 55行向串口写数据 4.2 编写测试代码的Makefile
代码实现功能介绍
代码 2行编译器地址
代码 3行linux内核地址
代码 3行链接的.o文件名
代码 6行生成可执行型文件 5 测试中断模式下串口数据的发送和接收功能
使用Make命令编译代码然后将生成的可执行性文件copy到NFS的共享目录下然后在板卡中执行。
在代码中定义要发送的数据如下 strcpy(buf, I am from iMX.6ULL board, hello world! \r\n); PC端使用串口调试助手接收数据详细信息如下