I2C to UART(300px)

简介

Arduino、树莓派、micro:bit等主板往往只有1-2个UART串口,而且有一个串口会作为程序下载或调试用,如果项目中需要连接多个UART设备,主板将难以连接。对于Arduino主板,我们往往通过IO口虚拟串口,但是虚拟串口将会打乱其他程序的执行,例如时序有严格要求的红外接收模块、WS2818单总线RGB灯。而我们的I2C to dual UART module I2C转双串口模块很好地解决了这个问题,该模块将主板的I2C接口转换为两个串口,可以连接两个串口设备,如果不够,你还可以级联多个I2C转双串口模块。 I2C to dual UART module I2C最高速率为1Mbps,每个子串口具备收/发独立的256字节FIFO硬件缓存,串口的波特率,字长,校验格式可独立设置,最高提供2M bps的通信速率,支持4个I2C地址,一块主控上最多并联4个模块,一次最多扩展8个硬串口。

技术规格

DFR0627 I2C to UART尺寸图
  • 工作电压:3.3~5V
  • 工作电流:<3mA
  • 通信接口:Gravity-I2C 4Pin
  • I2C地址:传输协议规定,见使用教程
  • 扩展串口数量:2个
  • 尺寸:32.5mmx27mm
  • 安装孔尺寸:20mm
  • 工作温度:-40℃~85℃

引脚说明

丝印 功能描述
D I2C数据SDA
C I2C时钟SCL
- 电源负极
+ 电源正极
T 串口发送端
R 串口接受收端

拨码开关与地址的对应关系

I2C转双串口模块是一个非标准的I2C设备,它的地址不唯一。I2C地址有7位数据,运行I2C地址扫描程序时,只要高4位和模块的地址一样,就会应答,故在一个模块上,你会扫描出多个I2C地址,它们的高四位是一致的。模块地址配置如下表所示:

6 5 4 3 2 1 0
IA1 IA0 1 0 C1 C0 0/1

I2C转双串口

第6位:IA1的值对应I2C转双串口模块上拨码开关A1的值;
第5位:IA0的值对应I2C转双串口模块上拨码开关A0的值;

拨码开关与IA1和IA0的对应关系表

拨码开关A1 拨码开关A0 IA1 IA0
0 0 0 0
0 1 0 1
1 0 1 0
1 1 1 1

第4位:固定位,值为1;
第3位:固定位,值为0;
第2/1位:C1C0代表子串口通道号,如00代表UART1,01代表UART2;
第0位:代表操作的对象是模块的寄存器还是FIFO,0代表寄存器,1代表FIFO

Arduino使用教程

I2C转串口模块对象构

构造I2C转双串口对象时, 需要指定子串口号(UART1或UART2)以及IA1和IA0的值,构造函数如下所示:

DFRobot_IIC_Serial(TwoWire &wire = Wire, uint8_t subUartChannel = SUBUART_CHANNEL_1, uint8_t IA1 = 1, uint8_t IA0 = 1);

  • 如果要操作UART1,则需传递参数SUBUART_CHANNEL_1,如果要操作UART2,则需传递参数SUBUART_CHANNEL_2;

  • 如果模块的拨码开关状态为A1(1), A2(0), 需在形参IA1和IA0的位置分别传递参数1和0;

  • 例:I2C转双串口模块的拨码开关A1拨至1,A0拨至0

    • 构建对象,使用UART1,代码示例如下:

DFRobot_IIC_Serial iicSerial(Wire, SUBUART_CHANNEL_1, /*IA1=*/1, /*IA0=*/0);//构造对象UART1

    • 构建对象,使用UART2,代码示例如下:

DFRobot_IIC_Serial iicSerial(Wire, SUBUART_CHANNEL_2, /*IA1=*/1, /*IA0=*/0);//构造对象UART2

设置波特率

I2C转双串口扩展出的UART同其他硬串口一样,也涉及到了波特率的设置,如将UART1的波特率设置为9600,UART2设置为115200, 示例代码如下所示:

