Chinaunix首页 | 论坛 | 博客
  • 博客访问: 232972
  • 博文数量: 80
  • 博客积分: 1597
  • 博客等级: 上尉
  • 技术积分: 597
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-30 13:49
文章分类

全部博文(80)

文章存档

2017年(1)

2015年(1)

2014年(1)

2013年(10)

2012年(10)

2011年(27)

2010年(30)

分类:

2011-12-05 13:24:50

  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;   
}
 
阅读(1292) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~