串口编程_串口编程调试精灵 - CSDN
精华内容
参与话题
  • 串口编程(C语言)

    2020-07-30 23:33:28
    Linux下串口编程源代码(C语言) 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用。常用的串口是 RS-232-C 接口(又称 EIA RS-232-C)。
  • C——Linux下的串口编程

    万次阅读 多人点赞 2017-08-16 14:10:32
    之前在学习安信可A7模块时,是在PC上使用串口调试助手做了GPS的坐标数据信息的采集,同时分析了一些语句的含义。在这过程中,涉及到对嵌入式开发人员一个非常重要的知识:串口通信。在前篇也说到,我们将会自己写...

    之前在学习安信可A7模块时,是在PC上使用串口调试助手做了GPS的坐标数据信息的采集,同时分析了一些语句的含义。在这过程中,涉及到对嵌入式开发人员一个非常重要的知识:串口通信。在前篇也说到,我们将会自己写程序来对GPS数据进行解析,而这些数据正是靠串口来传输的。所以,本篇博文将进行关于串口通信的学习。

    一、串口接头

    首先我们得知道串口长什么样,常用的串口接头有两种,一种是9针串口(简称DB-9),一种是25针串口(简称DB-25)。每种接头都有公头和母头之分,其中带针状的接头是公头,而带孔状的接头是母头。
    以DB9为例,如图:
    这里写图片描述
    各个针脚功能说明:
    这里写图片描述
    在TXD和RXD数据线上:
      (1)逻辑1为-3~-15V的电压
      (2)逻辑0为3~15V的电压
    在RTS、CTS、DSR、DTR和DCD等控制线上:
      (1)信号有效(ON状态)为3~15V的电压
      (2)信号无效(OFF状态)为-3~-15V的电压
    这是由通信协议RS-232C规定的(请看后文)。

    注:一般我们需要的就是2,3,5接口,连接时是TXD接RXD,RXD接TXD,GND接GND。自己的TXD口接RXD口,自发自收,测试串口是否正常。

    二、串口通信基础知识

    OK,知道了串口的样子了,接下来就要更进一步,学习串口通信的基础知识了。

    1、什么是串口通信?

    串口通信(Serial Communication),是指外设和计算机间,通过数据信号线、地线等,按位进行传输数据的一种通讯方式。
    串口是一种接口标准,它规定了接口的电气标准,没有规定接口插件电缆以及使用的协议。

    2、串口通信协议

    在串口通信中,常用的协议包括RS-232、RS-422和RS-485。
    •RS-232:标准串口,最常用的一种串行通讯接口。有三种类型(A,B和C),它们分别采用不同的电压来表示on和off。最被广泛使用的是RS-232C,它将mark(on)比特的电压定义为-3V到-12V之间,而将space(off)的电压定义到+3V到+12V之间。传送距离最大为约15米,最高速率为20kb/s。RS-232是为点对点(即只用一对收、发设备)通讯而设计的,其驱动器负载为3~7kΩ。所以RS-232适合本地设备之间的通信。
    •RS-422:最大传输距离为1219米,最大传输速率为10Mb/s。其平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能达到最大传输距离。只有在很短的距离下才能获得最高速率传输。一般100米长的双绞线上所能获得的最大传输速率仅为1Mb/s。
    •RS-485:从RS-422基础上发展而来的,最大传输距离约为1219米,最大传输速率为10Mb/s。平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能使用规定最长的电缆长度。只有在很短的距离下才能获得最高速率传输。一般100米长双绞线最大传输速率仅为1Mb/s。

    3、同步通信?异步通信?

    同步通信:是一种比特同步通信技术,要求发收双方具有同频同相的同步时钟信号,只需在传送报文的最前面附加特定的同步字符,使发收双方建立同步,此后便在同步时钟的控制下逐位发送/接收。如:SPI总线。
    异步通信:指两个互不同步的设备通过计时机制或其他技术进行数据传输。也就是说,双方不需要共同的时钟。发送方可以随时传输数据,而接收方必须在信息到达时准备好接收。如:串口(UART)。
    接下来在后续的串口编程中讨论的都是异步通信,所以对同步通信不做过多的赘述了。
    这里提一下UART和USART,实际上,从字面意思即可理解:
    UART:universal asynchronous receiver and transmitter(通用异步收/发器)。
    USART:universal synchronous asynchronous receiver and transmitter(通用同步/异步收/发器)。
    USART在UART基础上增加了同步功能,即USART是UART的增强型。
    我常使用的S3C2440上就是支持的UART。

    3、通信方式

    •单工模式(Simplex Communication):单向的数据传输。通信双方中,一方为发送端,一方则为接收端。信息只能沿一个方向传输,使用一根传输线。双方是固定的。
    •半双工模式(Half Duplex):通信使用同一根传输线,既可以发送数据又可以接收数据,但不能同时进行发送和接收。数据传输允许数据在两个方向上传输,但是,在任何时刻只能由其中的一方发送数据,另一方接收数据。
    •全双工模式(Full Duplex)通信允许数据同时在两个方向上传输。因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。在全双工模式中,每一端都有发送器和接收器,有两条传输线,信息传输效率高。

    4、数据格式

    我们有必要先弄清楚异步通信的数据格式。
    这里写图片描述
    (1)起始位:起始位必须是持续一个比特时间的“0”,标志传输一个字符的开始。
    (2)数据位:数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定,一般可以是5位、7位或8位。传输数据时先传送字符的低位,后传送字符的高位。
    (3)奇偶校验位:奇偶校验位仅占一位,用于进行奇校验或偶校验,奇偶检验位不是必须有的。如果是奇校验,需要保证传输的数据总共有奇数个“1”;如果是偶校验,需要保证传输的数据总共有偶数个“1”。
      举例来说,假设传输的数据位为01001100,如果是奇校验,则奇校验位为0(要确保总共有奇数个1),如果是偶校验,则偶校验位为1(要确保总共有偶数个1)。
      由此可见,奇偶校验位仅是对数据进行简单的置逻辑高位或逻辑低位,不会对数据进行实质的判断,这样做的好处是接收设备能够知道一个位的状态,有可能判断是否有噪声干扰了通信以及传输的数据是否同步。
    (4)停止位:停止位可以是是1位、1.5位或2位,可以由软件设定。它一定是“1”,标志着传输一个字符的结束。
    (5)空闲位:空闲位是指从一个字符的停止位结束到下一个字符的起始位开始,表示线路处于空闲状态,必须由高电平来填充。

    好了,一些基础知识暂时先到这里,更深入的知识得自己自行了解了,接下来便是重头戏,在Linux下的串口编程了。

    ===========================================
    这里同时可以参考我之前的博文:STM8串口 (有相关经验的话)。对比一下两者的区别来进行学习。

    ===========================================

    1、首先是操作串口需要包含的头文件:

    #include <stdio.h>   /*标准输入输出的定义*/
    #include <errno.h>  /*错误号定义*/
    #include <sys/stat.h>
    #include <fcntl.h>  /*文件控制定义*/
    #include <termios.h>    /*PPSIX 终端控制定义*/
    #include <stdlib.h> /*标准函数库定义*/
    #include <sys/types.h>
    #include <unistd.h> /*UNIX 标准函数定义*/

    2、串口相关操作
    打开串口:
    我们都知道,在Linux下,除了网络设备,其余的都是文件的形式。串口设备也一样在/dev下。
    这里写图片描述
    所以我们可以通过open系统调用/函数来访问它。
    示例:fd = open("/dev/ttyUSB0",O_RDWR|O_NOCTTY|O_NDELAY);
    O_NOCTTY:可以告诉Linux这个程序不会成为这个端口上的“控制终端”.如果不这样做的话,所有的输入,比如键盘上过来的Ctrl+C中止信号等等,会影响到你的进程。
    O_NDELAY:标志则是告诉Linux,这个程序并不关心DCD信号线的状态——也就是不关心端口另一端是否已经连接。

    读写串口:
    与普通文件一样,使用read,write函数。
    示例:read(fd,buff,8);
    write(fd,buff,8);

    串口属性设置:
    最基本的设置串口包括波特率设置,效验位和停止位设置。这由通信双方协定。

    很多系统都支持POSIX终端(串口)接口.程序可以利用这个接口来改变终端的参数,比如,波特率,字符大小等等.要使用这个端口的话,你必须将<termios.h>头文件包含到你的程序中。这个头文件中定义了终端控制结构体和POSIX控制函数。

    最重要的就是这个结构体:

    struct termios
          {
          tcflag_t  c_iflag;  //输入选项
          tcflag_t  c_oflag;  //输出选项
          tcflag_t  c_cflag;  //控制选项
          tcflag_t  c_lflag;  //行选项
          cc_t      c_cc[NCCS]; //控制字符
          }; 

    其中我们更关注的是c_cflag控制选项。其中包含了波特率、数据位、校验位、停止位的设置。
    它可以支持很多常量名称其中设置数据传输率为相应的数据传输率前要加上“B”。
    c_cflag成员不能直接对其初始化,而要将其通过与、或操作使用其中的某些选项。
    设置串口属性主要是配置termios结构体中的各个变量,大致流程如下:

    1.使用函数tcgetattr保存原串口属性
    struct termios newtio,oldtio;
    tcgetattr(fd,&oldtio);

    2.通过位掩码的方式激活本地连接和接受使能选项:CLOCAL和CREAD
    newtio.c_cflag | = CLOCAL | CREAD;

    3.使用函数cfsetispeed和cfsetospeed设置数据传输率
    cfsetispeed(&newtio,B115200);
    cfsetospeed(&newtio,B115200);

    4.通过位掩码设置字符大小。
    newtio.c_cflag &= ~CSIZE;
    newtio.c_cflag |= CS8;

    5.设置奇偶效验位需要用到两个termios中的成员:c_cflag和c_iflag。首先要激活c_cflag中的校验位使能标志PARENB和是否进行奇偶效验,同时还要激活c_iflag中的奇偶效验使能。
    设置奇校验:
    newtio.c_cflag |= PARENB;
    newtio.c_cflag |= PARODD;
    newtio.c_iflag |= (INPCK | ISTRIP);
    设置偶校验:
    newtio.c_iflag |= (INPCK|ISTRIP);
    newtio.c_cflag |= PARENB;
    newtio.c_cflag |= ~PARODD;

    6.激活c_cflag中的CSTOPB设置停止位。若停止位为1,则清除CSTOPB;若停止位为0,则激活CSTOPB。
    newtio.c_cflag &= ~CSTOPB;

    7.设置最少字符和等待时间。在对接收字符和等待时间没有特别要求的情况下,可以将其设置为0。
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 0;

    8.调用函数”tcflush(fd,queue_selector)”来处理要写入引用的对象,queue_selector可能的取值有以下几种。
    TCIFLUSH:刷新收到的数据但是不读
    TCOFLUSH:刷新写入的数据但是不传送
    TCIOFLUSH:同时刷新收到的数据但是不读,并且刷新写入的数据但是不传送。

    9.激活配置。在完成配置后,需要激活配置使其生效。使用tcsetattr()函数。
    int tcsetattr(int filedes,int opt,const struct termios *termptr);

    最后贴出串口配置的完整代码:

    /*********************************************************************************
      *      Copyright:  (C) 2017 TangBin<tangbinmvp@gmail.com>
      *                  All rights reserved.
      *
      *       Filename:  s_uart1.c
      *    Description:  This file 
      *                 
      *        Version:  1.0.0(06/04/2017)
      *         Author:  TangBin <tangbinmvp@gmail.com>
      *      ChangeLog:  1, Release initial version on "06/04/2017 07:51:59 PM"
      *                 
      ********************************************************************************/
    #include <stdio.h>
    #include <errno.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <termios.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    
    int set_serial(int fd,int nSpeed,int nBits,char nEvent,int nStop)
    {
        struct termios newttys1,oldttys1;
    
         /*保存原有串口配置*/
         if(tcgetattr(fd,&oldttys1)!=0) 
         {
              perror("Setupserial 1");
              return -1;
         }
         bzero(&newttys1,sizeof(newttys1));
         newttys1.c_cflag|=(CLOCAL|CREAD ); /*CREAD 开启串行数据接收,CLOCAL并打开本地连接模式*/
    
         newttys1.c_cflag &=~CSIZE;/*设置数据位*/
         /*数据位选择*/   
         switch(nBits)
         {
             case 7:
                 newttys1.c_cflag |=CS7;
                 break;
             case 8:
                 newttys1.c_cflag |=CS8;
                 break;
         }
         /*设置奇偶校验位*/
         switch( nEvent )
         {
             case '0':  /*奇校验*/
                 newttys1.c_cflag |= PARENB;/*开启奇偶校验*/
                 newttys1.c_iflag |= (INPCK | ISTRIP);/*INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特  */
                 newttys1.c_cflag |= PARODD;/*启用奇校验(默认为偶校验)*/
                 break;
             case 'E':/*偶校验*/
                 newttys1.c_cflag |= PARENB; /*开启奇偶校验  */
                 newttys1.c_iflag |= ( INPCK | ISTRIP);/*打开输入奇偶校验并去除字符第八个比特*/
                 newttys1.c_cflag &= ~PARODD;/*启用偶校验*/
                 break;
             case 'N': /*无奇偶校验*/
                 newttys1.c_cflag &= ~PARENB;
                 break;
         }
         /*设置波特率*/
        switch( nSpeed )  
        {
            case 2400:
                cfsetispeed(&newttys1, B2400);
                cfsetospeed(&newttys1, B2400);
                break;
            case 4800:
                cfsetispeed(&newttys1, B4800);
                cfsetospeed(&newttys1, B4800);
                break;
            case 9600:
                cfsetispeed(&newttys1, B9600);
                cfsetospeed(&newttys1, B9600);
                break;
            case 115200:
                cfsetispeed(&newttys1, B115200);
                cfsetospeed(&newttys1, B115200);
                break;
            default:
                cfsetispeed(&newttys1, B9600);
                cfsetospeed(&newttys1, B9600);
                break;
        }
         /*设置停止位*/
        if( nStop == 1)/*设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB*/
        {
            newttys1.c_cflag &= ~CSTOPB;/*默认为一位停止位; */
        }
        else if( nStop == 2)
        {
            newttys1.c_cflag |= CSTOPB;/*CSTOPB表示送两位停止位*/
        }
    
        /*设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时*/
        newttys1.c_cc[VTIME] = 0;/*非规范模式读取时的超时时间;*/
        newttys1.c_cc[VMIN]  = 0; /*非规范模式读取时的最小字符数*/
        tcflush(fd ,TCIFLUSH);/*tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来 */
    
         /*激活配置使其生效*/
        if((tcsetattr( fd, TCSANOW,&newttys1))!=0)
        {
            perror("com set error");
            return -1;
        }
    
        return 0;
    }
    

    下一篇将具体结合GPS的数据解析,便能更好从整体上理解、学习了。

    展开全文
  • 一个串口编程实例

    千次阅读 2010-04-19 18:02:00
    添加串口事件消息处理函数OnComm()6.打开和设置串口参数7.发送数据 在众多网友的支持下,串口调试助手从2001年5月21日发布至今,短短一个月,在全国各地累计下载量近5000人次,在近200多个电子邮件中

    1.建立项目  

    2.在项目中插入MSComm控件

    3.利用ClassWizard定义CMSComm类控制变量

    4.在对话框中添加控件  

    5.添加串口事件消息处理函数OnComm()

    6.打开和设置串口参数

    7.发送数据

     

     

          在众多网友的支持下,串口调试助手从2001年5月21日发布至今,短短一个月,在全国各地累计下载量近5000人次,在近200多个电子邮件中,20多 人提供了使用测试意见,更有50多位朋友提出要串口调试助手的源代码,为了答谢谢朋友们的支持,公开推出我最初用VC控件MSComm编写串口通信程序的 源代码,并写出详细的编程过程,姑且叫串口调试助手源程序V1.0VC串口通讯源程序吧,我相信,如果你用VC编程,那么有了这个代码,就可以轻而易举地完成串口编程任务了。(也许本文过于详细,高手就不用看)

    开始吧:

    1.建立项目:打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest(与我源代码一致,等会你会方便一点);

    2.在项目中插入MSComm控件     选择Project菜单下Add To Project子菜单中的 Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。 选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX一项选上,重新安装VC6,选上ActiveX就可以了),

    这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构 clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标 是看不到的。

    3.利用ClassWizard定义CMSComm类控制对象    打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时你可以看一看,在对 话框头文件中自动加入了//{{AFX_INCLUDES()    #include "mscomm.h"    //}}AFX_INCLUDES (这时运行程序,如果有错,那就再从头开始)。

    4.在对话框中添加控件    向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为 IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为 IDC_BUTTON_MANUALSEND。别忘记了将接收编辑框的Properties->Styles中把Miltiline和 Vertical Scroll属性选上,发送编辑框若你想输入多行文字,也可选上Miltiline。

    再打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类, 为IDC_EDIT_RXDATA添加CString变量m_strRXData, 为IDC_EDIT_TXDATA添加CString变量m_strTXData。说明: m_strRXData和m_strTXData分别用来放入接收和发送的字符数据。

             休息一会吧?我们天天与电脑打交道,要注意保重,我现在在单杠上做引体向上可以来40次,可我都32了,佩服吗?。。。。。。好了,再接着来,下面是关键了:

    5.添加串口事件消息处理函数OnComm() 打开ClassWizard->Message Maps,选择类CSCommTestDlg,选择IDC_MSCOMM1,双击消息OnComm,将弹出的对话框中将函数名改为OnComm,(好记而已)OK。

    这个函数是用来处理串口消息事件的,如每当串口接收到数据,就会产生一个串口接收数据缓冲区中有字符的消息事件,我们刚才添加的函数就会执行,我们在OnComm()函数加入相应的处理代码就能实现自已想要的功能了。请你在函数中加入如下代码:

    void CSCommTestDlg::OnComm()
    {
          // TODO: Add your control notification handler code here
          VARIANT variant_inp;
          COleSafeArray safearray_inp;
          LONG len,k;
          BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
          CString strtemp;
          if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
          {               以下你可以根据自己的通信协议加入处理代码
              variant_inp=m_ctrlComm.GetInput(); //读缓冲区
              safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
              len=safearray_inp.GetOneDimSize(); //得到有效数据长度
              for(k=0;k<len;k++)
                  safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
              for(k=0;k<len;k++) //将数组转换为Cstring型变量
              {
                  BYTE bt=*(char*)(rxdata+k); //字符型
                  strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
                  m_strRXData+=strtemp; //加入接收编辑框对应字符串
              }
          }
          UpdateData(FALSE); //更新编辑框内容
    }

    到目前为止还不能在接收编辑框中看到数据,因为我们还没有打开串口,但运行程序不应该有任何错误,不然,你肯定哪儿没看仔细,因为我是打开VC6对照着做一步写一行的,运行试试。没错吧?那么做下一步:

    6.打开串口和设置串口参数    你可以在你需要的时候打开串口,例如在程序中做一个开始按钮,在该按钮的处理函数中打开串口。现在我们在主对话框的CSCommTestDlg::OnInitDialog()打开串口,加入如下代码:

    // TODO: Add extra initialization here
    if(m_ctrlComm.GetPortOpen())
    m_ctrlComm.SetPortOpen(FALSE);

    m_ctrlComm.SetCommPort(1); //选择com1
    if( !m_ctrlComm.GetPortOpen())
    m_ctrlComm.SetPortOpen(TRUE);//打开串口
    else
    AfxMessageBox("cannot open serial port");

    m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位

    m_ctrlComm.SetInputModel(1); //1:表示以二进制方式检取数据
    m_ctrlComm.SetRThreshold(1);
    //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
    m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0
    m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据

    现在你可以试试程序了,将串口线接好后(不会接?去看看我写的串口接线基本方法),打开串口调试助手,并将串口设在com2,选上自动发送,也可以等会手动发送。再执行你编写的程序,接收框里应该有数据显示了。

    7.发送数据    先为发送按钮添加一个单击消息即BN_CLICKED处理函数,打开ClassWizard->Message Maps,选择类CSCommTestDlg,选择IDC_BUTTON_MANUALSEND,双击BN_CLICKED添加 OnButtonManualsend()函数,并在函数中添加如下代码:

    void CSCommTestDlg::OnButtonManualsend()
    {
    // TODO: Add your control notification handler code here
    UpdateData(TRUE); //读取编辑框内容
    m_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送数据
    }

    运行程序,在发送编辑框中随意输入点什么,单击发送按钮,啊!看看,在另一端的串口调试助手(或别的调试工具)接收框里出现了什么。

    如果你真是初次涉猎串口编程,又一次成功,那该说声谢谢我了,因为我第一次做串口程序时可费劲了,那时网上的资料也不好找。开开玩笑,谢谢你的支持,有什么好东西别忘了给我寄一份。

    最后说明一下,由于用到VC控件,在没有安装VC的计算机上运行时要从VC中把mscomm32.ocx、msvcrt.dll、mfc42.dll拷到Windows目录下的System子目录中(win2000为System32)并再进行注册设置,请参考

    如何手工注册MSComm控件。

    龚建伟 2001.6.20


    什么是VARIANT数据类型?如何使用VARIANT数据类型? 怎么以十六进制或二进制发送和接收?

    如果还想再深入了解,请看:

    串口调试助手源程序及编程详细过程(二)2001.8.26

    1.建立项目  

    2.在项目中插入MSComm控件

    3.利用ClassWizard定义CMSComm类控制变量

    4.在对话框中添加控件  

    5.添加串口事件消息处理函数OnComm()

    6.打开和设置串口参数

    7.发送数据

    8.发送十六进制字符

    9.在接收框中以十六进制显示

    10.如何设置自动发送

    11.什么是VARIANT数据类型?如何使用VARIANT数据类型?

     

      

          这是串口调试助手源程序及编程详细过程(一)的续篇,首先谢谢朋友们的支持与鼓励。

      

    8.发送十六进制字符

          在主对话框中加入一个复选接钮,ID为IDC_CHECK_HEXSEND Caption: 十六进制发送,再利用ClassWizard为其添加控制变量:m_ctrlHexSend;

          在ClassView中为SCommTestDlg类添加以下两个PUBLIC成员函数,并输入相应代码;

     

    //由于这个转换函数的格式限制,在发送框中的十六制字符应该每两个字符之间插入一个空隔
    //如:A1 23 45 0B 00 29
    //CByteArray是一个动态字节数组,可参看MSDN帮助
    int CSCommTestDlg::String2Hex(CString str, CByteArray &senddata)
    {
    int hexdata,lowhexdata;
    int hexdatalen=0;
    int len=str.GetLength();
    senddata.SetSize(len/2);
    for(int i=0;i<len;)
    {
    char lstr,hstr=str[i];
    if(hstr==' ')
    {
    i++;
    continue;
    }
    i++;
    if(i>=len)
    break;
    lstr=str[i];
    hexdata=ConvertHexChar(hstr);
    lowhexdata=ConvertHexChar(lstr);
    if((hexdata==16)||(lowhexdata==16))
    break;
    else
    hexdata=hexdata*16+lowhexdata;
    i++;
    senddata[hexdatalen]=(char)hexdata;
    hexdatalen++;
    }
    senddata.SetSize(hexdatalen);
    return hexdatalen;
    }

    //这是一个将字符转换为相应的十六进制值的函数
    //好多C语言书上都可以找到
    //功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1
    char CSCommTestDlg::ConvertHexChar(char ch)
    {
    if((ch>='0')&&(ch<='9'))
    return ch-0x30;
    else if((ch>='A')&&(ch<='F'))
    return ch-'A'+10;
    else if((ch>='a')&&(ch<='f'))
    return ch-'a'+10;
    else return (-1);
    }

     

        再将CSCommTestDlg::OnButtonManualsend()修改成以下形式:

    void CSCommTestDlg::OnButtonManualsend()
    {
    // TODO: Add your control notification handler code here
    UpdateData(TRUE); //读取编辑框内容
    if(m_ctrlHexSend.GetCheck())
    {
    CByteArray hexdata;
    int len=String2Hex(m_strTXData,hexdata); //此处返回的len可以用于计算发送了多少个十六进制数
    m_ctrlComm.SetOutput(COleVariant(hexdata)); //发送十六进制数据
    }
    else
    m_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送ASCII字符数据

    }

    现在,你先将串口线接好 并打开串口调试助手V2.1,选上以十六制显示,设置好相应串口,然后运行我们这个程序,在发送框中输入00 01 02 03 A1 CC等十六进制字符,并选上以十六进制发送,单击手动发送,在串口调试助手的接收框中应该可以看到00 01 02 03 A1 CC了。

     

    9.在接收框中以十六进制显示

          这就容易多了:    在主对话框中加入一个复选接钮,IDC_CHECK_HEXDISPLAY Caption: 十六进制显示,再利用ClassWizard为其添加控制变量:m_ctrlHexDiaplay。 然后修改CSCommTestDlg::OnComm()函数:

    void CSCommTestDlg::OnComm()
    {
    // TODO: Add your control notification handler code here
    VARIANT variant_inp;
    COleSafeArray safearray_inp;
    LONG len,k;
    BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
    CString strtemp;
    if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
    {
    variant_inp=m_ctrlComm.GetInput(); //读缓冲区
    safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
    len=safearray_inp.GetOneDimSize(); //得到有效数据长度
    for(k=0;k<len;k++)
    safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
    for(k=0;k<len;k++) //将数组转换为Cstring型变量
    {
    BYTE bt=*(char*)(rxdata+k); //字符型
    if(m_ctrlHexDisplay.GetCheck())
    strtemp.Format("%02X ",bt); //将字符以十六进制方式送入临时变量strtemp存放,注意这里加入一个空隔
    else
    strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放

    m_strRXData+=strtemp; //加入接收编辑框对应字符串
    }
    }
    UpdateData(FALSE); //更新编辑框内容
    }

    测试:在串口调试助手发 送框中输入00 01 02 03 A1 CC等十六进制字符,并选上以十六进制发送,单击手动发送,在本程序运行后选上以十六进制显示,在串口调试助手中单击手动发送或自动发送,则在本程序的接 收框中应该可以看到00 01 02 03 A1 CC了。

     

    10.如何设置自动发送

           最简单的设定自动发送周期是用SetTimer()函数,这在数据采集中很有用,在控制中指令的传送也可能用到定时发送。

          方法是:在ClassWizard中选上MessageMap卡,然后在Objects IDs选中CSCommTestDlg类,再在Messages框中选上WM_TIMER消息,单击ADD_FUNCTION加入void CSCommTestDlg::OnTimer(UINT nIDEvent) 函数,这个函数是放入“时间到”后要处理的代码:

    void CSCommTestDlg::OnTimer(UINT nIDEvent)
    {
    // TODO: Add your message handler code here and/or call default
    OnButtonManualsend();
    CDialog::OnTimer(nIDEvent);
    }

    再在在主对话框中加入一 个复选接钮,ID为IDC_CHECK_AUTOSEND Caption: 自动发送(周期1秒),再利用ClassWizard为其添加BN_CLICK消息处理函数void CSCommTestDlg::OnCheckAutosend():

    void CSCommTestDlg::OnCheckAutosend()
    {
    // TODO: Add your control notification handler code here
    m_bAutoSend=!m_bAutoSend;
    if(m_bAutoSend)
    {
    SetTimer(1,1000,NULL);//时间为1000毫秒
    }
    else
    {
    KillTimer(1);    //取消定时
    }
    }

    其中:m_bAutoSend为BOOL型变量,在CLASSVIEW中为CSCommTestDlg类加入,并在构造函数中初始化:

            m_bAutoSen=FALSE;
    现在可以运行程序测试了。

     

    11.什么是VARIANT数据类型?如何使用VARIANT数据类型?

           不知如何使用VARIANT数据类型, 有不少朋友对VARIANT这个新的数据类型大感头疼。SetOutput()函数中 需要的VARIANT参数还可以使用COleVariant类的构造函数简单生成,现在GetInput()函数的返回值也成了VARIANT类型,那么 如何从返回的值中提取有用的内容。 VARIANT及由之而派生出的COleVariant类主要用于在OLE自动化中传递数据。实际上VARIANT也只不过是一个新定义的结构罢了,它的 主要成员包括一个联合体及一个变量。该联合体由各种类型的数据成员构成, 而该变量则用来指明联合体中目前起作用的数据类型。我们所关心的接收到的数据就存储在该联合体的某个数据成员中。 该联合体中包含的数据类型很多,从一些简单的变量到非常复杂的数组和指针。由于通过串口接收到的内容常常是一个字节串,我们将使用其中的某个数组或指针来 访问接收到的数据。这里推荐给大家的是指向一个SAFEARRAY(COleSafeArray)类型变量。新的数据类型SAFEARRAY正如其名字一 样,是一个“安全数组”,它能根据系统环境自动调整其16位或32 位的定义,并且不会被OLE改变(某些类型如BSTR在16位或32位应用程序间传递时会被OLE翻译从而破坏其中的二进制数据)。大家无须了解 SAFEARRAY的具体定义,只要知道它是另外一个结构,其中包含一个 (void *)类型的指针pvData,其指向的内存就是存放有用数据的地方。 简而言之,从GetInput()函数返回的VARIANT类型变量中,找出parray 指针,再从该指针指向的SAFEARRAY变量中找出pvData指针,就可以向访问数组一样取得所接收到的数据了。具体应用请参见void CSCommTestDlg::OnComm()函数。

          大概我现在也说不清这个问题,我自己从第一次接触这个东西,到现在还是给别人讲不清

    展开全文
  • C#串口编程基础入门

    千次阅读 2019-08-06 17:12:39
    最近在学习C#串口编程,对于串口编程是一个全新的领域,以前没有接触过,现在记录下自己学到的一些基础内容。 串口编程中需要用到一个非常重要的组件SerialPort,将此组件拖动到窗体之后,它是一个不可见组件,不会...

    最近在学习C#串口编程,对于串口编程是一个全新的领域,以前没有接触过,现在记录下自己学到的一些基础内容。

    串口编程中需要用到一个非常重要的组件SerialPort,将此组件拖动到窗体之后,它是一个不可见组件,不会像Button按钮等直接显示在窗体上,而是显示在窗体的下面,如下图所示:
    在这里插入图片描述
    将窗体按照如上图所示的进行设计好了之后(用到了ComboBox控件,需要有一定的C#基础),就可以进行编程了。
    首先把要发送的数据放在ComboBox里面,单击选择内容之后,就可以点击发送按钮进行数据发送了。
    可以使用System.IO.Ports.SerialPort.GetPortNames()方法查看自己电脑上可用的端口。可以用下面的代码将所有可用的端口都显示在comboBox2控件上

    comboBox2.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
    

    我刚开始在这个地方走了一些弯路,因为我发现我的电脑没有可用的端口,这意味着我无法进行端口调试,后来在网上发现可以用虚拟串口来生成自己想要的串口。我用的软件的下载地址是:https://dl.pconline.com.cn/download/825163.html ,大家也可以从网上找其它的软件。
    软件下载安装完成之后的打开页面如下图所示:
    在这里插入图片描述
    单击Add pair即可添加一对串口。
    程序运行效果如下图:
    在这里插入图片描述

    下面是程序的源代码,此程序只能打开并发送数据到指定端口,但还没有实现接收数据的功能。这里多说一下SerialPort组件,它的属性页如下图所示
    在这里插入图片描述
    它的大部分属性我们都可以使用默认值,但是有一个属性得根据自己实际情况进行修改,这个属性就是PortName,要把它的值修改为可用的端口号。

    using System;
    using System.Windows.Forms;
    
    namespace PC
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                string str;
                for (int i = 0; i < 256; i++)
                {
                    str = i.ToString("x").ToUpper();
                    if (str.Length == 1)
                    {
                        str += "0";
    
                    }
                    comboBox1.Items.Add("0x" + str);
    
                }
               // comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                comboBox1.Text = "0x00";
    
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                string data = comboBox1.Text;
                string convertdata = data.Substring(2, 2);
                byte[] buffer = new byte[1];
                buffer[0] = Convert.ToByte(convertdata, 16);
                //serialPort1.PortName = textBox1.Text;
                try
                {
                    serialPort1.Open();
                    serialPort1.Write(buffer,0,1);
                    serialPort1.Close();
                    MessageBox.Show("发送成功","提示");
                }
                catch
                {
                    if (serialPort1.IsOpen)
                    {
                        serialPort1.Close();
                        MessageBox.Show("端口打开成功");
                    }
                    MessageBox.Show("端口错误", "提示");
    
                }
            }
        }
    }
    
    

    完整项目下载地址:https://download.csdn.net/download/weixin_43074474/11475776

    展开全文
  • UART0串口编程系列(一)

    万次阅读 热门讨论 2013-07-14 14:23:36
    串口编程(UART0)---------------------------------------------------------Author :tiger-johnWebSite :blog.csdn.net/tigerjbEmail :jibo.tiger@gmail.comUpdate-Time : 2011年1月23日星期日Tiger声明:本人...

    串口编程(UART0)

    ---------------------------------------------------------

    Author             :tiger-john
    WebSite            :blog.csdn.net/tigerjb

    Email               jibo.tiger@gmail.com

    Update-Time   : 2011123日星期日

    Tiger声明:本人鄙视直接复制本人文章而不加出处的个人或团体,但不排斥别人转载tiger-john的文章,只是请您注明出处并和本人联系或留言给我3Q

    ---------------------------------------------------------

    本文章针对的是ARM2200环境下编写串口程序,其中设计轮循方式,中断方式,以及在UC/OS-II操作系统下的串口编程。

    使用轮循和中断两种方式来实现串口编程。

    (当然了,用中断实现串口编程,系统的效率较高。但是难度也较大 。轮循方式效率较低,但是编程比较简单)

    一.        串口编程的硬件原理

    1.     串口特性:

    1>16字节接收FIFO16字节发送FIFO

    2>接收FIFO触发点可设置为14814字节。

    3>内置波特率发生器。

    2.     UART0引脚:
    1>RxD0
    引脚用于UART0接受数据,接受方式为串行输入。

    2>TxD0引脚用于UART0发送数据,发送方式为串行发送数据。

    3.     UART0的结构和工作方式

    先看图在说明:

     

    1>  VPB总线提供CPUUART0之间得的通信连接

    (CPU内核通过VPB接口对UART0的寄存器进行读写访问.)

    2>  UART0 接收器模块监视串行输入线RxD0的有效输入。UART0 接收单元的移位寄存器(U0RSR)通过RxD0接收有效的字符。当U0RSR接受到一个有效字符时,它将该字符传送到UART0 接收单元缓冲寄存器FIFO中,等待CPU通过VPB接口进行访问。

    3>  UART0发送器模块接收CPU或主机写入的数据并将数据缓存到UART0 FIFOU0THR中,UART0发送模块中的移位寄存器(U0TSR)读取U0THRFIFO中的数据并将数据通过串行输出到引脚TxD0发送。

    4>  UART0的接收模块和发送模块的状态信息保存在U0LSR中。

    控制信息保存在U0LCR中。

    5>  UART0波特率发送器模块产生UART0 发送模块所使用的定时。波特率发生器模块时钟源为VPB时钟(pclk)。主时钟与U0DLLU0DLM寄存器所定义的除数相除得到UART0 发送器模块使用的时钟,该时钟必须为波特率的16倍。

    6>  中断接口包含寄存器U0IERU0IIR。中断接口接收UART0发送模块和接收模块发出的单时钟宽度的使能信号。

    4.     UART0ARM7 CPU之间的通信过程

    1>CPU通过UART0发送模块发送信息给外设

    l  CPU发出信息通过AHB总线到AHB-VPB

    l  通过AHB-VPB桥把信息转换后发送给VPB总线。

    l  UART0接收模块接受来自VPB总线的数据。并将数据缓存到U0THR寄存器中。

    l  UART0接受模块的移位寄存器U0TSR读取U0THR中的数据 并将数据通过输出引脚TxD0发送

    2>外设通过UART0接收模块向ARM7 CPU发送信息

    l  UART0移位寄存器(U0RSR)通过引脚RxD0接收有效字符。

    l  UART0接收到一个有效字符后,通过读取U0RBR寄存器可以将FIFO中最早接收到的字节读出,当FIFO中不再包含有效数据时,该寄存器反映接收到的最后一个有效字节数据。接收的数据不足8位时,高位用0填充。

    l  VPB总线将缓冲寄存器(U0RBR)中的数据通过AHB-VPB桥传到AHB总线上

    l  AHB总线将数据传送给ARM7 CPU

    二.          轮训方式的串口编程

    1.     串口程序都有那几部分组成

    看图:       

    1>  串口初速化

    A.    串口初始化的流程

    l  设置I/O引脚连接到UART0

    l  设置串口波特率

    l  设置串口工作模式

    B.     串口初始化需要设置的寄存器

    l  U0LCR(控制寄存器):设置UART0的通信格式。

    l  U0DLL,U0DLM(寄存器):设置UART0的通信波特率。

    C.     具体寄存器的设置

    (1) U0LCR(线控制寄存器)

    l  作用:设置通信格式(通信字符长度,停止位个数,奇偶校验位

    l  长度:8位寄存器

    l  各位寄存器的含义:

    [1 ,0]: 表示字长

    00:表示5位字长

    01:表示6位字符长度

    10:表示7位字符长度

    11:表示8位字符长度

    2: 表示停止位选择

             01个停止位

     12个停止位

    3位:表示奇偶使能

    0:禁止奇偶产生和校验

    1:使能奇偶产生和校验

    注:奇偶使能:控制是否进行奇偶校验。如果使能,发送时将添加一位校验位。

    [5 4]位:表示奇偶选择位

           00:奇数(数据位+校验位=奇数)

           01:偶数(数据位+校验位=偶数)

           10:校验位强制为1

           11:校验位强制为0

    注:奇偶选择主要是设置奇偶校验类型。

       6位:间隔控制

                      0:禁止间隔发送

                      1:使能间隔发送

    注:当该位为1时,输出引脚(TxD0)强制为逻辑0,可以引起通信对方产生间隔中断。在一些通信方式中,使用间隔中断作为通信的起始信号(eg:LIN Bus)      

       7位:除数锁存访问位

            0:禁止访问除数锁存寄存器

            1:始能访问除数锁存寄存器

    (2) U0DLL,U0DLM(除数锁存寄存器)

    l  作用:U0DLLU0DLM寄存器一起构成一个16位除数。

    l  U0DLLU0DLM都为8位寄存器。

    l  U0DLL:存放分频值的低8

    l  U0DLM:存放分频值的高8位。

    注:

    Ø  1.使用U0DLLU0DLM配置波特率之前,必须先计算分频值。

    Fdiv=Fpclk/(16*baud)

    Ø  2.使用U0DLLU0DLM配置波特率之前必须把U0LCR控制寄存器的第8位置为1才能进行配置。配置完后要把U0LCR控制寄存器的第8位置位0

    2>  串口初始化化程序

    A方法一:

    /**********************************************************

    * 作者:tiger-john

    * 时间:2011117

    * 名称:UART0_Init()

    * 功能:UART0初始化(通讯波特率1152008位数据位,1位停止

            位,无奇偶校验)

    * 入口参数:bps     串口波特率

    * 出口参数:无**********************************************************/

    void     UART0_Init(uint32 bps)

    {

     

        uint16  Fdiv;

        PINSEL0=0x00000005;  //设置串口引脚

        U0LCR=0x83;     //置为除数锁存位,进行配置

        Fdiv=(Fpclk>>4)/UART0_BPS;

        U0DLM=Fdiv>>8;

        U0DLL=Fdiv&0xff;

        U0LCR=0x03;         //清除除数锁存位,并设置工作模式

        }

    B.方法二:

    /**********************************************************

    * 作者:tiger-john

    * 时间:2011117

    *     称:UART0_Init()

    *     能:初始化串口0。设置其工作模式及波特率。

    * 入口参数:baud                波特率

    *          set          模式设置(UARTMODE数据结构)

    * 出口参数:返回值为1时表示初化成功,为0表除参数出错********************************************************/

    /* 定义串口模式设置数据结构 */

    typedef  struct  UartMode

    {   uint8 datab;           // 字长度,5/6/7/8

        uint8 stopb;           // 停止位,1/2

        uint8 parity;      // 奇偶校验位,0为无校验,1奇数校验,2为偶数校验

    }   UARTMODE;

    uint8  UART0_Init(uint32 baud, UARTMODE set)

    {   uint32  bak;

      

        /* 参数过滤 */

        if( (0==baud)||(baud>115200) )

        {

            return(0);

        }

        if( (set.datab<5)||(set.datab>8) )

        {

            return(0);

        }

        if( (0==set.stopb)||(set.stopb>2) )

        {

            return(0);

        }

        if( set.parity>4 )

        {

            return(0);

        }

     

        /* 设置串口波特率 */

        U0LCR = 0x80;                    // DLAB位置1

        bak = (Fpclk>>4)/baud;

        U0DLM = bak>>8;

        U0DLL = bak&0xff;

      

        /* 设置串口模式 */

        bak = set.datab-5;                // 设置字长度

        if(2==set.stopb)

        {

           bak |= 0x04;                      // 判断是否为2位停止位 

        }

        if(0!=set.parity)

        {

            set.parity = set.parity-1;

            bak |= 0x08;

        }

        bak |= set.parity<<4;           // 设置奇偶校验

        U0LCR = bak;

     

        return(1);

    }

    2.     串口接收数据

    用轮循方式接收数据

    1>CPU通过串口接收数据时各个寄存器之间的关系

     

     

    2>串口接受数据的流程:

    l  循环检测U0RBR是否有未读取的数据。

    l  如果有数据到来,则接收数据。

    3>相关寄存器配置

    (1) U0LSR(线状态寄存器)

    l  作用:只读寄存器,它提供UART0发送和接收模块的状态信息。

    l  长度:8位寄存器。

    l  各位寄存器的含义:

    A0位:表示接收数据就绪

    0表示U0RBR为空

    1表示U0RBR包含有效数据

    注:当U0RBR包含未读的字符时,第0位被置位;当UART0U0RBRFIFO为空时,第0位置零。

    B.1位:溢出错误。

    0:溢出错误状态未激活

    1:溢出错误状态激活

    注:溢出错误条件在错误发生后立即设置。U0LSR读操作将清零第1。当UART0RSR已经有新的字符就绪,而UART0  RBRFIFO已满时,第一位置1.此时的UART0 RBRFIFO不会被覆盖,UART0 RSR中的字符将丢失。

    C.2位:奇偶错误。

    0:奇偶错误状态未激活

    1:奇偶错误状态激活

    注:

    ²  当接收字符的奇偶位处于错误状态时产生一个奇偶错误。U0LSR读操作清零该位。

    ²  奇偶错误检测时间取决于U0FCRbit0奇偶错误与UART0 RBRFIFO中读出的字符相关。

    D.3位:帧错误

           0:帧错误状态未激活。

                     1:帧错误状态激活

                     注:

    ²  当接收字符的停止位为0,产生帧错误。对读操作U0LSR清零该位。

    ²  帧错误检测时间取决于U0FCRbit0.

    ²  帧错误与UART0RBRFIFO中读出的字符相关。当检测到一个帧错误时,Rx将尝试与数据重新同步并假设错误的停止位实际是一个超前的起始位。但即使没有出现帧错误,它也不能假设下一个接收到的字节是正确的。

    E.第四位:间隔中断

    0:间隔中断状态未激活

    1:间隔中断状态状态激活

    注:

    ²  在发送整个字符(起始位,数据,奇偶位和停止位)过程中RXD0如果都保持逻辑0,则产生间隔中断。

    ²  当检测到中断条件时,接收器立即进入空闲状态直到RXD0变为全1状态。

    ²  读操作U0LSR清零该状态位。

    ²  间隔检测的时间取决于U0FCRbit0.

    ²  间隔中断与UART0RBRFIFO中读出的字符相关。

    F.第五位:发送保持寄存器空

          0:表示U0THR包含有效数据

    1:表示U0THR

    注:

    ²  当检测到UART0 THR空时,THRE置位。

    ²  U0THR写操作清零该位。

    G.6位:表示发送器空

    0U0THR和或U0TSR包含有效数据。

    1U0THRU0TSR

    注:

    ²  U0THRU0TSR都为空时,该位置1

    ²  U0TSRU0THR包含有效数据时,该位清零。

    H7位:表示Rx FIFO 错误。

    0U0RBR中没有UART0 Rx错误,或U0FCRbit0.

    1U0RBR包含至少一个UART0 Rx错误。

    注:

    ²  当一个带有Rx错误(例如帧错误,奇偶错误或间隔中断)的字符装入U0RBR时,该位置1.

    ²  当读取U0LSR寄存器并且UART0FIFO中不再有错误时,该位置零。

    (2) U0RBR(接收器缓冲寄存器)

    l  作用:只读寄存器,是UART0 Rx FIFO的最高字节。它包含了最早接收到的字符,可通过总线接口读出。串口接收数据时低位在先,U0RBRbit0为最早接收到的数据位。如果接收到的数据小于8位,未使用的MSB填充为0.

    l  长度:8位寄存器。

    4>串口接收数据程序

    /**********************************************************

    *     者:tiger-john

    *     间:2011117

    *     称:            UART0_RcvByte

    *     能:            用查询方式接收一字节的数据

    * 入口参数:           

    * 出口参数:            data              要接收的数据

    **********************************************************/

    uint8     UART0_RcvByte(void)

    {

    uint8 rcv_data ;

    while((U0LSR&0X01)==0);         //等待数据到达

            rcv_data = U0RBR;       //U0RBR中读出接收到的数据

    return  rcv_data;               //返回接收到的数据

    }

     

    3.     串口发送数据

    1>  CPU通过串口发送数据时,各寄存器之间的关系

    2>  串口发送数据时的流程

    l  将要发送的一字节数据写入U0THR

    l  等待数据发送完毕

    3>  相关寄存器配置

    (1)U0THR(发送保持寄存器)

    l  最用:只写寄存器。U0THRUART0 Tx FIFO的最高字节。它包含了Tx FIFO 中最新的字符,可通过总线接口写入。串口发送数据时,低位在先,bit0代表最先发送的位。

    l  长度:8位寄存器

    (2)U0LSR(线状态寄存器)

    在上面已经介绍,在此步再涉及。

    4>  串口发送数据程序

    /**********************************************************

    *     者:tiger-john

    *     间:2011117

    *     称:            UART0_SendByte

    *     能:            向串口发送字节数据,并等待发送完毕。

    * 入口参数:            data              要发送的数据

    * 出口参数:           

    **********************************************************/

    void       UART0_SendByte(uint8 data)

    {

    U0THR = data;                

    while(0 == (U0LSR & 0x40));

     

    4.    完整的程序事例:

    用轮训方式实现接收上位机数据,并把数据再发送给上位机。

    展开全文
  • 串口编程--RS485

    万次阅读 多人点赞 2018-01-19 16:16:06
    最近被安排实现 linux rs485 串口通信。期间遇到各种问题,现在加以分析总结。 一、硬件相关  1.1 单工、半双工、全双工 首先,我使用的是芯片为 SP3485E 为半双工通信。那么先要明确什么是单工、半双工、...
  • 串口编程(VS2010)

    万次阅读 多人点赞 2018-04-27 02:51:56
    1.准别工作 高版本的VS没有MSComm通讯控件,... 解压后拷贝到: C:\Windows\System32(WIN7系统); C:\WINDOWS\system32(XP系统)。 注意:64位win7系统还需要将mscomm32.ocx文件复制到C:\Windows\SysWOW...
  • 串口编程1:基本概念介绍

    千次阅读 2019-09-26 22:15:54
    串口定义 串口分类 同步通信、异步通信 串行通讯 流控制 终端 串口定义: 串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。 串口分类: 按接口划分...
  • Linux串口编程

    千次阅读 2019-05-18 13:41:47
    一、串口通信介绍 串口是计算机上的串行通信的物理接口。首先先介绍一下串行通信,串行通信的分类: 1、按照数据传送方向,分为: 单工:数据传输只支持数据在一个方向上传输;就像路上的单行线。 半双工:允许...
  • windows中Python串口编程(一)

    万次阅读 2016-08-12 14:56:48
    在windows中,使用python进行串口编程需要安装一个Serial模块 pyserial: 下载地址:https://pypi.python.org/pypi/pyserial 下载完成后得到一个xxx.whl文件,下面进行安装 安装pyserial模块 pip install pyserial-...
  • 嵌入式Linux文件与串口编程

    千人学习 2018-10-22 21:38:03
    本课程介绍Linux环境下shell编程,普通文件与设备文件的编程方法,串口介绍与应用编程。 学习条件: 1.C语言编程基础 2.嵌入式Linux开发基础
  • 深入浅出Visual C++串口编程

    千次阅读 2006-04-04 22:25:00
  • ARM串口编程入门

    千次阅读 2012-10-29 16:50:29
    from :blog.csdn.net/tigerjb ...   Update-Time : 2011年1月30日星期日   ...-------------------------------------------------------------------------- ...众所周知嵌入式系统之间采用通信方式交换数
  • Android 串口编程

    千次下载 热门讨论 2020-07-30 23:30:46
    Android 串口编程,《Android 串口编程原理和实现方式》代码
  • 原文见链接Linux串口编程(中断方式和select方式)
  • VSPM使用方法

    千次阅读 2009-11-07 11:28:00
    对于C#串口编程,熟悉的应该觉得不困难。.NET下就更容易了。我们从两个方面向你介绍C#串口编程具体的步骤,那么我们第一要注意使用串口编程的软件是什么?并且要注意到它的安装及环境的配置,只有这些做得到位了,...
  • MFC 串口编程详细教程 图文并茂

    万次阅读 多人点赞 2013-08-14 21:42:14
    本人之前从未接触MFC编程,由于项目需要,所以上网查阅了相关资料,并实现了上位机串口通信...串口编程方法:32位控件 第一步:建工程 运行VC 6.0,文件-〉新建,选择MFC AppWizard(exe) ,工程名称:CommTest。确定
  • vc 串口编程示例

    千次下载 热门讨论 2020-07-30 23:33:29
    vc 使用MSCOMM32控件的串口通信编程实例 简单易懂
  • UART0串口编程系列之前奏篇

    万次阅读 2013-07-14 14:22:04
    串口编程之前奏篇------------------------------------------------------------------------Author :tiger-johnWebSite :blog.csdn.net/tigerjbEmail :jibo.tiger@gmail.comTiger声明:本人鄙视直接复制本人...
  • Delphi 串口通信技术资料

    千次阅读 热门讨论 2012-11-02 15:51:55
     资料2.Delphi串口通信源码(总共242个源码,大小:151MB)  资料3.Delphi串口通信技术文章(总共54篇文章,大小:4.76MB)  资料4.Delphi串口通信技术书籍(总共10本书籍,大小:142MB)  资料5.Delphi串口...
1 2 3 4 5 ... 20
收藏数 43,106
精华内容 17,242
关键字:

串口编程