stm32操作fm25c64,读不到数据

hxuan   2009-5-23 19:22 楼主
spi初始化:
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI2, &SPI_InitStructure);
  /* Enable SPI2 */
  SPI_Cmd(SPI2, ENABLE);

断点监测寄存器DR的数据:
  SPI_I2S_SendData(SPI2, 0x06);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
DR的值为0xff。

百思不得其解,至少这里不应该出错啊。

回复评论 (13)

仿真

                                  
点赞  2009-5-23 19:30

读和写SPI_DR寄存器,实际操作的不是同一个寄存器

                                 写DR实际操作的是发送寄存器,而读DR实际操作的是接收寄存器。
点赞  2009-5-23 20:15

香主,这个我知道

现在的问题是:
SPI_I2S_SendData(SPI2, 0x06);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

发送寄存器DR不是0x06
点赞  2009-5-23 21:10

补充

执行这条语句:SPI_I2S_SendData(SPI2, 0x06);
应该是往发送寄存器DR写入0x06,可是在keil检测到是0x00
点赞  2009-5-23 21:14

没有办法可以读到SPI发送寄存器DR

                                 KEIL当然也不可能检测到。
点赞  2009-5-23 21:33

fm26c54操作代码

int fm25cx_writestatus(u8 status)
{
  //LCD_CS_HIGH();

  FM25CX_WP_HIGH();

  FM25CX_CS_LOW();
  SPI_I2S_SendData(SPI2, 0x06);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  FM25CX_CS_HIGH();

  FM25CX_CS_LOW();
  SPI_I2S_SendData(SPI2, 0x01);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI2, status);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  FM25CX_CS_HIGH();

  FM25CX_WP_LOW();

  return 1;
}

int fm25cx_readbyte(u16 addr, u16 *value)
{
  //LCD_CS_HIGH();

  FM25CX_CS_LOW();

  SPI_I2S_SendData(SPI2, 0x03);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI2, addr >> 8);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI2, addr & 0xff);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
  *value = SPI_I2S_ReceiveData(SPI2);

  FM25CX_CS_HIGH();

  return 1;
}

int fm25cx_writebyte(u16 addr, u8 value)
{
  //LCD_CS_HIGH();

  fm25cx_writestatus(0x00);  

  FM25CX_WP_HIGH();

  FM25CX_CS_LOW();
  SPI_I2S_SendData(SPI2, 0x06);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  FM25CX_CS_HIGH();

  FM25CX_CS_LOW();
  SPI_I2S_SendData(SPI2, 0x02);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI2, addr >> 8);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI2, addr & 0xff);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI2, value);
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  FM25CX_CS_HIGH();

  FM25CX_WP_LOW();

  fm25cx_writestatus(0x8c);

  return 1;
}
点赞  2009-5-23 22:45

续7楼

主程序执行下面的代码:
fm25cx_writebyte(0, 0xaa);
fm25cx_readbyte(0, &c);

断点监测c的值不是0xaa,而是0x00。
点赞  2009-5-23 22:46

9楼 low 

有做过stm32操作铁电的吗?

                                  
点赞  2009-5-24 08:48

我的刚刚做成功,给你原码看看

我刚刚做成功,我的源代码:

/*******************************************************************/
/*    文件名:user_fm25.c      */

/******************************************************************
输入:通过SPI发送的字节数据
输出:无
返回:通过SPI读取的字节数据
说明:通过SPI发送一个字节并返回接收的一个字节,该子程序与Read_FM25
    和Write_FM25配合使用
******************************************************************/
unsigned char SPI2_SendByte(unsigned char dt)
{
    /* 等待数据寄存器空 */
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

    /* 通过SPI2接口发送数据 */
    SPI_I2S_SendData(SPI2, dt);

    /* 等待接收到一个字节的数据 */
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

    /* 返回接收的数据 */
    return SPI_I2S_ReceiveData(SPI2);
}

/*****************************************************************
程序名:Read_FM25
输入: 地址
输出: 无
返回: 读取的数据
说明:从FM25指定的地址读取一个字节
*****************************************************************/
unsigned char Read_FM25(unsigned short addr)
{
    unsigned char i;

    /* 置FM25的CS为低电平 */
    GPIO_ResetBits(GPIOB, GPIO_Pin_12);

    /* 发送读命令 */
    SPI2_SendByte(0x03);

    /* 发送地址 */
    SPI2_SendByte((u8)addr/256);
    SPI2_SendByte((u8)addr);

    /* 发送一个哑书记并读取数据 */
    i=SPI2_SendByte(0x00);

    /* 置FM25的CS为高电平 */
    GPIO_SetBits(GPIOB, GPIO_Pin_12);

    return i;
}

/*****************************************************************
程序名:Write_FM25
输入: 地址,字节数据
输出: 无
返回: 无
说明:将一个字节写入W5100指定的地址
*****************************************************************/
void Write_FM25(unsigned short addr, unsigned char dat)
{
    /* 置FM25的CS为低电平 */
    GPIO_ResetBits(GPIOB, GPIO_Pin_12);

    /* 发送写使能命令 */
    SPI2_SendByte(0x06);
        GPIO_SetBits(GPIOB,GPIO_Pin_12);
        GPIO_ResetBits(GPIOB, GPIO_Pin_12);
    //发送写命令
        SPI2_SendByte(0x02);
    /* 发送地址 */
    SPI2_SendByte((u8)addr/256);
    SPI2_SendByte((u8)addr);

    /* 写入数据 */
    SPI2_SendByte(dat);

    /* 置FM25的CS为高电平 */
    GPIO_SetBits(GPIOB,GPIO_Pin_12);
}


点赞  2009-5-24 15:32

另外要记得将hold引脚接10k上拉

                                 如题
点赞  2009-5-24 15:33

谢谢楼上的兄弟

下午我也搞定了,做法差不多。
不过有个地方不明白:通过SPI发送的字节数据为什么每次还要读一下?
点赞  2009-5-24 23:17

SPI是有2个线,收发独立的

                                 读一下,相当于把时钟送出去,暂且这么理解吧
点赞  2009-5-24 23:19
MARK
点赞  2011-11-23 16:12
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复