一. SPI 实验
SPI实验:学习如何使用 I.MX6U 的 SPI 接口来驱动 ICM-20608,读取 ICM-20608 的六轴数据。
本文学习 SPI主控芯片的代码编写。其中,包括SPI工作模式设置,主从模式设置,时钟配置等实现。
二. SPI 主控芯片代码
本实验的工程代码是在 "I2C实验" 的工程代码基础上继续实现的SPI的。将"I2C实验"工程代码拷贝一份。更名为 "18_spi"。
在 工程目录中的 bsp 文件夹下创建名为 "spi" 文件。在 /bsp/spi 目录中,新建 bsp_spi.h 和 bsp_spi.c 这两个文件。
1. 设置 SPI根时钟源
在 bsp/clk 目录的时钟代码中,即 /bsp/clk/ 目录下的 bsp_clk.c 文件添加 SPI根时钟配置代码。
SPI 的时钟树如下:
通过时钟树,可以知道 :
SPI 选择的是 PLL3_SW_CLK时钟,经过了 8分频,再经过一个1分频。最后得到 ECSPI_CLK_ROOT时钟,供 SPI外设使用。
bsp_clk.c 文件中的 imx6u_clkinit( ) 函数(即初始化系统时钟接口)中,添加如下 SPI根时钟代码:
/* 设置SPI的根时钟源*/
CCM->CSCDR2 &= ~(1 << 18); //选择pll3_sw_clk/8= 480/8 = 60MHz
CCM->CSCDR2 &= ~(0x3F << 19); //设置为1分频
2. SPI主控代码
SPI 通信中,片选信号可以有两种选择。可以选择硬件片选或软件片选。本实验使用软件片选。
bsp_spi.h 代码如下:
#ifndef _BSP_SPI_H_
#define _BSP_SPI_H_
#include "imx6ull.h"
void spi_init(ECSPI_Type* base);
unsigned char spich0_readwrite_byte(ECSPI_Type *base, unsigned char txdata);
#endif
bsp_spi.c 代码如下:
#include "bsp_spi.h"
/*SPI初始化*/
void spi_init(ECSPI_Type* base)
{
base->CONREG = 0; //清零
//设置开始模式,主模式,片选通道,数据长度
base->CONREG |= (1 << 3) | (1 << 4) | (7 << 20);
//设置工作模式,SPI数据线状态,片选信号有效位,SPI时钟线空闲状态
base->CONFIGREG = 0;
//设置采样周期,设置为0X2000
base->PERIODREG = 0x2000;
/* 设置时钟分频 */
//由于从设备ICM20608最大支持 8MHz,这里就设置为 6MHz
//即设置为10分频,60MHz/10 = 6MHz
// base->CONREG &= ~((0xF << 12) | (0xF << 8));
base->CONREG |= (9 << 12);
/* 选择通道0 */
base->CONREG &= ~(3 << 18);
base->CONREG |= (1 << 0); //使能SPI
}
/*SPI通道0发送/接收一个字节的数据 */
unsigned char spich0_readwrite_byte(ECSPI_Type *base, unsigned char txdata)
{
uint32_t spirxdata = 0;
uint32_t spitxdata = txdata;
while((base->STATREG & (1 << 0)) == 0); /* 等待发送FIFO为空 */
base->TXDATA = spitxdata;
while((base->STATREG & (1 << 3)) == 0); /* 等待接收FIFO有数据 */
spirxdata = base->RXDATA;
return spirxdata;
}
本文学习 SPI实验中,SPI主控芯片代码。下一篇继续学习 SPI实验部分:从设备 ICM20608涉及的SPI通信代码。