首页 > 编程语言 >嵌入式串口应用编程

嵌入式串口应用编程

时间:2023-08-28 16:00:55浏览次数:48  
标签:case cflag cfg 编程 嵌入式 break 串口 new

1.串口概述

常见的数据通信的基本方式可分为并行通信与串行通信两种。

  • 并行通信是指利用多条数据传输线将一个字数据的各比特位同时传送。它的特点是传输速度快,适用于传输距离短且传输速度较高的通信。
  • 串行通信是指利用一条传输线将数据以比特位为单位顺序传送。特点是通信线路简单,利用简单的线缆就可实现通信,降低成本,适用于传输距离长且传输速度较慢的通信。

串口是计算机一种常用的接口,常用的串口有 RS-232-C 接口。它是于 1970 年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通信的标准,它的全称是“数据终端设备(DTE)和数据通信设备(DCE)之间串行二进制数据交换接口技术标准”。该标准规定采用一个 DB25 芯 引脚的连接器或 9 芯引脚的连接器
img

S3C2410X 内部具有两个独立的 UART 控制器,每个控 制器都可 以工作在 Interrupt(中断)模式或者 DMA(直接存储访 问)模式。 同时,每个 UART 均具有 16 字节的 FIFO(先入先出寄 存器),支持的最高波特率可达到 230.4Kbps。UART 的操作主要可分为以下几个部分:数据发送、数据接收、产生中断、设置波 特 率 、
Loopback 模式、红外模式以及硬软流控模式。串口参数的配置读者在配置超级终端和 minicom 时也已经接触过,一般包括波特率、起始位比特数、数据位比特数、停止位比特数和流控模式。在此,可以将其配置为波特率 115200、起始位 1b、数据位 8b、停止位 1b 和无流控模式。在 Linux 中,所有的设备文件一般都位于“/dev”下,其中串口 1 和串口 2 对应的设备名依次为“/dev/ttyS0”和“/dev/ttyS1”,而且 USB 转串口的设备名通常为“/dev/ttyUSB0”和“/dev/ttyUSB1”(因版本不同该设备名会有所不同),可以查看在“/dev”下的文件以确认。

串口设置

struct termios
  {
    tcflag_t c_iflag;		/* input mode flags */
    tcflag_t c_oflag;		/* output mode flags */
    tcflag_t c_cflag;		/* control mode flags */
    tcflag_t c_lflag;		/* local mode flags */
    cc_t c_line;			/* line discipline */
    cc_t c_cc[NCCS];		/* control characters */
    speed_t c_ispeed;		/* input speed */
    speed_t c_ospeed;		/* output speed */
#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
 };

终端有 3 种工作模式,分别为规范模式(canonical mode)、非规范模式(non-canonical mode)和原始模式(raw mode)。
通过在 termios 结构的 c_lflag 中设置 ICANNON 标志来定义终端是以规范模式(设置 ICANNON 标志)还是以非规范模式(清除ICANNON 标志)工作,默认情况为规范模式。

在规范模式下,所有的输入是基于行进行处理。在用户输入一个行结束符(回车符、EOF 等)之前,系统调用read()函数读不到用户输入的任何字符。除了 EOF 之外的行结束符(回车符等)与普通字符一样会被 read()函数读取到缓冲区之中。在规范模式中,行编辑是可行的,而且一次调用 read()函数最多只能读取一行数据。如果在 read()函数中被请求读取的数据字节数小于当前行可读取的字节数,则 read()函数只会读取被请求的字节数,剩下的字节下次再被读取。

