STM32
直播中

河神大人

9年用户 1528经验值
擅长:电源/新能源
私信 关注
[问答]

用stm32的spi接口驱动MB85RS2MT,读不出任何数据是为什么?

现象:
STM32的spi接口驱动MB85RS2MT(此芯片兼容FM25H20),问题是用示波器能看到单片机有数据输出,但是我读不出任何数据,读出的都是0x00,不知道是什么原因,发帖求助。下面是我的代码,我会加注释的,方便大家查看。

系统时钟是72MHZ,芯片型号是STM32F103RE

#define FRAM_WREN_INST      0x06                //设置写使能
#define FRAM_WRDI_INST      0x04                //写禁止
#define FRAM_RDSR_INST      0x05                //读状态寄存器
#define FRAM_WRSR_INST      0x01                //写状态寄存器
#define FRAM_READ_INST      0x03                //读存储器数据
#define FRAM_WRITE_INST     0x02            //写存储器数据
#define FRAM_STATUS_REG     0x0                //
#define FRAM_INIT_STATE     0x09        //

//测试代码:
        SPI_write_FRAM('a',0x01); //向地址1写入字节'a'
        t = SPI_read_FRAM(0x01); //从地址1读出字节

结果: t永远是0,为什么啊?
      


void SPI_FRAM_Init(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_SPI1, ENABLE);        

        GPIO_InitStructure.GPIO_Pin = FRAM_CS;  //SPI CS
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
         GPIO_Init(GPIOA, &GPIO_InitStructure);
         GPIO_SetBits(GPIOA,FRAM_CS);

        GPIO_InitStructure.GPIO_Pin = FRAM_SCK | FRAM_MISO | FRAM_MOSI;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
         GPIO_SetBits(GPIOA,FRAM_SCK|FRAM_MISO|FRAM_MOSI);

        GPIO_InitStructure.GPIO_Pin = FRAM_HOLD|FRAM_WP;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
         GPIO_Init(GPIOC, &GPIO_InitStructure);
         GPIO_SetBits(GPIOC,FRAM_HOLD|FRAM_WP);
   
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //选择了串行时钟的稳态:时钟悬空高
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //数据捕获于第二个时钟沿
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;                //定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
        SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
        SPI_Cmd(SPI1, ENABLE); //使能SPI外设
    delay_us(500);
}

u8 SPIx_WriteByte(u8 TxData)
{
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
    SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
    SPI_I2S_ReceiveData(SPI1);
   
}

u8 SPIx_ReadByte(u8 TxData)
{
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
    SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
    return SPI_I2S_ReceiveData(SPI1);
}

void SPI_write_FRAM(u8 data,u16 address)//写入一个字节到特定地址空间
{
        u8 addr_tempH,addr_tempM,addr_tempL;
        addr_tempH = (u8)((address>>16)&0x000000ff);      //获取高8位地址
        addr_tempM = (u8)((address>>8)&0x000000ff);   //获取中8位地址
        addr_tempL = (u8)(address&0x000000ff);        //获取低8位地址
        FRAM_Reset_CS;
        SPIx_WriteByte(FRAM_WREN_INST);    //写使能
    FRAM_Set_CS;
    delay_us(100);

        FRAM_Reset_CS;
        SPIx_WriteByte(FRAM_WRITE_INST);   //写存储器寄存器操作码
        SPIx_WriteByte(addr_tempH);            //写入高八位地址,高6位忽略
        SPIx_WriteByte(addr_tempM);             //写入中八位地址
        SPIx_WriteByte(addr_tempL);            //
        SPIx_WriteByte(data);                  //写入数据
        FRAM_Set_CS;
}
        
u8 SPI_read_FRAM(u16 address)//读出特定地址空间的数据
{
        u8 dat,addr_tempH,addr_tempM,addr_tempL;
        addr_tempH = (u8)((address>>16)&0x000000ff);      //获取高8位地址
        addr_tempM = (u8)((address>>8)&0x000000ff);   //获取中8位地址
        addr_tempL = (u8)(address&0x000000ff);        //获取低8位地址
        FRAM_Reset_CS;
        SPIx_WriteByte(FRAM_READ_INST);      //读存储器寄存器操作码        
        SPIx_WriteByte(addr_tempH);
        SPIx_WriteByte(addr_tempM);             //写入中八位地址        
        SPIx_WriteByte(addr_tempL);
        dat=SPIx_ReadByte(0xa5);               //读取数据
        FRAM_Set_CS;
        return (dat);
}

回帖(1)

乐骞添

2024-3-20 17:14:55
您好!根据您的描述,读不出任何数据的问题可能有以下几个方面的原因:

1. 读取寄存器地址错误:在读取数据前,您需要先发送指令和寄存器地址。请确认您发送的指令和地址是正确的,并且按照芯片的要求进行发送。

2. SPI模式设置错误:请确认您的SPI模式设置正确。MB85RS2MT芯片支持多种SPI模式,例如CPOL=0 CPHA=0或CPOL=1 CPHA=1等。请根据MB85RS2MT的数据手册来确认您的SPI模式设置是否正确。

3. SPI时钟速度设置过高:请注意,MB85RS2MT芯片的SPI时钟速度必须小于或等于20MHz。请确认您的SPI时钟速度设置正确。

4. 片选信号控制错误:请确保在进行数据读取操作时,片选信号(Chip Select)已经正确拉低,使MB85RS2MT处于读取模式。

另外,请注意您的代码中“delay_us()”函数的实现,确保延时函数能够准确地提供正确的延时时间。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分