iicSerial1.begin(9600);   //UART1初始化,将波特率设置为9600
iicSerial2.begin(115200); //UART2初始化,将波特率设置为115200

I2C转双串口模块采用14.7456M晶振,它支持下表所示波特率:

序号 1 2 3 4 5 6 7 8
波特率 2400 4800 57600 7200 9600 14400 19200 28800
波特率 38400 76800 115200 153600 230400 460800 307200 921600

常见波特率支持表

用户可以将该模块配置为上表所示的波特率,也可以自定义波特率,比如设置为12800等。

warning_yellow.png

注:由于波特率与晶振有关,晶振不能支持所有的波特率,故用户自定义波特率需要用户自己测试,是否可行。

准备

关于如何安装库文件,点击链接

接线图

warning_yellow.png

注:在运行下例代码前,需检查模块的拨码开关是否都拨到“1”位置,如果不是需要将其拨至“1”位置,或在下例demo的构造函数中修改形参IA1和IA0位置处传入的值

样例代码1

写一个例程,要求实现UART1和UART2的自收自发功能。将UART1的T引脚和R引脚通过杜邦线连接,再将UART2的TX和RX相连,UART1发送"hello,Serial1",UART2发送"123",分别接收各自发出的数据,并打印。

    /*!
     * @file dataTxAndRx.ino
     * @brief Receive and transmit data via UART. Read the data sent by TX pin via pin RX.
     * @n Experiment phenomenon: connect the TX to RX in Sub UART1 and UART2. Read the data sent by Sub UART and print it out.
     *
     * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (https://www.dfrobot.com)
     * @licence     The MIT License (MIT)
     * @author [Arya](xue.peng@dfrobot.com)
     * @version  V1.0
     * @date  2019-07-28
     * @get from https://www.dfrobot.com
     * @url https://github.com/DFRobot/DFRobot_IIC_Serial
     */
    #include <DFRobot_IIC_Serial.h>
    /*DFRobot_IIC_Serial Constructor
     *Parameter&wire  Wire
     *Parameter subUartChannel sub UART channel, for selecting to operate UART1 or UART2
     *@n Available parameter:
         SUBUART_CHANNEL_1  SUBUART_CHANNEL_2
               UART1             UART2
     *Parameter IA1 corresponds with IA1 Level(0 or 1) of DIP switch on the module, and is used for configuring
     * @n the I2C address of the 6th bit value(default: 1).
     *Parameter IA0 corresponds with IA0 Level(0 or 1) of DIP switch on the module, and is used for configuring
     * @n I2C address of the 5th bit value(default: 1).
     * I2C address configuration:
     * 7   6   5   4   3   2   1   0
     * 0  IA1 IA0  1   0  C1  C0  0/1
     *@n I2C address only has 7 bits, while there are 8 bits for one byte, so the extra one bit will be filled as 0.
     *@n The 6th bit corresponds with IA1 Level of DIP switch, can be configured manually.
     *@n The 5th bit corresponds with IA0 Level of DIP switch, can be configured manually.
     *@n The 4th and 3rd bits are fixed, value 1 and 0 respectively
     *@n The values of the 2nd and 1st bits are the sub UART channels, 00 for sub UART 1, 01 for sub UART 2.
     *@n The 0 bit represents the operation object: 0 for register, 1 for FIFO cache.
     */
    DFRobot_IIC_Serial iicSerial1(Wire, /*subUartChannel =*/SUBUART_CHANNEL_1,/*IA1 = */1,/*IA0 = */1);//Construct UART1
    //DFRobot_IIC_Serial iicSerial1;//Default constructor, UART1, IA1 = 1, IA0 = 1
    DFRobot_IIC_Serial iicSerial2(Wire, /*subUartChannel =*/SUBUART_CHANNEL_2, /*IA1 = */1,/*IA0 = */1);//Construct UART2

    uint8_t flag = 0;//A flag bit, judge whether to print the prompt information of UART1 and UART2.
    //if it is 0, print "UART1 receive data: " or "UART2 receive data: "
    void setup() {
      Serial.begin(115200);
      /*begin Init function, set band rate according to the selected crystal frequency.
      begin(long unsigned baud) Call the function, set sub UART band rate.
      default setting->Band rate: baud, data format:IIC_SERIAL_8N1, 8 bits data, no check mode, 1 bit stop bit.
      begin(long unsigned baud, uint8_t format)Use the function to set band rate and data format:
      Parameter supported baud:2400, 4800, 57600, 7200, 9600, 14400, 19200, 28800, 38400,
                    76800, 115200, 153600, 230400, 460800, 307200, 921600
      Parameter available format:
      IIC_SERIAL_8N1  IIC_SERIAL_8N2  IIC_SERIAL_8Z1  IIC_SERIAL_8Z2  IIC_SERIAL_8O1
      IIC_SERIAL_8O2  IIC_SERIAL_8E1  IIC_SERIAL_8E2  IIC_SERIAL_8F1  IIC_SERIAL_8F2
      8 represents the number of data bit, N for no parity, Z for 0 parity, O for Odd parity, E for Even parity,
      F for 1 parity, 1 or 2 for the number of stop bit. Default IIC_SERIAL_8N1
      */
      iicSerial1.begin(/*baud = */115200);/*UART1 init*/
      //iicSerial1.begin(/*baud = */115200, /*format = */IIC_SERIAL_8N1);

      iicSerial2.begin(/*baud = */115200);/*UART2 init*/
      Serial.println("\n+--------------------------------------------+");
      Serial.println("|  Connected UART1's TX pin to RX pin.       |");//Connect pin TX and RX of UART1
      Serial.println("|  Connected UART2's TX pin to RX pin.       |");//Connect pin TX and RX of UART2
      Serial.println("|  UART1 send a String: \"hello, Serial1!\"    |");//UART1 transmit a string "hello, Serial1!"
      Serial.println("|  UART2 send a number: 123                  |");//UART2 transmit numbers 123
      Serial.println("+--------------------------------------------+");
      iicSerial1.println("hello, Serial1!");//UART1 transmit string:"hello, Serial1!"
      iicSerial2.write(123);//UART2 transmit:123
      Serial.println("Serial to print UART1 and UART2's receive data.");//print the data received by UART1 and UART2
    }

    void loop() {
      char c;
      if(iicSerial1.available()){/*available return the number of byte in UART1 receive buffer, none- return 0*/
        flag = 0;
        while(iicSerial1.available()){
          if(flag == 0){
            Serial.print("\nUART1 receive data: ");
            flag = 1;
          }
          c = iicSerial1.read();/*Read data of UART1 receive buffer */
          Serial.print(c);
        }
      }
      if(iicSerial2.available()){
        flag = 0;
        while(iicSerial2.available()){
          if(flag == 0){
            Serial.print("\nUART2 receive data: ");
            flag = 1;
          }
          Serial.print(iicSerial2.read());/*Read and print the data of Sub UART2 receive buffer*/
        }
      }
      delay(1000);
    }