在非规范模式下,所有的输入是即时有效的,不需要用户另外输入行结束符,而且不可进行行编辑。 在非规范模式下,对参数 MIN(c_cc[VMIN])TIME(c_cc[VTIME])的设置决定 read()函数的调用方式。设置可以有 4 种不同的情况。

  • MIN = 0 和 TIME = 0:read()函数立即返回。若有可读数据,则读取数据并返回被读取的字节数,否则读取失败并返回 0。
  • MIN > 0 和 TIME = 0:read()函数会被阻塞直到 MIN 个字节数据可被读取。
  • MIN = 0 和 TIME > 0:只要有数据可读或者经过 TIME 个十分之一秒的时间,read()函数则立即返回,返回值为被读取的字节数。如果超时并且未读到数据,则 read()函数返回 0。
  • MIN > 0 和 TIME > 0:当有 MIN 个字节可读或者两个输入字符之间的时间间隔超过 TIME 个十分之一秒时,read()函数才返回。因为在输入第一个字符之后系统才会启动定时器,所以在这种情况下,read()函数至少读取一个字节之后才返回。

按照严格意义来讲,原始模式是一种特殊的非规范模式。在原始模式下,所有的输入数据以字节为单位被处理。在这个模式下,终端是不可回显的,而且所有特定的终端输入/输出控制处理不可用。通过调用cfmakeraw()函数可以将终端设置为原始模式,而且该函数通过以下代码可以得到实现。

    termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    termios_p->c_oflag &= ~OPOST;
    termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    termios_p->c_cflag &= ~(CSIZE | PARENB);
    termios_p->c_cflag |= CS8;
int set_com_config(int fd, int baud_rate, int data_bits, char party, int stop_bits)
{
    struct termios new_cfg, old_cfg;
    int speed;
    // 1.保存并测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息
    if (tcgetattr(fd, &old_cfg) != 0)
    {
        perror("tcgetattr");
        return -1;
    }
    // 2.设置字符大小
    new_cfg = old_cfg;
    cfmakeraw(&new_cfg); // 配置为原始模式
    new_cfg.c_cflag &= ~CSIZE;

    // 3.设置波特率
    switch (baud_rate)
    {
    case 2400:
        speed = B2400;
        break;
    case 4800:
        speed = B4800;
        break;
    case 9600:
        speed = B9600;
        break;
    case 19200:
        speed = B19200;
        break;
    case 38400:
        speed = B38400;
        break;
    default:
    case 115200:
        speed = B115200;
        break;
    }
    cfsetispeed(&new_cfg, speed);
    cfgetospeed(&new_cfg, speed);

    // 4.设置停止位
    switch (data_bits)
    {
    case 7:
        new_cfg.c_cflag |= CS7;
        break;

    default:
    case 8:
    {
        new_cfg.c_cflag |= CS8;
    }
    break;
    }

    // 5.设置奇偶位校验
    switch (party)
    {
    default:
    case 'n':
    case 'N':
    {
        new_cfg.c_cflag &= ~PARENB;
        new_cfg.c_cflag &= ~INPCK;
    }
    break;
    case 'o':
    case 'O':
    {
        new_cfg.c_cflag |= (PARENB | PARODD);
        new_cfg.c_cflag |= INPCK;
    }
    break;
    case 'e':
    case 'E':
    {
        new_cfg.c_cflag |= PARENB;
        new_cfg.c_cflag &= ~PARODD;
    }
    break;
    case 's':
    case 'S':
    {
        new_cfg.c_cflag &= ~PARENB;
        new_cfg.c_cflag &= ~CSTOPB;
    }
    break;
    }

    // 6.设置停止位
    switch (stop_bits)
    {
    default:
    case 1:
    {
        new_cfg.c_cflag &= ~CSTOPB;
    }
    break;
    case 2:
    {
        new_cfg.c_cflag |= CSTOPB;
    }
    }
    // 7.设置等待时间和最小接受字符
    new_cfg.c_cc[VTIME] = 0;
    new_cfg.c_cc[VMIN] = 1;

    // 8.处理未接受字符
    tcflush(fd, TCIFLUSH);

    // 9.激活新配置
    if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0)
    {
        perror("tcsetattr");
        return -1;
    }
    return 0;
}

串口使用详解

