Linux下串口编程实例,实现0~255数据自环测试
2012-03-31 17:25
671 查看
#include <stdio.h> /*标准输入输出定义*/
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
#include <errno.h> /*错误号定义*/
#include <string.h>
#define FALSE
-1
#define TRUE
0
/*
设置串口
最基本的设置串口包括波特率设置,效验位和停止位设置。
串口的设置主要是设置 struct termios 结构体的各成员值。
struct termio
{
unsigned short c_iflag;
// 输入模式标志
unsigned short c_oflag;
// 输出模式标志
unsigned short c_cflag;
// 控制模式标志
unsigned short c_lflag;
// local mode flags
unsigned char c_line;
// line discipline
unsigned char c_cc[NCC]; //
control characters
};
*/
/**
*@brief 设置串口通信速率
*@param fd 类型 int 打开串口的文件句柄
*@param speed 类型 int 串口速度
*@return void
*/
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,
19200, 9600, 4800, 2400, 1200, 300, };
int set_speed(int fd, int speed){
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < 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 fd");
return;
}
tcflush(fd,TCIOFLUSH);
return TRUE;
}
}
fprintf(stderr,"Unsupported speed\n");
return FALSE;
}
/**
*@brief 设置串口数据位,停止位和效验位
*@param fd 类型 int 打开的串口文件句柄
*@param databits 类型 int 数据位 取值 为 7 或者8
*@param stopbits 类型 int 停止位 取值为 1 或者2
*@param parity 类型 int 效验类型 取值为N,E,O,,S
*/
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0) {
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
// important
options.c_cflag |= CLOCAL | CREAD;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME] = 10; /* 设置超时*/
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
/**********************************************************************
代码说明:使用串口二测试的,发送的数据是字符,
但是没有发送字符串结束符号,所以接收到后,后面加上了结束符号。
**********************************************************************/
/*********************************************************************/
int OpenDev(char *Dev)
{
int
fd = open( Dev, O_RDWR ); //| O_NOCTTY | O_NDELAY
if (-1 == fd)
{
perror("Can't Open Serial Port");
return -1;
}
else
return fd;
}
int main(int argc, char **argv)
{
int i, fd;
int nread, nwrite, cnt, index, cmd;
unsigned char rcv_buff[512];
unsigned char send_buff[512];
char dis_buff[512];
char *dev = "/dev/ttyS0"; //串口一
if((fd=OpenDev(dev)) == FALSE)
{
return -1;
}
else
{
if(set_speed(fd,38400) == FALSE)
{
printf("Set Speed Error\n");
exit (0);
}
if (set_Parity(fd,8,1,'N') == FALSE)
{
printf("Set Parity Error\n");
exit (0);
}
}
while(1)
{
printf("sellect: w|r|q\n");
cmd = getchar();
switch(cmd)
{
case 'w':
printf("test write\n");
//发送缓冲区字节数定义
for(i=0; i<256; i++)
send_buff[i] = i;
cnt= write(fd,send_buff,256);
if(cnt == -1)
printf("Wirte sbuf error.\n");
else
printf("Wirte:%s \tcnt:%d\n", send_buff, cnt);
break;
case 'r':
printf("test read\n");
cnt = read(fd, rcv_buff, sizeof(rcv_buff));
if(cnt == -1)
printf("Read sbuf error.\n");
else
{
printf("Read: \tcnt:%d\n", cnt);
for(i=0; i<cnt; i++)
printf("%d ", rcv_buff[i]);
printf("\n");
}
break;
case 'q':
close(fd);
return 0;
case '\n':
break;
default:
printf("worry cmd!\n");
break;
}
}
close(fd);
return 0;
}
注:此实验需将PC串口收发短接,以实现自环测试。
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
#include <errno.h> /*错误号定义*/
#include <string.h>
#define FALSE
-1
#define TRUE
0
/*
设置串口
最基本的设置串口包括波特率设置,效验位和停止位设置。
串口的设置主要是设置 struct termios 结构体的各成员值。
struct termio
{
unsigned short c_iflag;
// 输入模式标志
unsigned short c_oflag;
// 输出模式标志
unsigned short c_cflag;
// 控制模式标志
unsigned short c_lflag;
// local mode flags
unsigned char c_line;
// line discipline
unsigned char c_cc[NCC]; //
control characters
};
*/
/**
*@brief 设置串口通信速率
*@param fd 类型 int 打开串口的文件句柄
*@param speed 类型 int 串口速度
*@return void
*/
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,
19200, 9600, 4800, 2400, 1200, 300, };
int set_speed(int fd, int speed){
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < 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 fd");
return;
}
tcflush(fd,TCIOFLUSH);
return TRUE;
}
}
fprintf(stderr,"Unsupported speed\n");
return FALSE;
}
/**
*@brief 设置串口数据位,停止位和效验位
*@param fd 类型 int 打开的串口文件句柄
*@param databits 类型 int 数据位 取值 为 7 或者8
*@param stopbits 类型 int 停止位 取值为 1 或者2
*@param parity 类型 int 效验类型 取值为N,E,O,,S
*/
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0) {
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
// important
options.c_cflag |= CLOCAL | CREAD;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME] = 10; /* 设置超时*/
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
/**********************************************************************
代码说明:使用串口二测试的,发送的数据是字符,
但是没有发送字符串结束符号,所以接收到后,后面加上了结束符号。
**********************************************************************/
/*********************************************************************/
int OpenDev(char *Dev)
{
int
fd = open( Dev, O_RDWR ); //| O_NOCTTY | O_NDELAY
if (-1 == fd)
{
perror("Can't Open Serial Port");
return -1;
}
else
return fd;
}
int main(int argc, char **argv)
{
int i, fd;
int nread, nwrite, cnt, index, cmd;
unsigned char rcv_buff[512];
unsigned char send_buff[512];
char dis_buff[512];
char *dev = "/dev/ttyS0"; //串口一
if((fd=OpenDev(dev)) == FALSE)
{
return -1;
}
else
{
if(set_speed(fd,38400) == FALSE)
{
printf("Set Speed Error\n");
exit (0);
}
if (set_Parity(fd,8,1,'N') == FALSE)
{
printf("Set Parity Error\n");
exit (0);
}
}
while(1)
{
printf("sellect: w|r|q\n");
cmd = getchar();
switch(cmd)
{
case 'w':
printf("test write\n");
//发送缓冲区字节数定义
for(i=0; i<256; i++)
send_buff[i] = i;
cnt= write(fd,send_buff,256);
if(cnt == -1)
printf("Wirte sbuf error.\n");
else
printf("Wirte:%s \tcnt:%d\n", send_buff, cnt);
break;
case 'r':
printf("test read\n");
cnt = read(fd, rcv_buff, sizeof(rcv_buff));
if(cnt == -1)
printf("Read sbuf error.\n");
else
{
printf("Read: \tcnt:%d\n", cnt);
for(i=0; i<cnt; i++)
printf("%d ", rcv_buff[i]);
printf("\n");
}
break;
case 'q':
close(fd);
return 0;
case '\n':
break;
default:
printf("worry cmd!\n");
break;
}
}
close(fd);
return 0;
}
注:此实验需将PC串口收发短接,以实现自环测试。
相关文章推荐
- 有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0<n
- linux环境下C语言实现非阻塞方式读取字符串数据的串口测试程序,即串口工具的编写
- linux下c编程之内存共享shemget函数的实现及案例-bmi体重身高测试2
- 【十大算法实现之KNN】KNN算法实例(含测试数据和源码)
- Linux下安装Mysql多实例作为数据备份服务器实现多主到一从多实例的备份
- 树莓派Linux串口编程实现自发自收
- linux下串口编程简单实例
- linux下c编程之内存共享shemget函数的实现及案例-bmi体重身高测试1
- linux串口编程传送二进制数据时遇到0x0d,0x11和0x13会被丢掉问题
- Linux编程实践——文件I/O缓冲区测试及cat简单实现
- linux 串口编程实现代码
- Linux网络编程:使用select函数实现socket 收发数据
- Linux下实现流水灯等功能的LED驱动代码及测试实例
- 用蓝牙串口模块,实现和笔记本电脑自带蓝牙的数据收发测试
- LinuxC/C++编程基础(8) 基于条件变量实现生产者与消费者的实例
- Linux下的串口编程实例
- 嵌入式成长轨迹24【Linux应用编程强化】【Linux下的C编程 下】【实例:Linux命令实现】
- linux系统管理客户端2--串口实现测试代码编写
- Linux 程序设计学习笔记----终端及串口编程及实例应用
- windows下,C++实现串口编程,串间口转发数据