结果

程序运行后,串口打印如下图所示:

DFR0627_UART1and2.png

样例代码2

通过UART2发送1个字符串"ABCDEFASFGHJUAAAEEB",接收并解析改字符串,要求将去掉该字符串中的字符"A",并将解析后的数据打印出来,示例代码如下所示:

/*!
 * @file cmdAnalysis.ino
 * @brief Analyze UART command, save and print (example: UART2, connect UART2's RX and TX together)
 * @n Transmit a random string via UART: "ABCDEFASFGHJUAAAEEB"
 * @n Receive the string, remove the char "A" of the string, and then print out the new string.
 *
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (https://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author [Arya](xue.peng@dfrobot.com)
 * @version  V1.0
 * @date  2019-07-28
 * @get from https://www.dfrobot.com
 * @url https://github.com/DFRobot/DFRobot_IIC_Serial
 */
#include <DFRobot_IIC_Serial.h>
/*DFRobot_IIC_Serial Constructor
 *Parameter &wire  Wire
 *Parameter subUartChannel sub UART channel, for selecting to operate UART1 or UART2
 *@n Available parameter:
     SUBUART_CHANNEL_1  SUBUART_CHANNEL_2
           UART1             UART2
 *Parameter IA1 corresponds with IA1 Level(0 or 1) of DIP switch on the module, and is used for configuring
 * @n the I2C address of the 6th bit value(default: 1).
 *Parameter IA0 corresponds with IA0 Level(0 or 1) of DIP switch on the module, and is used for configuring
 * @n I2C address of the 5th bit value(default: 1).
 * I2C address configuration:
 * 7   6   5   4   3   2   1   0
 * 0  IA1 IA0  1   0  C1  C0  0/1
 *@n I2C address only has 7 bits, while there are 8 bits for one byte, so the extra one bit will be filled as 0.
 *@n The 6th bit corresponds with IA1 Level of DIP switch, can be configured manually.
 *@n The 5th bit corresponds with IA0 Level of DIP switch, can be configured manually.
 *@n The 4th and 3rd bits are fixed, value 1 and 0 respectively
 *@n The values of the 2nd and 1st bits are the sub UART channels, 00 for sub UART 1, 01 for sub UART 2.
 *@n The 0 bit represents the operation object: 0 for register, 1 for FIFO cache.
 */