在配置完串口的相关属性后,就可以对串口进行打开和读写操作了。它所使用的函数和普通文件的读写函数一样,都是 open()、write()和 read()。它们之间的区别的只是串口是一个终端设备,因此在选择函数的具体参数时会有一些区别。另外,这里会用到一些附加的函数,用于测试终端设备的连接情况等。下面将对其进行
具体讲解。

标签:case,cflag,cfg,编程,嵌入式,break,串口,new
From: https://www.cnblogs.com/cuifujian/p/17662524.html

相关文章

  • 封装Modbus串口通讯之SerialPort类
    前言C#为我们更好的与设备进行通讯,提供了SerialPort类于我们进行设备通讯,我们只需要将参数给与这个类并且实例化该类就可以通讯1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Data;4usingSystem.IO.Ports;5usingSystem.Linq;6usingSys......
  • Kubernetes编程—— 如何操作自定义资源
    如何操作自定义资源client-go为每种kubernetes内置资源提供对应的clientset和informer。那如果我们要监听和操作自定义资源对象,应该如何做呢?这里我们有两种方式:我理解意思是说:1、使用client-go提供的dynamicClient来操作自定义操作资源对象,当......
  • Windows编程:获取系统图标
    使用SHGetStockIconInfo函数可以获取系统定义的Shell图标的信息 SHGetStockIconInfo函数定义如下:1SHSTDAPISHGetStockIconInfo(2SHSTOCKICONIDsiid,3UINTuFlags,4[in,out]SHSTOCKICONINFO*psii5); SHSTOCKICONI......
  • Win11开发嵌入式Linux与交叉编译的一些轮子
    由于我不愿意直接使用ubuntu环境来开发Linux,所以在实践中我摸索出一套能够在最新的win11下调试Linux开发板的方法。wsl2准备首先我们需要安装wsl2。安装教程使用USBIP读写SD卡我们需要在linux环境下对开发板使用的TF卡进行读写。由于wsl2不支持直接挂载宿主机的usb设备,并且其......
  • 1-5可编程定时器/计数器 8253 实验
    EXTRNInitKeyDisplay:NEAR,Display8A:NEARIO8259_0EQU0250HIO8259_1EQU0251HCOM_ADDREQU0263HT2_ADDREQU0262H_STACKSEGMENTSTACKDW100DUP(?)_STACKENDS_DATASEGMENTWORDPUBLIC'DATA'BUFFERDB8DUP(?)CounterDB?ReDisplayFlagDB......
  • RS232串口专题
    启动串口调试助手项目运行截图基础类封装数据类型转换类usingSystem;usingSystem.Text;namespaceSerialPortHelperDemo{///<summary>///16进制使用的隔离符枚举///</summary>publicenumEnum16Hex{None,//无Blank,/......
  • 基于RS232的VGA图像显示(串口+ram)
    第40章、基于RS232的VGA图像显示(串口+ram)【实战】使用PC机通过UART串口传输图片像素数据(txt文件)给FPGA,FPGA将图片数据缓存到内部RAM中,再利用vga控制模块读取,在VGA显示器中心位置显示缓存到RAM中的图片。VGA显示模式为640x480@60;图片大小为100x100。基于RS232的VGA图......
  • 串口RS485
    第31章、串口RS485【理论】【RS485简介】1、RS-485是双向、半双工通信协议,允许多个驱动器和接收器挂接在总线上,其中每个驱动器都能够脱离总线。(RS232为双向,双工,单端传输)半双工:指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。2、RS-485采用差分传输方式能......
  • 串口RS232
    第30章、串口RS232UART,通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter),是一种通用的数据通信协议,也是异步串行通信口(串口)的总称,它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。它包括了RS232、RS499、RS......
  • 面试类-Java并发编程(三)
    39.CountDownLatch(倒计数器)了解吗?CountDownLatch,倒计数器,有两个常见的应用场景[18]:场景1:协调子线程结束动作:等待所有子线程运行结束CountDownLatch允许一个或多个线程等待其他线程完成操作。例如,我们很多人喜欢玩的王者荣耀,开黑的时候,得等所有人都上线之后,才能开打。   ......