注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

W_中原的博客笔记

通知:新博客日志将更新到个人站点:http://www.zhgyuan.cn/

 
 
 

日志

 
 

【笔记】VxWorks学习之串口编程  

2016-02-01 16:05:26|  分类: 嵌入式 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |


VxWorks 中,串口是一种特殊的字符型设备,它的驱动程序并不是直接挂在 I/O 系统中,而是通过在其上构建的 tty 驱动及其支持库 tyLib 接入。

VxworksI/O设备都是以文件存取的方式操作,这里以串口为例,”/tyCo/0”表示一个物理串口,”/tyCo/”是设备名(设备名称是 VxWorks系统规定的),表明此设备为串行设备,”0”是设备号。

 

打开一个串口设备:open(dev_addr, O_RDWR, 0) // 读写方式打开

传输设置波特率:ioctlserialFdFIOBAUDRATE9600 // 设置波特率9600

串口模式设置:ioctl(serialFd,SIO_HW_OPTS_SET,CS8); // 串口工作模式8 N 1

 

如:

ioctlserialFdSIO_HW_OPTS_SET CLOCAL| CREAD|CS8|STOPB|PARENB|PARODD
设置为没有流控制CLOCAL,使能读CREAD8位数据位,2位停止位,带校验位,奇校验 

STOPB:两位停止位,默认是1位停止位。PARENB使能校验,PARODD奇校验,使能后默认是偶校验,未使能则是无校验,CS5CS6CS7CS85678位数据位。

  如:CS8|PARENB 8位数据位,1位停止位,偶校验;

  CS8|PARENB|PARODD8位数据位,1位停止位,奇校验;

  CS88位数据位,1位停止位,无校验;

  CS8|STOPB8位数据位,2位停止位,无校验;

 

 

串口读写可以使用writeread函数。

int write

    (

    int    fd,                /* file descriptor on which to write */

    char * buffer,            /* buffer containing bytes to be written */

    size_t nbytes             /* number of bytes to write */

    )

 

read函数:

int read

    (

    int    fd,                /* file descriptor from which to read */

    char * buffer,            /* pointer to buffer to receive bytes */

    size_t maxbytes           /* max no. of bytes to read into buffer */

    )

 

下面使用VxWorks创建两个任务,一个向串口不断写入数据,另一个任务不断接受串口信息,并将收到的信息打印出来。这里接收使用到了select函数,当串口上没有数据时,任务二进入阻塞等待状态,一旦有数据或者超时函数才会返回。通常在串口编程中都会用select等待超时。

 

#include <vxWorks.h>

#include <ioLib.h>

#include <sioLib.h>

#include <taskLib.h>

#include <selectLib.h>

 

 

int serial_fd;

 

int sysRsInit(char *dev_addr, unsigned int baundrate)

{

    int serialFd;

   

    serialFd = open(dev_addr, O_RDWR, 0);

    if((serialFd < 0) || (serialFd == ERROR))

       printf("open seria error!\n");

   

    /*设置串口速率*/

    if(ioctl(serialFd, FIOBAUDRATE, baundrate)== ERROR)

    perror("ioctl 1");

 

    /*设置8个数据位一个停止位无校验*/

    ioctl(serialFd,SIO_HW_OPTS_SET,CS8);

   

    /*设置串口模式为 RAW 模式*/

    if(ioctl(serialFd, FIOSETOPTIONS, OPT_RAW)== ERROR)

    perror("ioctl 2");

    else

    printf("\n\rioctl set mode RAW\n\r");

 

    /*清空输入输出缓冲区*/

    ioctl(serialFd, FIOFLUSH, 0);

   

    return serialFd;

}

 

 

int sysRsDataRecv(int fd, unsigned char *pdata, unsigned int maxBytes,unsigned int timewait)

{

    int byte=0,rc=0;

    int ret;

    fd_set readFds;

    struct timeval timing;

 

    /*初始化超时时间*/

    timing.tv_sec = 0;

    timing.tv_usec = timewait * 1000;

 

    for(byte=0; byte<maxBytes; byte+=rc)

    {

       FD_ZERO(&readFds);

       FD_SET(fd, &readFds); /*添加fdselect*/

       ret = select(fd + 1, &readFds, 0, 0, &timing);

       if(ret == 0)

       {

           /*超时返回实际读到的个数*/

           return byte;

       }

       else if(ret > 0)

       {

           /*有数据可读*/

           if(FD_ISSET(fd, &readFds))

           {

              rc = read(fd, pdata + byte, maxBytes - byte);

              if(rc < 0 && errno != EINTR)

              {

                  break; /*读取出错*/

              }

           }

       }

      

    }

    return byte;

}

 

 

int UsrTask1( void )

{  

    int index = 0;

    char snd_buf[30] = {0};

   

    for(;;)

    {  

       sprintf(snd_buf, "Hello,World %d", index++);

       write(serial_fd, snd_buf, strlen(snd_buf));

      

       taskDelay(180);  

    } 

}

 

int UsrTask2( void )

{  

    int index;

    int bytes;

    char rev_buf[30] = {0};

   

    for(;;)

    {  

       memset(rev_buf, 0 , 30);

       bytes = sysRsDataRecv(serial_fd, rev_buf, 30, 1000);

       printf("recved %d bytes\n", bytes);

       for(index=0;index<bytes;index++)

       {

           printf("%c", rev_buf[index]);

       }

       printf("\n");

      

       taskDelay(60);

    } 

}

 

int UsrAppConfig( void )

{  

 

    serial_fd = sysRsInit("/tyCo/0",9600);

    printf("serial_fd: %d\n", serial_fd);

    taskSpawn( "task1",60, VX_FP_TASK, 0x1000, &UsrTask1, 0,0,0,0,0, 0,0,0,0,0 );

    taskSpawn( "task2",61, VX_FP_TASK, 0x1000, &UsrTask2, 0,0,0,0,0, 0,0,0,0,0 );

   

    return 0;

}

 

int usrEnter(void)

{  

    UsrAppConfig ();

    return 0;

}


串口自发自收测试可以正常收发数据:

【笔记】VxWorks学习之串口编程 - W_中原 - 汪中原的博客笔记

 

  评论这张
 
阅读(91)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017