XC2440开发板上已经含有S3C2440的3个串口驱动,我们只要知道各个串口的设备名称就可以了,
204 s3c2410_serial ,204是串口的主设备号。s3c2410_serial是设备名称,
在 dev目录下 ls 一下 就可以发现
ptyd0 s3c2410_serial0 ttysa
ptyd1 s3c2410_serial1 ttysb
ptyd2 s3c2410_serial2 ttysc
s3c2410_serial0,s3c2410_serial1,s3c2410_serial2 分别是串口1、2、3的设备名称
下面是测试源码,打开串口1、2,程序执行后,串口1的波特率变为9600,这时候你的串口
终端就没有反应了(串口1波特率默认115200),把终端软件串口1 波特率改为9600后,
连接终端,回车一下,然后输入几个‘1’后,画面如上图。
这时用telnet工具登陆开发板,执行ps 查看现有运行的程序,找到tty
[root@XC2440 /root]# ps
PID USER TIME COMMAND
1 root 0:04 init
2 root 0:00 [kthreadd]
3 root 0:00 [ksoftirqd/0]
5 root 0:00 [kworker/u:0]
6 root 0:00 [khelper]
7 root 0:00 [kworker/u:1]
10 root 0:00 [netns]
236 root 0:00 [sync_supers]
238 root 0:00 [bdi-default]
240 root 0:00 [kblockd]
249 root 0:00 [khubd]
252 root 0:00 [kseriod]
258 root 0:00 [kmmcd]
347 root 0:00 [rpciod]
349 root 0:00 [kworker/0:1]
355 root 0:00 [kswapd0]
356 root 0:00 [aio]
357 root 0:00 [nfsiod]
358 root 0:00 [crypto]
901 root 0:00 [mtdblock0]
906 root 0:00 [mtdblock1]
911 root 0:00 [mtdblock2]
916 root 0:00 [mtdblock3]
1028 root 0:00 [usbhid_resumer]
1049 root 0:00 [yaffs-bg-1]
1060 root 0:00 vsftpd /etc/vsftpd.conf
1065 root 0:00 -/bin/sh
1067 root 0:00 /usr/sbin/telnetd -l /bin/login
1070 root 0:18 /usr/local/qtopia/bin/qpe -qws
1071 root 0:00 boa
1072 root 0:00 [kworker/0:2]
1085 root 0:02 /usr/local/qtopia/bin/quicklauncher
1086 root 0:00 /usr/local/qtopia/bin/qss
1089 root 0:02 /usr/local/qtopia/bin/quicklauncher
1098 root 0:00 [flush-31:3]
1100 root 0:00 ./tty
1101 root 0:00 -ash
1104 root 0:00 ps
[root@XC2440 /root]# kill 1100
执行 kill 1100 后tty测试程序就被终止了,这时串口终端就可以用了,回车一下
Terminated
[@XC2440 pub]#
Please press Enter to activate this console.
Processing /etc/profile...
Done
[root@XC2440 /]#
[root@XC2440 /]#
测试代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "pthread.h"
//#include "serial_set.h"
/*******************************************************************
* 函数名称: set_opt
* 功能描述: 设置串口基本参数
* 输入参数: fd 打开的串口标识符 (通过open_port函数返回)
nSpeed 波特率 2400、4800、9600、115200
nBits 数据位 7、8
nEvent 奇偶校验 'O' 'N' 'E'
nStop 停止位 1、2
* 输出参数: 无
* 返 回 值: 0 设置成功
-1 设置过程出错
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* --------------------------------------------------------------------
* 2010/09/27 V1.0 *** 创建函数
***********************************************************************/
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
struct termios newtio,oldtio;
//保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息
if ( tcgetattr( fd,&oldtio) != 0)
{
perror("SetupSerial 1");
return -1;
}
//extern void bzero(void *s, int n); 置字节字符串s的前n个字节为零
bzero( &newtio, sizeof( newtio ) );
//设置字符大小
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
//设置数据位
switch( nBits )
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
}
//设置校验位
switch( nEvent )
{
case 'O':
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
case 'E':
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break;
case 'N':
newtio.c_cflag &= ~PARENB;
break;
}
//设置波特率
switch( nSpeed )
{
case 2400:
cfsetispeed(&newtio, B2400);
cfsetospeed(&newtio, B2400);
break;
case 4800:
cfsetispeed(&newtio, B4800);
cfsetospeed(&newtio, B4800);
break;
case 9600:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
case 115200:
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
break;
default:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
}
//设置停止位
if( nStop == 1 )
newtio.c_cflag &= ~CSTOPB;
else if ( nStop == 2 )
newtio.c_cflag |= CSTOPB;
//设置等待时间和最小接收字符
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
//处理未接收字符
tcflush(fd,TCIFLUSH);
//激活新配置
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
{
perror("com set error");//打印com set error及出错原因
return -1;
}
printf("set done!\n");
return 0;
}
/**********************************************************************
* 函数名称: open_port
* 功能描述: 打开指定串口
* 输入参数: fd 文件描述符
comport 串口号(1、2、3)
* 输出参数: 无
* 返 回 值: 出错 返回 -1
成功 返回 fd文件描述符
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* --------------------------------------------------------------------
* 2010/09/27 V1.0 *** 创建函数
***********************************************************************/
/*
static struct uart_driver s3c24xx_uart_drv = {
.owner = THIS_MODULE,
.dev_name = "s3c2410_serial",
.nr = CONFIG_SERIAL_SAMSUNG_UARTS,
.cons = S3C24XX_SERIAL_CONSOLE,
.driver_name = S3C24XX_SERIAL_NAME,
.major = S3C24XX_SERIAL_MAJOR,
.minor = S3C24XX_SERIAL_MINOR,
};*/
int open_port(int fd,int comport)
{
//char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};
long vdisable;//没用
//打开串口
if (comport==1)
{
//fd = open("/dev/ttySAC0",O_RDWR|O_NOCTTY|O_NDELAY);
fd = open("/dev/s3c2410_serial0",O_RDWR|O_NOCTTY|O_NDELAY);
if (-1 == fd)
{
perror("Can't Open s3c2410_serial0");
return(-1);
}
else
printf("open s3c2410_serial0 .....\n");
}
else if(comport==2)
{
fd = open("/dev/s3c2410_serial1",O_RDWR|O_NOCTTY|O_NDELAY);
if (-1 == fd)
{
perror("Can't Open s3c2410_serial1");
return(-1);
}
else
printf("open s3c2410_serial1 .....\n");
}
else if (comport==3)
{
fd = open("/dev/s3c2410_serial2",O_RDWR|O_NOCTTY|O_NDELAY);
if (-1 == fd)
{
perror("Can't Open s3c2410_serial2");
return(-1);
}
else
printf("open s3c2410_serial2 .....\n");
}
else if (comport==4)
{
fd = open("/dev/s3c2410_serial3",O_RDWR|O_NOCTTY|O_NDELAY);
if (-1 == fd)
{
perror("Can't Open s3c2410_serial3");
return(-1);
}
else
printf("open s3c2410_serial3 .....\n");
}
//恢复串口的状态为阻塞状态,用于等待串口数据的读入
if(fcntl(fd, F_SETFL, 0) < 0)
printf("fcntl failed!\n");
else
printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
//测试打开的文件描述符是否引用一个终端设备,以进一步确认串口是否正确打开
if(isatty(STDIN_FILENO)==0)
printf("standard input is not a terminal device\n");
else
printf("isatty success!\n");
printf("fd-open=%d\n",fd);
return fd;
}
unsigned int val=0;
int main(int argc, char **argv)
{
long ret=0;
int receNum=0,receFlag=0;
unsigned char ReceBuf[512],SendBuf[512];
int fd,fdd;
int nread,i;
unsigned char buff[512];
struct timeval timeout;
bzero(buff, 512);
if((fdd=open_port(fdd,2)) < 0)//打开串口 2
{
printf("open_port error2\n");
return -1;
}
if((i=set_opt(fdd,9600,8,'N',1)) < 0)//设置串口 9600 8 N 1
{
printf("set_opt error2\n");
return -1;
}
printf("fd=%d\n",fdd);
if((fd=open_port(fd,1)) < 0)//打开串口 1
{
printf("open_port error1\n");
return -1;
}
if((i=set_opt(fd,9600,8,'N',1)) < 0)//设置串口 9600 8 N 1
{
printf("set_opt error1\n");
return -1;
}
printf("fd=%d\n",fd);
timeout.tv_sec=1;//设置定时器
timeout.tv_usec=0;
while (1)
{
nread = read(fd,buff,256);//读串口数据 非阻塞
if(nread>0)
{
memcpy(&ReceBuf[receNum],buff,nread);
receFlag=2;
receNum +=nread; if(receNum>511)receNum=0;
printf("nread = %d\n",nread);
printf("%s\n",buff);
bzero(buff,nread);//清空
}
else
{
//printf("main\n");
if(receFlag>1)receFlag--;
if(receFlag==1)
{
write(fd,ReceBuf,receNum);//写数据
receNum=0;
receFlag=0;
}
timeout.tv_sec=0;
timeout.tv_usec=20000;//设置时间 20MS 读取一下串口数据
ret=select(0,NULL,NULL,NULL,&timeout);
}
}
close(fdd);
close(fd);
return 0;
}
阅读(13126) | 评论(0) | 转发(2) |