打印

stm32操作fm25c64,读不到数据

[复制链接]
4055|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
big5|  楼主 | 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。

百思不得其解,至少这里不应该出错啊。
沙发
big5|  楼主 | 2009-5-23 19:30 | 只看该作者

仿真

使用特权

评论回复
板凳
香水城| | 2009-5-23 20:15 | 只看该作者

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

写DR实际操作的是发送寄存器,而读DR实际操作的是接收寄存器。

使用特权

评论回复
地板
big5|  楼主 | 2009-5-23 21:10 | 只看该作者

香主,这个我知道

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

发送寄存器DR不是0x06

使用特权

评论回复
5
big5|  楼主 | 2009-5-23 21:14 | 只看该作者

补充

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

使用特权

评论回复
6
香水城| | 2009-5-23 21:33 | 只看该作者

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

KEIL当然也不可能检测到。

使用特权

评论回复
7
big5|  楼主 | 2009-5-23 22:45 | 只看该作者

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;
}

使用特权

评论回复
8
big5|  楼主 | 2009-5-23 22:46 | 只看该作者

续7楼

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

断点监测c的值不是0xaa,而是0x00。

使用特权

评论回复
9
big5|  楼主 | 2009-5-24 08:48 | 只看该作者

有做过stm32操作铁电的吗?

使用特权

评论回复
10
swtool| | 2009-5-24 15:32 | 只看该作者

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

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

/*******************************************************************/
/*    文件名: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);
}


使用特权

评论回复
11
swtool| | 2009-5-24 15:33 | 只看该作者

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

如题

使用特权

评论回复
12
big5|  楼主 | 2009-5-24 23:17 | 只看该作者

谢谢楼上的兄弟

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

使用特权

评论回复
13
McuPlayer| | 2009-5-24 23:19 | 只看该作者

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

读一下,相当于把时钟送出去,暂且这么理解吧

使用特权

评论回复
14
zhaoxingchen| | 2013-4-25 17:14 | 只看该作者
学习学习

使用特权

评论回复
15
hawksabre| | 2013-4-25 19:20 | 只看该作者
问题解决了吗   呼唤香主   香主应该有办法   

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

91

主题

242

帖子

0

粉丝