您的位置:首页 > 运维架构 > Linux

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串口收发短接,以实现自环测试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