打印
[其他芯片]

玩转开发板--CH341串口编程及测试

[复制链接]
11648|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wiba|  楼主 | 2021-7-7 14:52 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
开发环境:CentOS6.7(虚拟机)

交叉编译器:arm-linux-gcc  gcc version 4.4.6 (crosstool-NG 1.16.0)

开发板fl2440(内核版本-linux-3.0)

开发模块:SIM900 GPRS

串口编程:

    编写串口需要注意的点:

    1.串口为串行通信,全双工,异步通信,因此需要了解它的异步通信的速率;

    2.了解串口包含哪几种数据位,异步通信速率,校验位及停止位等;




使用特权

评论回复
沙发
wiba|  楼主 | 2021-7-7 14:53 | 只看该作者
简易串口set_comport.c:



/*********************************************************************************
*      Copyright:  (C) 2018 Lingyunstudio
*                  All rights reserved.
*
*       Filename:  set_comport.c
*    Description:  This file
*                 
*        Version:  1.0.0(04/28/2018)
*         Author:  guozhihao <810170156@qq.com>
*      ChangeLog:  1, Release initial version on "04/28/2018 01:04:27 AM"
*                 
********************************************************************************/
/* head of sturct termios */
#include <termios.h>
#include <unistd.h>

/* head of perror */
#include <stdio.h>
#include <errno.h>

/* head of bzero() */
#include <strings.h>

/********************************************************************************
*  Description:comport about ttyUSB0
*   Input Args:fd=open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NDELAY) nspeed nBits:8 nEvent:N nStop:1
*  Output Args:comport failure:return -1
* Return Value:
********************************************************************************/

int set_comport(int fd,int nSpeed,int nBits,char nEvent,int nStop)    //串口设置,第一个传递文件描述符,第二个是设置异步通信的速率,第三个设置数据位,第四个设置校验位,第五个设置停止位;
{
    struct termios newttyUSB0,oldttyUSB0;        //设置新旧结构体

    if(tcgetattr(fd,&oldttyUSB0) != 0)                //保存原先串口配置
    {
        perror("Setupserial 1");
        return -1;
    }

    bzero(&newttyUSB0,sizeof(newttyUSB0));    //将这个结构体中的内存区域的内容全清为0
    newttyUSB0.c_cflag|=(CLOCAL|CREAD);       //将c_cflag设置成开启串行接收模式,并且建立本地连接具体可参考下方的2.

    newttyUSB0.c_cflag &=~CSIZE;                   //设置数据位

    switch( nSpeed )                                          //波特率设置选项如2400,4800,9600,115200
    {
        case 2400:
            cfsetispeed(&newttyUSB0,B2400);    // 在设置波特率时需要在数字前加上’B’,如B9600,B15200
            cfsetospeed(&newttyUSB0,B2400);   //设置输出速率,上方的cfsetispeed则是设置输入速率
            break;

        case 4800:
            cfsetispeed(&newttyUSB0,B4800);
            cfsetospeed(&newttyUSB0,B4800);
            break;

        case 9600:
            cfsetispeed(&newttyUSB0,B9600);
            cfsetospeed(&newttyUSB0,B9600);
            break;

        case 115200:
            cfsetispeed(&newttyUSB0,B115200);
            cfsetospeed(&newttyUSB0,B115200);
            break;

        default:
            cfsetispeed(&newttyUSB0,B115200);
            cfsetospeed(&newttyUSB0,B115200);
            break;
    }

    switch( nBits )                                            //选择数据位,如:CS7,CS8
    {
        case 7:
            newttyUSB0.c_cflag |= CS7;               //7位数据位
            break;

        case 8:
            newttyUSB0.c_cflag |= CS8;               //8位数据位
            break;
    }

    switch( nEvent )                                        //设置校验位,如奇校验和偶校验
    {
        case '0':
            newttyUSB0.c_cflag |= PARENB;     //开启校验奇偶校验
            newttyUSB0.c_iflag |= (INPCK | ISTRIP);    //INPCK打开奇偶校验,ISTRIP去除字符的第八个
            newttyUSB0.c_cflag |= PARODD;   //启用奇校验,参数详细可参考下方2
            break;

        case 'E':
            newttyUSB0.c_cflag |= PARENB;    //开启校验奇偶校验
            newttyUSB0.c_iflag |= (INPCK | ISTRIP);    //INPCK打开奇偶校验,ISTRIP去除字符的第八个
            newttyUSB0.c_cflag &= ~PARODD;    //启用偶校验,参数详细可参考下方2
            break;


        case 'N':
            newttyUSB0.c_cflag &= ~PARENB;    //不启用奇偶校验
            break;

    }

    if( 1 == nStop )                                        //停止位诺为1,则清除CSTOPB
    {
        newttyUSB0.c_cflag &= ~CSTOPB;    //默认送一位停止位
    }
    else if ( 2 ==nStop )                                
    {
        newttyUSB0.c_cflag |= CSTOPB;        //CSTOPB表示送两位停止位
    }

    /* 设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时 */
    newttyUSB0.c_cc[VTIME] = 0;                //非规范模式读取时间时的超时时间
    newttyUSB0.c_cc[VMIN]  = 0;                //非规范模式读取时间时的最小字节数

    tcflush(fd,TCIFLUSH);                             //清空终端未完成的输入和输出请求及数据;TCIFLUSH表示清空

    /* 在完成配置后需要激活生效 */
    if( (tcsetattr(fd,TCSANOW,&newttyUSB0)) != 0 )    //TCSANOW不等数据传输完毕就立即改变属性
    {
        perror("comport set error");
        return -1;
    }

    return 0;

}