DFRobot_IIC_Serial iicSerial2(Wire, /*subUartChannel =*/SUBUART_CHANNEL_2, /*IA1 = */1,/*IA0 = */1);//Construct Sub UART2

char rx_buffer[256];//Define a receive buffer to store the data received by UART2
void setup() {
  Serial.begin(115200);
  /*begin Init function, set band rate according to the selected crystal frequency.
  begin(long unsigned baud) Call the function, set sub UART band rate.
  default setting->Band rate: baud, data format:IIC_SERIAL_8N1, 8 bits data, no check mode, 1 bit stop bit.
  begin(long unsigned baud, uint8_t format) Use the function to set band rate and data format:
  Parameter supported baud: 2400, 4800, 57600, 7200, 9600, 14400, 19200, 28800, 38400,
                76800, 115200, 153600, 230400, 460800, 307200, 921600
  Parameter available format:
  IIC_SERIAL_8N1  IIC_SERIAL_8N2  IIC_SERIAL_8Z1  IIC_SERIAL_8Z2  IIC_SERIAL_8O1
  IIC_SERIAL_8O2  IIC_SERIAL_8E1  IIC_SERIAL_8E2  IIC_SERIAL_8F1  IIC_SERIAL_8F2
  8 represents the number of data bit, N for no parity, Z for 0 parity, O for Odd parity, E for Even parity,
  F for 1 parity, 1 or 2 for the number of stop bit. Default IIC_SERIAL_8N1
  */
  iicSerial2.begin(/*baud = */115200);/*UART2 init*/
  //iicSerial2.begin(/*baud = */115200, /*format = */IIC_SERIAL_8N1);
  Serial.println("\n+-----------------------------------------------------+");
  Serial.println("|  connected UART2's TX pin to RX pin.                |");
  Serial.println("|  Analysis string and eliminate a char of a string.  |");
  Serial.println("|  Original string: ABCDEFASFGHJUAAAEEB               |");
  Serial.println("|  Eliminate char: A                                  |");
  Serial.println("|  Original string: BCDEFSFGHJUEEB                    |");
  Serial.println("|  Print the parsed string.                           |");
  Serial.println("+-----------------------------------------------------+");
  Serial.println("Please Send to the string by UART2's TX.");
  Serial.println("UART2 send a string: ABCDEFASFGHJUAAAEEB");
  iicSerial2.println("ABCDEFASFGHJUAAAEEB");//UART2 transmit string "ABCDEFASFGHJUAAAEEB"
}

