打印

stm32的奇怪SPI2问题?求解

[复制链接]
8984|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
alenthj|  楼主 | 2010-2-8 14:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现象:使用stm32的SPI2读写铁电FM25L512,软件IAR 5.4,仿真器JTAGE。
接上仿真器,使用硬件SPI2读写正常;把仿真器去掉开机,硬件SPI2读写错误,其它程序正常。

该用软件SPI2读写,带上仿真器正常,不带仿真器也正常。

附硬件SPI2初始化程序:
void SPI2Init(void)
{   
    SPI_InitTypeDef  SPI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
               
        //启动SPI时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
        //下面是SPI相关GPIO初始化//
        //SPI2模块对应的SCK、MISO、MOSI为AF引脚
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        //////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_High;
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;      //
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                        //高位先发
        SPI_InitStructure.SPI_CRCPolynomial = 7;
        SPI_Init(SPI2, &SPI_InitStructure);
        SPI_Cmd(SPI2, ENABLE);
}
沙发
香水城| | 2010-2-8 15:15 | 只看该作者
请用示波器看看,接上仿真器与去掉仿真器时,SPI的信号有什么不同。

使用特权

评论回复
板凳
yybj| | 2010-2-8 19:28 | 只看该作者
最近也在调这个铁电存储器,但是始终回读不到发回来的信号,楼主能否给点建议呢

使用特权

评论回复
地板
alenthj|  楼主 | 2010-2-9 08:25 | 只看该作者
/*结合上面的初始化程序,就是这个FRAM的驱动,希望对你有帮助*/

#define  WREN_CMD         0x06
#define  WRDI_CMD         0x04
#define  WRSR_CMD         0x01
#define  RDSR_CMD         0x05  
#define  WRITE_CMD        0x02
#define  READ_CMD         0x03  


//读或写一个直接
//返回读写是否成功标记。 1失败,0成功。
UCHAR SPI_ReadWriteByte(UCHAR TxData,UCHAR *RxData)
{
    USHORT cw=0,cr=0;
   
        //等待发送缓冲区空
        while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
        {
            if(++cw > 60000)return 1;
        }
        //发一个字节
        SPI_I2S_SendData(SPI2, TxData);

        //等待数据接收
        while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
        {
            if(++cr > 60000)return 1;   
        }
        //取数据
        *RxData = SPI_I2S_ReceiveData(SPI2);

        return 0;
}

//SPI写一个字节
void SPIWriteByte(UCHAR nByte)
{
    UCHAR rd;
   
        SPI_ReadWriteByte(nByte,&rd);
}

//SPI读一个字节
UCHAR SPIReadByte(void)
{
    UCHAR data;
        
        SPI_ReadWriteByte(0xA5,&data);   //0xA5是dummy data
        
        return data;
}

/*-----------------------------------------------------------*/
/*
* 函数:
*
* 入口:
*
* 出口:
*
* 说明: 写FRAM函数
*
* 创建:
*
*/
//写一个字节到FRAM
void FMWriteOne(USHORT nFMAddr,UCHAR nFMData)
{
        FM_CS_0;
        SPIWriteByte(WREN_CMD);  
        FM_CS_1;
        DelayNOP(10);
        
        FM_CS_0;
        SPIWriteByte(WRITE_CMD);
        SPIWriteByte((UCHAR)(nFMAddr>>8));
        SPIWriteByte((UCHAR)(nFMAddr&0x00ff));
        SPIWriteByte(nFMData);
        FM_CS_1;
}

//连续写N个字节到FRAM
UCHAR FMWriteSerial(USHORT nFMAddr,USHORT nFMNum,UCHAR *nFMData)
{
    USHORT i;
    UCHAR xor;          //写的同时进行异或
   
        xor = 0;
        
        FM_CS_0;
        SPIWriteByte(WREN_CMD);  
        FM_CS_1;
        Delayms(3);

        FM_CS_0;
        SPIWriteByte(WRITE_CMD);
        SPIWriteByte((UCHAR)(nFMAddr>>8));
        SPIWriteByte((UCHAR)(nFMAddr&0x00ff));
        for(i=0;i<nFMNum;i++)
        {
            SPIWriteByte(*nFMData);
            xor = xor ^ (*nFMData);
            nFMData++;
        }
        FM_CS_1;   
        
        return xor;
}



/*-----------------------------------------------------------*/
/*
* 函数:
*
* 入口:
*
* 出口:
*
* 说明: 读FRAM函数
*
* 创建:
*
*/
//从FRAM里读出一个字节
UCHAR FMReadOne(USHORT nFMAddr)
{
    UCHAR nData;
        
        FM_CS_0;  
        
        SPIWriteByte(READ_CMD);        
        SPIWriteByte((UCHAR)(nFMAddr>>8));
        SPIWriteByte((UCHAR)(nFMAddr&0x00ff));
        nData = SPIReadByte();
        
        FM_CS_1;
        
        return nData;
}

//从FRAM里连续读出N个字节
UCHAR FMReadSerial(USHORT nFMAddr,USHORT nFMNum,UCHAR *nFMData)
{
    USHORT i;
    UCHAR xor;
   
        xor = 0;
        
        FM_CS_0;  
        
        SPIWriteByte(READ_CMD);        
        SPIWriteByte((UCHAR)(nFMAddr>>8));
        SPIWriteByte((UCHAR)(nFMAddr&0x00ff));
        for(i=0;i<nFMNum;i++)
        {
            *nFMData = SPIReadByte();
            xor = xor ^ *nFMData;
            nFMData++;
        }
        FM_CS_1;
        
        return xor;
}

//从FRAM读出数据后校验
UCHAR FMCheck(USHORT nFMAddr,USHORT nFMNum)
{
    USHORT i;
    UCHAR xor,data;
   
        xor=0;
        
        FM_CS_0;  
        
        SPIWriteByte(READ_CMD);        
        SPIWriteByte((UCHAR)(nFMAddr>>8));
        SPIWriteByte((UCHAR)(nFMAddr&0x00ff));
        for(i=0;i<nFMNum;i++)
        {
            data = SPIReadByte();
            xor = xor ^ data;
        }
        FM_CS_1;     
        
        return xor;
}

/*-----------------------------------------------------------*/
/*
* 函数:
*
* 入口:
*
* 出口:
*
* 说明: 读FRAM状态
*
* 创建:
*
*/
UCHAR FMReadStatus(void)
{
    UCHAR nStatus;
        
        FM_CS_0;
        
        SPIWriteByte(RDSR_CMD);
        nStatus = SPIReadByte();
        
        FM_CS_1;
        
        return nStatus;
}


/*-----------------------------------------------------------*/
/*
* 函数:
*
* 入口:
*
* 出口:
*
* 说明: 写FRAM状态
*
* 创建:
*
*/
void FMWriteStatus(UCHAR nStatus)
{   
        FM_CS_0;
        SPIWriteByte(WREN_CMD);  
        FM_CS_1;
        DelayNOP(10);
        
        FM_CS_0;
        SPIWriteByte(WRSR_CMD);
        SPIWriteByte(nStatus);
        FM_CS_1;
}

使用特权

评论回复
5
lyadgjm| | 2013-10-12 16:38 | 只看该作者
我也遇到同样问题,在发送数据时用SPI_I2S_FLAG_TXE判断发送完成是不行的,用示波器看发现第一个数据还没发完,后面数据又写进发送寄存器,导致数据丢失,原因还没搞清,但通过SPI_I2S_FLAG_BSY判断成功,不信你可以试试

使用特权

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

本版积分规则

40

主题

221

帖子

0

粉丝