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。
百思不得其解,至少这里不应该出错啊。
读和写SPI_DR寄存器,实际操作的不是同一个寄存器
写DR实际操作的是发送寄存器,而读DR实际操作的是接收寄存器。
香主,这个我知道
现在的问题是:
SPI_I2S_SendData(SPI2, 0x06);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
发送寄存器DR不是0x06
补充
执行这条语句:SPI_I2S_SendData(SPI2, 0x06);
应该是往发送寄存器DR写入0x06,可是在keil检测到是0x00
没有办法可以读到SPI发送寄存器DR
KEIL当然也不可能检测到。
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;
}
续7楼
主程序执行下面的代码:
fm25cx_writebyte(0, 0xaa);
fm25cx_readbyte(0, &c);
断点监测c的值不是0xaa,而是0x00。
我的刚刚做成功,给你原码看看
我刚刚做成功,我的源代码:
/*******************************************************************/
/* 文件名: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);
}
谢谢楼上的兄弟
下午我也搞定了,做法差不多。
不过有个地方不明白:通过SPI发送的字节数据为什么每次还要读一下?
SPI是有2个线,收发独立的
读一下,相当于把时钟送出去,暂且这么理解吧