查看: 5074|回复: 3

【SPI】SPI的配置和读取问题!

[复制链接]

11

主题

22

帖子

135

积分

中级工程师

Rank: 2

积分
135
发表于 2021-7-16 14:08:02 | 显示全部楼层 |阅读模式
如题,请问SPI应该怎么配置,用的是加速度LIS2DH12模块,SPI通信

读取芯片的ID寄存器,每次都是第二次才能读正确,第一次从来都是错误。而且发现NSS软件控制不管用,只有硬件控制

spiInitStruct.softControl = FL_DISABLE;     设置成这样,请问是否是芯片的SPI有问题,用STM32之前跑通无问题,是SPI读写还是配置初始化的问题?

代码如下:

SPI配置如下下:
void SpiInit(void)   //SPI初始化
{
    FL_GPIO_InitTypeDef gpioInitStruct = {0};
    FL_SPI_InitTypeDef spiInitStruct = {0};

    spiInitStruct.baudRate = FL_SPI_BAUDRATE_DIV16;       //波特率2分频
    spiInitStruct.bitOrder = FL_SPI_BIT_ORDER_MSB_FIRST; //先发送高位
    spiInitStruct.clockPhase = FL_SPI_PHASE_EDGE2;       //第二个时钟边沿是第一个捕捉边沿
    spiInitStruct.clockPolarity = FL_SPI_POLARITY_INVERT;//串行时钟停止在高电平
    spiInitStruct.dataWidth = FL_SPI_DATA_WIDTH_8B;      //通信长度16bit   
    spiInitStruct.mode = FL_SPI_WORK_MODE_MASTER;        //主机模式
    spiInitStruct.softControl = FL_DISABLE;               //ENABLE:SSN寄存器控制 DISABLE:SSN硬件自动控制
    spiInitStruct.transferMode = FL_SPI_TRANSFER_MODE_FULL_DUPLEX;  
    FL_SPI_Init(SPI1, &spiInitStruct);

//    FL_SPI_ClearTXBuff(SPI1);                            //清除SPI TX缓冲区
//    FL_SPI_ClearRXBuff(SPI1);                                                                                                                 //清除SPI RX缓冲区

    gpioInitStruct.pin = FL_GPIO_PIN_8 | FL_GPIO_PIN_9 | FL_GPIO_PIN_10 |
                         FL_GPIO_PIN_11;
    gpioInitStruct.mode = FL_GPIO_MODE_DIGITAL;
    gpioInitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
    gpioInitStruct.pull = FL_DISABLE;
    gpioInitStruct.remapPin = FL_DISABLE;

    FL_GPIO_Init(GPIOB, &gpioInitStruct);
               
}


读一个字节函数:
uint8_t SpiWriteAndRead(uint8_t data)   //向寄存器写的同时读取数据
{
    FL_SPI_SetSSNPin(SPI1, FL_SPI_SSN_LOW);                                   //CS片选(SPI使能)
    FL_SPI_WriteTXBuff(SPI1, 0x80|data);
                                       //发送数据
    while(!(FL_SPI_IsActiveFlag_TXBuffEmpty(SPI1)));
                FL_SPI_WriteTXBuff(SPI1, 0xFF);                                           //发送数据   
    while(!(FL_SPI_IsActiveFlag_TXBuffEmpty(SPI1)));
    while(!(FL_SPI_IsActiveFlag_RXBuffFull(SPI1)));   //获取SPI RX 缓冲区满标志

    data = FL_SPI_ReadRXBuff(SPI1);                   //读取SPI TX 缓冲区


    FL_SPI_SetSSNPin(SPI1, FL_SPI_SSN_HIGH);                                  //CS片选(SPI空闲)
    return data;
}


写一个字节函数

uint8_t SpiWrite(uint32_t addres,uint8_t data)   //向寄存器写的同时读取数据
{
    FL_SPI_SetSSNPin(SPI1, FL_SPI_SSN_LOW);                                   //CS片选(SPI使能)
   FL_SPI_WriteTXBuff(SPI1, 0x00|addres);   
   while(!(FL_SPI_IsActiveFlag_TXBuffEmpty(SPI1)));  //获取SPI TX 缓冲区空标志
                                       
    FL_SPI_WriteTXBuff(SPI1, data);                                           //发送数据   
    while(!(FL_SPI_IsActiveFlag_TXBuffEmpty(SPI1)));
        
        
    while(!(FL_SPI_IsActiveFlag_RXBuffFull(SPI1)));   //获取SPI RX 缓冲区满标志

    data = FL_SPI_ReadRXBuff(SPI1);                   //读取SPI TX 缓冲区

    FL_SPI_SetSSNPin(SPI1, FL_SPI_SSN_HIGH);                                  //CS片选(SPI空闲)
    return data;
}


回复

使用道具 举报

11

主题

22

帖子

135

积分

中级工程师

Rank: 2

积分
135
 楼主| 发表于 2021-7-19 09:20:02 | 显示全部楼层
用SPI2可以,SPI1不行,请问这是为何?
回复

使用道具 举报

154

主题

846

帖子

4624

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4624
发表于 2021-7-19 15:12:36 | 显示全部楼层
橘子洲头 发表于 2021-7-19 09:20
用SPI2可以,SPI1不行,请问这是为何?

理论上 spi2与spi1 是相同的。
软件控制ssn 我这边用例程肯定是可以的。例程也用的软件控制。
我觉得用示波器看波形,比较容易查,毕竟spi的协议时很死,就是 波形对,那就肯定对。仿真一步一步走,看各引脚的波形,是否符合要求
回复

使用道具 举报

11

主题

22

帖子

135

积分

中级工程师

Rank: 2

积分
135
 楼主| 发表于 2021-7-26 09:50:11 | 显示全部楼层
顾博文 发表于 2021-7-19 15:12
理论上 spi2与spi1 是相同的。
软件控制ssn 我这边用例程肯定是可以的。例程也用的软件控制。
我觉得用 ...

感谢,解决了,换了一个FM33LC023N的芯片可以了,买的开发板是FM33LC046的SPI1就是不行,SPI2相同的程序就可以,怀疑是开发板的SPI1有点问题硬件
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表