在i.MX RT1010上使用FlexIO模拟SPI
在i.MX RT上有一个非常神奇的外设——FlexIO,用它可以模拟各种各样的串并型外设接口,例如UART、I2C、SPI等简单协议,还可以实现比较复杂的I2S接口协议,甚至是LIN总线或摄像头的接口。我们将陆续推出一系列介绍FlexIO实现各种接口协议的介绍文章。
前几周发布了几篇:
在i.MX RT1010上使用FlexIO模拟UART
在i.MX RT1010上使用FlexIO模拟IrDA
使用FlexIO模块来产生PWM及PFM波
一、概述
本文介绍了如何使用i.MX RT系列芯片上的FlexIO模块,来模拟SPI总线的主机与从机应用。
FlexIO是i.MX RT系列MCU片内的一种外设,它是一个非常灵活并且可以随意配置的模块,可以模拟出类似于UART、I2C、I2S等常用通信接口。当然,也可以成功的模拟SPI总线。
本文基于i.MX RT1010平台创建了一个简单的例程,来演示如何使用FlexIO模块去模拟出SPI总线的主机与从机。
二、FlexIO简介
i.MX RT1010的FlexIO模块具有以下的一些特性:
多组32位的移位寄存器,具有发送、接收以及数据拟合等模式
具有双重缓存区的移位寄存器支持连续的数据传输
自动生成并插入起始位及停止位
中断,直接存储器存取或轮询的方式进行收发
独立于总线时钟频率的可编程波特率,支持停止模式下的异步操作
高度灵活的16位定时器,支持各种内部或外部触发器、复位、使能与失能方式
可编程的逻辑模式,通过集成外部数字逻辑功能芯片或结合引脚/移位器/定时器功能,以产生复杂的输出
支持当CPU进入失能各项系统控制功能模式下的可编程状态机,支持最多8个状态,8个输出和每个状态3个可选择的输入
下图为整个FlexIO模块的移位器定时器及引脚的结构图。
图1. FlexIO模块框图 i.MXRT系列MCU的FlexIO模块所包含的资源不尽相同,用户可根据FLEXIO_PARAM寄存器读取所用芯片FlexIO模块包含的移位器、定时器、引脚及触发器数量。
本例程中所使用的i.MX RT1010芯片中包含8个寄存器、8个定时器、32个引脚以及两个外部触发器。(由于芯片设计引脚的限制,RT1010的实际使用的FlexIO引脚只有27个)
三、利用FlexIO模拟SPI
本节主要介绍如何使用FlexIO模拟SPI总线的主机及从机,将会详细阐述FlexIO模块的相关配置项。
3.1. SPI主机配置
模拟SPI主机时,需要用到以下的一些FlexIO模块资源:
两个定时器:一个用于产生SPI_CS输出信号,另一个用于产生SPI_SCK信号输出,并且控制所使用的两个移位器的数据读取/写入/移位操作。
两个移位器:分别用作数据的发送与接收。
四个引脚:分别接到上面使用的定时器与移位器,用作SPI_CS、SPI_SCK、SPI_MOSI 和SPI_MISO引脚。
下图所示为FlexIO SPI主机的结构框图。
图2. FlexIO SPI主机结构框图 在本例中,用Timer 0生成SPI_SCK信号,并通过FlexIO_D26引脚输出;用Timer 1生成SPI_CS信号,并通过FlexIO_D0输出;Shifter 0连接到FlexIO_D21,在SPI_SCK信号的每个上升沿发出数据;Shifter 1连接到FlexIO_D22,在SPI_SCK的每个下降沿以接收数据。
下表所示为主机Timer 0的具体配置。
[1] bitCountPerChar是每个字的数据所包含的位数。
[2] baudrate_divider可以由FlexIO clock除以SPI总线的波特率得到。
Timer 0被配置为8-bit baud counter模式,这种模式下,16位长度的计数器以及比较寄存器(计数器记到0时会重新加载比较寄存器内的值)被分割成两个8位长度的计数器。其中,低8位的计数器用来配置波特率(移位器时钟),高8位的计数器用来配置传输中的字长。当低8位的计数器自减到0时,Timer的输出会翻转,然后低8位的计数器会重载比较寄存器中的值,此时高8位的计数器会自减1。
下表所示为主机Timer 1的配置。
Timer 1被配置为随着Timer 0的使能而使能。Timer 1为16-bit counter模式,而这种情况下的计数器及比较寄存器会设置为0xFFFF,在这种配置下,计数器从不进行比较,并且当Timer 1使能时一直会输出高电平。
下表所示为主机Shifter 0的配置表。
下表4所示为主机Shifter 1的配置表。
Shifter 0与Shifter 1分别作为SPI主机中的移位输出与输入,它们同时受到Timer 0即SPI_SCK信号的控制,根据SPI_SCK的输出进行移位。
3.2. SPI从机配置
模拟SPI从机时,需要用到以下的一些FlexIO模块资源:
一个定时器:用于控制所使用的两个移位器数据的读取/写入/移位操作。
两个移位器:分别用作数据的发送与接收。
四个引脚:用作连接SPI_CS、SPI_SCK、SPI_MOSI和SPI_MISO各信号的引脚。
下图所示为FlexIO SPI从机的结构框图。
图3. FlexIO SPI从机结构框图
在从机模式下,Timer 0连接到FlexIO_D26引脚,用作接收从SPI主机发出的SPI_SCK的时钟信号,依据此信号来进行计数,并控制两个移位器数据的移位。当SPI_CS信号已经使能时,移位器内的数据将会在SPI_SCK信号的每个边沿进行移位。
FlexIO_D0作为SPI_CS信号与SPI主机的SPI_CS输出相连,以作为Timer 0的触发源。
Shifter 0连接到FlexIO_D21作为从机的发射端,Shifter 1连接到FlexIO_D22引脚作为从机的接收端
下表所示为从机Timer 0的配置。
下表所示为从机Shifter 0的配置。
下表所示为从机Shifter 1的配置。
四、示例的运行
4.1. 示例平台
i.MX RT1010-EVK板如下图所示。用户也可使用i.MX RT系列MCU的其他EVK板经过少许更改后实现这个例程。
图4. i.MX RT1010-EVK开发板 在本例程中,FlexIO使用FlexIO_D21引脚作为数据的输出引脚,使用FlexIO_D22作为数据的输入引脚,使用FlexIO_D26引脚作为SPI_SCK信号引脚,FlexIO_D0作为SPI_CS信号引脚。
本例程需要使用到两块EVK板分别作为SPI的主机与从机,两块板子的连线如下所示:
4.2. 示例运行
读者可从NXP官网上下载附带的示例程序。找到名为flexio_spi_master和 flexio_spi_slave的两个IAR工程。将两工程分别下载到两块EVK开发板上,按照上述的方案接好主机与从机,运行两块板上的示例程序即可。
图5所示为示波器捕获的SPI的4根线上的波形。
图5. SPI信号波形 本示例中SPI主机发送0x96到SPI从机,与此同时将收到从机发送的0xA5。
图6所示为SPI主机与从机之间通信的数据:
图6. 控制台打印的收发数据
作者:Tim Wang@NXP 文章出处:恩智浦MCU加油站
|