void loop() {
  int n = iicSerial2.available();//Read the number of bytes in UART2
  int i = 0;
  if(n){
      while(iicSerial2.available()){
          if((char)iicSerial2.peek() != 'A'){//Use peek function to read the character without deleting the data in buffer.
              rx_buffer[i++] = iicSerial2.read();//Use read function to read character and delete the data in buffer.
              if((i > (sizeof(rx_buffer) - 1)))
                  break;
          }else{
              iicSerial2.read();//Put read function here to remove a char "A" in buffer.
          }
      }
      Serial.print("Parsed string: ");
      for(int j = 0; j < i; j++){
          Serial.print(rx_buffer[j]);
      }
      Serial.println();
  }
  delay(1000);
}

结果

程序运行后,显示效果如下图所示:

DFR0627_UART.png

树莓派使用教程

准备

接线图

  • 将模块与树莓派按照连线图相连。

安装驱动

  1. 启动树莓派的I2C接口。如已开启,可跳过该步骤。
    打开终端(Terminal),键入如下指令,并回车:
    pi@raspberrypi:~ $ sudo raspi-config
    然后用上下键选择“ 5 Interfacing Options ”, 按回车进入,选择 “ P5 I2C ”, 按回车确认“ YES ”即可。重启树莓派主控板。

  2. 安装Python依赖库与git,树莓派需要联网。如已安装,可跳过该步骤。
    在终端中,依次键入如下指令,并回车:
    pi@raspberrypi:~ $ sudo apt-get update
    pi@raspberrypi:~ $ sudo apt-get install build-essential python-dev python-smbus git

  3. 下载LIS系列驱动库。在终端中,依次键入如下指令,并回车:
    pi@raspberrypi:~ $ cd Desktop/
    pi@raspberrypi:~/Desktop $ git clone https://github.com/DFRobot/DFRobot_IICSerial

注意:

样例代码

样例代码1-UART1和UART2互发数据(demo_tx_and_rx.py)

将UART1的TX连接到UART2的RX,将UART1的RX连接到UART2的TX

  • 在终端中,键入如下指令并回车,运行样例代码:
    pi@raspberrypi:~/Desktop $ cd DFRobot_IICSerial/python/raspberrypi/examples/
    pi@raspberrypi:~/Desktop/DFRobot_IICSerial/python/raspberrypi/examples/ $ python demo_tx_and_rx.py

  • 结果

DFR0627_01

样例代码2-串口写数据(demo_write_serial.py)

将UART2的TX连接到USB转串口模块的RX,打开串口监视器

  • 在终端中,键入如下指令并回车,运行样例代码:
    pi@raspberrypi:~/Desktop $ cd DFRobot_IICSerial/python/raspberrypi/examples/
    pi@raspberrypi:~/Desktop/DFRobot_IICSerial/python/raspberrypi/examples/ $ python demo_write_serial.py

  • 结果

dfr0627_02

样例代码3-串口读数据(demo_read_serial.py)

将UART1的RX连接到USB转串口模块的TX引脚,通过串口监视器向树莓派发送数据

  • 在终端中,键入如下指令并回车,运行样例代码:
    pi@raspberrypi:~/Desktop $ cd DFRobot_IICSerial/python/raspberrypi/examples/
    pi@raspberrypi:~/Desktop/DFRobot_IICSerial/python/raspberrypi/examples/ $ python demo_read_serial.py

  • 结果

dfr0627_03

样例代码4-解析字符串(demo_cmd_analysis.py)

将UART2的TX和RX连接,解析并打印去掉A的字符串

  • 在终端中,键入如下指令并回车,运行样例代码:
    pi@raspberrypi:~/Desktop $ cd DFRobot_IICSerial/python/raspberrypi/examples/
    pi@raspberrypi:~/Desktop/DFRobot_IICSerial/python/raspberrypi/examples/ $ python demo_cmd_analysis.py

  • 结果

dfr0627_04

常见问题

Q:插线,电源,示例都准备好了,为什么还是没有工作呢?
A:先检查拨码开关是否都在位置‘1’处,若拨正后还不行则需要进行复位操作,将位置标有RST丝印处和负极连接,三秒后松开则可正常工作;或者断电重启程序也可。

更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。

更多

DFshopping_car1.png 购买链接