项目内容:SPI驱动CMT2300A,实现数据的接收和发送
驱动芯片MCU:HC32F005
一、GPIO模拟三线SPI
1、CMT2300A的SPI接口定义:
SCLK | SPI的时钟 | CSB | SPI访问寄存器的片选 | FCSB | SP访问FIFO的片选 | SDIO | SPI的数据输入和输出 |
2、MCU的GPIO口模拟3线SPI
使用MCU的SPI来驱动CMT2300A,使得CMT2300A完成数据的接收和发送;
MCU和CMT2300A之间的通讯是通过3线SPI接口进行的。
MCU的引脚配置原理图:
?(1)第一步:配置MCU的3线SPI
GpioInitStruct.enDrv = GpioDrvH; //端口驱动能力:GPIO高驱动能力
GpioInitStruct.enDir = GpioDirOut; //GPIO:输出
Gpio_Init(EVB_SPI_MOSI_PORT, EVB_SPI_MOSI_PIN, &GpioInitStruct);
Gpio_SetAfMode(EVB_SPI_MOSI_PORT, EVB_SPI_MOSI_PIN, GpioAf0); //SPI_SDIO 24
Gpio_Init(EVB_SPI_CS_PORT, EVB_SPI_CS_PIN,&GpioInitStruct);
Gpio_SetAfMode(EVB_SPI_CS_PORT, EVB_SPI_CS_PIN,GpioAf0); //SPI_CS 14
Gpio_Init(EVB_SPI_SCK_PORT, EVB_SPI_SCK_PIN,&GpioInitStruct);
Gpio_SetAfMode(EVB_SPI_SCK_PORT, EVB_SPI_SCK_PIN,GpioAf0); //SPI_SCK 15
Gpio_Init(GpioPort3, GpioPin3, &GpioInitStruct);
Gpio_SetAfMode(GpioPort3, GpioPin3, GpioAf0); //SPI_FCSB 33
?(2)第二步:实现SPI写寄存器的功能
? ? ? ? SPI写寄存器时序原理图如下:
?
??SPI写寄存器__实现的代码:
void cmt_spi3_write(u8 addr, u8 dat)
{
cmt_spi3_sdio_1();
cmt_spi3_sdio_out(); //MCU_sdio_P24 设置为输出
cmt_spi3_sclk_0(); //时钟拉低
cmt_spi3_sclk_0();
cmt_spi3_fcsb_1(); //FSCB拉高,写FIFO时才拉低
cmt_spi3_fcsb_1();
cmt_spi3_csb_0(); //寄存器片选拉低
/* > 延迟0.5 SCLK cycle才开始进入第一个数据 */
cmt_spi3_delay();
cmt_spi3_delay();
/* r/w = 0 写寄存器的标志*/
cmt_spi3_send(addr&0x7F); //发送寄存器地址
cmt_spi3_send(dat); //发送数据
cmt_spi3_sclk_0(); //写完数据之后时钟至少拉低0.5个周期延时,才能把CSB拉高
/* > 0.5 SCLK cycle */
cmt_spi3_delay();
cmt_spi3_delay();
cmt_spi3_csb_1();//寄存器片选拉高
cmt_spi3_sdio_1();
cmt_spi3_sdio_in(); //gpio_sdio发送输出状态完成后变成输入状态
cmt_spi3_fcsb_1(); //FIFO片选拉高
}
(3)实现SPI写FIFO的功能
????????FIFO用来在CMT2300_Rx中存储接收到的数据,在CMT2300_Tx中存储即将发送的数据,FIFO可以通过SPI接口读取。
SPI写FIFO的时序图:
MCU生成一组数组,p_buf[i]=i,length=128,
CMT2300_FIFO中写入即将发送的数据,然后2300进入GO_TX状态,把数据发送出去;
??SPI写FIFO__实现的代码:
//给FIFO中要写的数:p_buf[i] = [1,128],这组数由MCU生成
void cmt_spi3_write_fifo(const u8* p_buf, u16 len)
{
u16 i;
cmt_spi3_fcsb_1();
cmt_spi3_fcsb_1();
cmt_spi3_csb_1();
cmt_spi3_csb_1();
cmt_spi3_sclk_0();
cmt_spi3_sclk_0();
cmt_spi3_sdio_out(); //sdio_输出:MCU的数组g_txBuffer[i]写入到2300_FIFO中
for(i=0; i<len; i++) //Buffer的长度:128
{
cmt_spi3_fcsb_0(); //FIFO片选,FCSB低有效,且延时1个SCLK长度
/* > 1 SCLK cycle */
cmt_spi3_delay();
cmt_spi3_delay();//延时1个SCLK时钟周期后,才开始发数
cmt_spi3_send(p_buf[i]);//把p_buf[]中的数写入FIFO,再由2300发送出去
cmt_spi3_sclk_0();//拉低,延迟2s,才能再拉高
CMT2300A_DelayUs(3); /* > 2 us */
cmt_spi3_fcsb_1();//拉高,延迟4s才能再拉低
/* > 4 us */
CMT2300A_DelayUs(4);
}
cmt_spi3_sdio_in(); //写完数据,状态由输出变为输入
cmt_spi3_fcsb_1();
}
二、MCU自带的4线SPI
1、MCU的SPI接口定义
CMT2300A | MCU | gpio复用功能 | SCLK | gpio_p15 | 5 | CSB | gpio_p14 | 5 | FCSB | gpio_p33 | 0 | SPI_MOSI | gpio_p24 | 5 | SPI_MISO | gpio_p23 | 5 |
2、使用MCU的4线SPI驱动CMT2300A
(1) 配置MCU的GPIO端口,复用SPI接口功能:
GpioInitStruct.enDrv = GpioDrvH; //端口驱动能力:GPIO高驱动能力
GpioInitStruct.enDir = GpioDirOut; //GPIO:输出
Gpio_Init(EVB_SPI_MOSI_PORT, EVB_SPI_MOSI_PIN, &GpioInitStruct);
Gpio_SetAfMode(EVB_SPI_MOSI_PORT, EVB_SPI_MOSI_PIN, GpioAf5); //SPI_MOSI 24
Gpio_Init(EVB_SPI_CS_PORT, EVB_SPI_CS_PIN,&GpioInitStruct);
Gpio_SetAfMode(EVB_SPI_CS_PORT, EVB_SPI_CS_PIN,GpioAf5); //SPI_CS 14
Gpio_Init(EVB_SPI_SCK_PORT, EVB_SPI_SCK_PIN,&GpioInitStruct);
Gpio_SetAfMode(EVB_SPI_SCK_PORT, EVB_SPI_SCK_PIN,GpioAf5); //SPI_SCK 15
Gpio_Init(GpioPort3, GpioPin3, &GpioInitStruct);
Gpio_SetAfMode(GpioPort3, GpioPin3, GpioAf0); //SPI_FCSB 33
GpioInitStruct.enDir = GpioDirIn;
Gpio_Init(EVB_SPI_MISO_PORT, EVB_SPI_MISO_PIN,&GpioInitStruct);
Gpio_SetAfMode(EVB_SPI_MISO_PORT, EVB_SPI_MISO_PIN,GpioAf5); //SPI_MISO 23
(2)实现SPI读寄存器功能:
? ? ? ? SPI读寄存器的时序图如下:
? ????????SPI读寄存器的代码:
//SPI读寄存器:根据寄存器地址,获取数据
void cmt_spi3_read(u8 addr, u8* p_dat)
{
Spi_SetCS(M0P_SPI, FALSE); //SPI配置主发送的电平,低电平有效
cmt_spi3_send(addr|0x80); //SPI发送一个字节的数据,发送要读的寄存器的地址
*p_dat = cmt_spi3_recv(); //得到想要的数据,存取p_dat
Spi_SetCS(M0P_SPI, TRUE); //电平置高
}
(3)实现SPI读FIFO的功能
SPI读FIFO的时序图:
void cmt_spi3_read_fifo(u8* p_buf, u16 len)
{
u16 i;
for(i=0; i<len; i++)
{
Spi_SetFCS(FALSE); //SPI读FIFO片选有效
p_buf[i] = cmt_spi3_recv(); //把接收到的数保存到p_buf[]中
Spi_SetFCS(TRUE); //读完数据,片选置高
cmt_spi3_delay();
cmt_spi3_delay();
}
}
参考:
1.CMT2300A官方使用手册《CMT2300A-CN-Rev0.7》
2.CMT2300A官方例程《CMT2300A_Demo(STM32)V1.0.1》
|