使用特权

评论回复
板凳
wiba|  楼主 | 2021-7-7 14:58 | 只看该作者
注:

    1.编写调用这个串口程序,需要调用open函数,并且设置参数模式为:

    O_NOCTTY:通知linux系统,这个程序不会成为这个端口的控制终端.

    O_NDELAY:通知linux系统不关心DCD信号线所处的状态(端口的另一端是否激活或者停止).

    然后恢复串口的状态为阻塞状态,用于等待串口数据的读入,用fcntl函数: fcntl(fd,F_SETFL,0); //F_SETFL:设置文件flag为0,即默认,即阻塞状态

    2.termios结构体包含以下成员:

struct termios
   {
    tcflag_t c_iflag; //input flags
    tcflag_t c_oflag; //output flags
    tcflag_t c_cflag; //control flags
    tcflag_t c_lflag; //local flags
    cc_t c_cc[NCCS]; //control characters
    };
    3.关于结构体c_cflag进一步说明:

    以及c_iflag举例说明:




使用特权

评论回复
地板
wiba|  楼主 | 2021-7-7 14:59 | 只看该作者
我们拿ch341串口来测试:

    测试串口:

    1.由于fl2440是用自己配置的最小系统,会出现u-boot的对于驱动usb串口存在时钟问题,如下图:




    修改后:




使用特权

评论回复
5
wiba|  楼主 | 2021-7-7 15:00 | 只看该作者

set_comport.c


/*********************************************************************************
*      Copyright:  (C) 2018 guozhihao
*                  All rights reserved.
*
*       Filename:  test.c
*    Description:  测试GPRS串口,并且发送AT命令,查看返回值
*                 
*        Version:  1.0.0(05/04/2018)
*         Author:  Guozhihao <810170156@qq.com>
*      ChangeLog:  1, Release initial version on "05/04/2018 10:55:47 PM"
*                 
********************************************************************************/
/* head of printf */
#include <stdio.h>

/* head of open() */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* head of memest */
#include <string.h>

int set_comport(int fd,int nSpeed,int nBits,char nEvent,int nStop);
/********************************************************************************
*  Description:测试串口
*   Input Args:NULL
*  Output Args:NULL
* Return Value:NULL
********************************************************************************/
int main (int argc, char **argv)
{
    int             comfd;
    char            send_buf[512],recv_buf[512];

    /* init the /dev/ttyUSB */
    comfd = open("/dev/ttyUSB0",O_RDWR|O_NOCTTY|O_NDELAY);
    set_comport(comfd,115200,8,'N',1);

    /* start to write "AT" command */
    memset(send_buf,0,sizeof(send_buf));
    strcpy(send_buf,"AT\r\n");
    write(comfd,send_buf,strlen(send_buf));
    sleep(1);

   /* start to read  result */
    memset(recv_buf,0,sizeof(recv_buf));
    read(comfd,recv_buf,sizeof(recv_buf));
    printf("%s\n",recv_buf);
    sleep(1);

    return 0;
} /* ----- End of main() ----- */


使用特权

评论回复
6
wiba|  楼主 | 2021-7-7 15:01 | 只看该作者
编写Makefile脚本


/*********************************************************************************
*      Copyright:  (C) 2018 guozhihao
*                  All rights reserved.
*
*       Filename:  Makefile
*    Description: 将串口程序和test.c一起静态编译,并且上传到windows
*                 
*        Version:  1.0.0(05/04/2018)
*         Author:  Guozhihao <810170156@qq.com>
*      ChangeLog:  1, Release initial version on "05/04/2018 10:55:47 PM"
*                 
********************************************************************************/
CROSS_TOOLS := /opt/xtools/arm920t/bin/arm-linux-
PWD := $(shell pwd)
FILE1:=/home/guozhihao/Desktop/fl2440/3rdparty/GPRS/bymyself/comport.c
FILE2:=/home/guozhihao/Desktop/fl2440/3rdparty/GPRS/bymyself/set_comport.c
LDFLAGS+=-I{PWD}

NAME:= comport

export CC=${CROSS_TOOLS}gcc

all: install


install:
        ${CC} ${FILE1} ${FILE2} -o ${NAME} --static
        echo " ATD file is creature,Over! ";
        sz      ${NAME}

clean:
        @rm -rf ${NAME}


使用特权

评论回复
7
wiba|  楼主 | 2021-7-7 15:01 | 只看该作者
在fl2440开发板上进行测试:

    1.先通过tftp -gr comport 192.168.92.99下载下来

    2.chmod a+x comport 给予权限

    3.运行./comport结果如下:(以上步骤可以编写一个shell脚本实现)



/GPRS >: ./c.sh
    comport              100% |*******************************|   567k  0:00:00 ETA
    AT

    OK


使用特权

评论回复
8
zhengshuai888| | 2021-7-10 13:57 | 只看该作者
这是要演示啥?

使用特权

评论回复
9
SoldierJazz| | 2021-10-6 22:46 | 只看该作者

看题主内容,是介绍linux系统如何使用USB转串口,以及介绍linux串口编程。

使用特权

评论回复
10
weifeng90| | 2021-10-7 09:39 | 只看该作者
不错,谢谢分享。

使用特权

评论回复
11
两只袜子| | 2021-10-11 10:27 | 只看该作者
好好学习天天向上

使用特权

评论回复
12
mutable| | 2021-11-2 17:24 | 只看该作者
这个是CH341``?

使用特权

评论回复
13
chenjun89| | 2021-11-2 19:31 | 只看该作者
可以,学习了,谢谢分享。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

3313

帖子

3

粉丝