/***************************************************************
Copyright 2024-2029. All rights reserved.
文件名 : 01_usr_serial.c
作者 : tangmingfei2013@126.com
版本 : V1.0
描述 : linux 串口应用程序接口
其他 : 无
日志 : 初版V1.0 2024/03/01
***************************************************************/
#include "usr_serial.h"
/* Private define ------------------------------------------------------------*/
#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)
#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 ch's 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 speed
cfsetospeed(&termios_new, speed); // set output speed
}
static unsigned int set_portattr ( unsigned int baudrate, // 1200 2400 4800 9600 .. 115200
unsigned int databit, // 5, 6, 7, 8
const char *stopbit, // "1", "1.5", "2"
char 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 */
没有合适的资源?快使用搜索试试~ 我知道了~
Linux环境下使用interrupt方式操作UART
共4个文件
c:2个
makefile:1个
h:1个
需积分: 5 1 下载量 29 浏览量
2024-03-04
13:43:58
上传
评论
收藏 4KB ZIP 举报
温馨提示
Linux环境下使用interrupt方式操作UART,实现功能如下 1. 串口发送数据 2. 串口通过终端方式接收数据 函数接口如下: 打开串口函数:usr_serial_open 关闭串口函数: usr_serial_close 发送数据函数: usr_serial_sendbytes 接收数据函数: usr_serial_readbytes Makefile 测试源码
资源推荐
资源详情
资源评论
收起资源包目录
Linux环境下使用interrupt方式操作UART.zip (4个子文件)
02_usr_serial_interrupt
test_serial.c 2KB
Makefile 372B
usr_serial.c 6KB
usr_serial.h 914B
共 4 条
- 1
资源评论
mftang
- 粉丝: 5432
- 资源: 110
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功