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

Linux下的串口总线驱动(四)

2012-10-28 20:56 106 查看
版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127
六.串口测试代码

我们已经配置了mini2440的串口配置,然后根据mini2440开发板的硬件电路知道S3C2440本身总共有3个串口:UART0、1、2,其中UART0,1可组合为一个全功能的串口,在大部分的应用中,我们只用到3个简单的串口功能(本开发板提供的Linux和WinCE驱动也是这样设置的),即通常所说的发送(TXD)和接收(RXD),它们分别对应板上的CON1、CON2、CON3,这3个接口都是从CPU直接引出的,是TTL电平。为了方便用户使用,其中UART0做了RS232电平转换,它们对应于COM0,可以通过附带的直连线与PC机互相通讯。我们这个实验选用CON1作为测试串口的端口。用导线将CON1的1号(TXD1)和2号(RXD1)引脚相连,实现自发自收。

实验环境:内核linux2.6.32.2,arm-linux-gcc交叉编译器,mini2440开发板

内核配置:选中s3c2440.o samsung.o serial_core.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o。

测试代码如下:

#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 <getopt.h>

#include <string.h>

#define FALSE 1

#define TRUE 0

char *recchr="We received:\"";

int speed_arr[] = {

B921600, B460800, B230400, B115200, B57600, B38400, B19200,

B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,

B4800, B2400, B1200, B300,

};

int name_arr[] = {

921600, 460800, 230400, 115200, 57600, 38400, 19200,

9600, 4800, 2400, 1200, 300, 38400, 19200, 9600,

4800, 2400, 1200, 300,

};

void 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 fd1");

return;

}

tcflush(fd,TCIOFLUSH); //刷新输入输出队列

}

}

/*

*@brief
设置串口数据位,停止位和效验位

*@param fd 类型 int 打开的串口文件句柄*

*@param databits类型 int数据位 取值为 7或者8*

*@param stopbits类型 int停止位 取值为 1或者2*

*@param parity 类型 int 效验类型取值为N,E,O,,S

*@param flowctrl类型 int 流控 取值无

*/

int set_Parity(int fd,int databits,int stopbits,int parity, int flowctrl)

{

struct termios options;

if ( tcgetattr( fd,&options) != 0) { //获取线路设置

perror("SetupSerial 1");

return(FALSE);

}

options.c_cflag &= ~CSIZE ; //利用CSIZE掩码把正确位从cflag中分离并清零,其他位不变

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; //相应位置0

break;

case 2:

options.c_cflag |= CSTOPB;

break;

default:

fprintf(stderr,"Unsupported stop bits\n");

return (FALSE);

}

/* Set flow control */

if (flowctrl)

options.c_cflag |= CRTSCTS;

else

options.c_cflag &= ~CRTSCTS;

/* Set input parity option */

if (parity != 'n')

options.c_iflag |= INPCK;

// VTIME设定字节输入时间计时器

options.c_cc[VTIME] = 150; // 15 seconds

//VMIN设定满足读取功能的最低字节个数

options.c_cc[VMIN] = 0;

options.c_lflag &= ~(ECHO | ICANON);

tcflush(fd,TCIFLUSH); //刷新输入队列

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 fd, next_option, havearg = 0;

char *device = "/dev/ttySAC1"; /* Default device */

int speed = 115200;

int flowctrl = 0;

int nread; /* Read the counts of data */

char buff[512]; /* Recvice data buffer */

pid_t pid;

char *xmit = "com test by ptr 2012"; /* Default send data */

sleep(1);

fd = OpenDev(device);

if (fd > 0) {

set_speed(fd,speed);

} else {

fprintf(stderr, "Error opening %s: %s\n", device, strerror(errno));

exit(1);

}

if (set_Parity(fd,8,1,'N',flowctrl)== FALSE) {

fprintf(stderr, "Set Parity Error\n");

close(fd);

exit(1);

}

pid = fork();

if (pid < 0) {

fprintf(stderr, "Error in fork!\n");

} else if (pid == 0){

while(1) {

printf("SEND: %s\n",xmit);

write(fd, xmit, strlen(xmit));

sleep(1);

}

exit(0);

} else {

while(1) {

nread = read(fd, buff, sizeof(buff));

if (nread > 0) {

buff[nread] = '\0';

printf("RECV: %s\n", buff);

}

}

}

close(fd);

exit(0);

}

测试结果:

虚拟机下编译arm-linux-gcc serial.c –o serial

在超级终端下运行./serial

可以看到:

SEND:com test by ptr 2012

RECV:com test by ptr 2012
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: