打印
[STM8]

关于使用SPI调试SPI FLASH的问题

[复制链接]
6851|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lanjackg2003|  楼主 | 2014-8-21 10:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
   小弟我用STM8的SPI功能,调试MX25L6406E这个64MB的SPI_Flash(硬件是搭了一个万用表然后飞线到学习板的SPI口上面的).使用的是SPI的模式3方式进行数据的传送接收.时钟使用Fcpu / 2.
   主要涉及的代码如下:

/*
* Function:       Wait_Flash_WarmUp
* Arguments:      None.
* Description:    Wait some time until flash read / write enable.
* Return Message: None.
*/
void Wait_Flash_WarmUp()
{
    uint32 time_cnt = FlashFullAccessTime;
    while( time_cnt > 0 )
    {
        time_cnt--;
    }
}

/*
* Function:       Initial_Spi
* Arguments:      None
* Description:    Initial spi flash state and wait flash warm-up
*                 (enable read/write).
* Return Message: None
*/
void Initial_Spi()
{
        GPIO_Init(CS_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
        GPIO_Init(SPI_SCK_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
        GPIO_Init(SPI_MOSI_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
        GPIO_Init(SPI_MISO_PIN,GPIO_MODE_IN_PU_NO_IT);

        SPI_DeInit();
        SPI_Init(SPI_FIRSTBIT_MSB,SPI_BAUDRATEPRESCALER_16,SPI_MODE_MASTER,SPI_CLOCKPOLARITY_HIGH,\
                SPI_CLOCKPHASE_2EDGE,SPI_DATADIRECTION_2LINES_FULLDUPLEX,SPI_NSS_SOFT,0x07);
        SPI_Cmd(TRUE);

        // Wait flash warm-up
    Wait_Flash_WarmUp();
}

/*
* Function:       CS_Low, CS_High
* Arguments:      None.
* Description:    Chip select go low / high.
* Return Message: None.
*/
void CS_Low()
{
    GPIO_WriteLow(CS_PIN);
}

void CS_High()
{
    //--- insert your chip select code here. ---//
    GPIO_WriteHigh(CS_PIN);
}


/*
* Function:       SendByte
* Arguments:      byte_value, data transfer to flash
*                 transfer_type, select different type of I/O mode.
*                 Seven mode:
*                 SIO, single IO
*                 DIO, dual IO
*                 QIO, quad IO
*                 PIO, parallel
*                 DTSIO, double transfer rate SIO
*                 DTDIO, double transfer rate DIO
*                 DTQIO, double transfer rate QIO
* Description:    Send one byte data to flash
* Return Message: None.
*/
void SendByte( uint8 byte_value, uint8 transfer_type )
{
        while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);

        SPI_SendData(byte_value);

}
/*
* Function:       GetByte
* Arguments:      byte_value, data receive from flash
*                 transfer_type, select different type of I/O mode.
*                 Seven mode:
*                 SIO, single IO
*                 DIO, dual IO
*                 QIO, quad IO
*                 PIO, parallel IO
*                 DTSIO, double transfer rate SIO
*                 DTDIO, double transfer rate DIO
*                 DTQIO, double transfer rate QIO
* Description:    Get one byte data to flash
* Return Message: 8 bit data
*/
uint8 GetByte( uint8 transfer_type )
{
    uint8 data_buf;
        SendByte( DUMMY_BYTE, SIO );
        while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET);
        data_buf = SPI_ReceiveData();

    return data_buf;
}

///////////////以下是测试代码//////////////////////////////
#define  TRANS_LENGTH  16
#define  RANDOM_SEED   106
#define  FLASH_TARGET_ADDR  0x00000000

#define  Error_inc(x)  x = x + 1;
/*
* Simple flash ID test
*/
uint8 FlashID_Test( void )
{
    uint32  flash_id = 0;
    uint16  error_cnt = 0;
    uint16  rems_id;
    uint8   electric_id = 0;
    FlashStatus  flash_state = {0};
    ReturnMsg  msg;

    /* Read flash device id */
    msg =  CMD_RDID( &flash_id );
    if( msg != (ReturnMsg)FlashOperationSuccess )
        return FALSE;

    msg = CMD_RES( &electric_id );
    if( msg != (ReturnMsg)FlashOperationSuccess )
        return FALSE;

    /* Decide rems_id order. 0: { manufacturer id, device id }
                             1: { device id,  manufacturer id } */
    flash_state.ArrangeOpt = 0;

    msg = CMD_REMS( &rems_id, &flash_state );
    if( msg != (ReturnMsg)FlashOperationSuccess )
        return FALSE;

    /* Compare to expected value */
    if( flash_id != FlashID )
        Error_inc( error_cnt );

    if( electric_id != ElectronicID )
        Error_inc( error_cnt );

    if( flash_state.ArrangeOpt )
    {
        if( rems_id != RESID1 )
           Error_inc( error_cnt );
    }else
    {
        if( rems_id != RESID0 )
           Error_inc( error_cnt );
    }

    if( error_cnt != 0 )
        return FALSE;
    else
        return TRUE;
}


//////
发现测试代码读取回来的值并非datasheet说的值.datasheet的值如下:
#define    FlashID          0xc22017
#define    ElectronicID     0x16
#define    RESID0           0xc216
#define    RESID1           0x16c2


因此,小弟想请教一下,SPI这个读数据会不会跟硬件是飞线的原因造成的.另外MISO及MOSI这个两个口都没有接外部上拉电阻.
还是我上面软件配置哪里有异常?
请大家指教,谢谢
沙发
airwill| | 2014-8-21 12:19 | 只看该作者
SPI 操作 SPI口的 FLASH, 应该是能够实现的
可以描述一下错误情况, 你读到的数据是什么?
SPI这个读数据会不会跟硬件是飞线的原因造成的. 这是有可能的. 凌乱的飞线, 受干扰的机会肯定多.
MISO及MOSI这个两个口都没有接外部上拉电阻. 应该不会有问题. 也可以接一下试试

使用特权

评论回复
板凳
lanjackg2003|  楼主 | 2014-8-21 22:26 | 只看该作者
airwill 发表于 2014-8-21 12:19
SPI 操作 SPI口的 FLASH, 应该是能够实现的
可以描述一下错误情况, 你读到的数据是什么?
SPI这个读数据会不 ...

就是我读FLASH的设备ID时候
读到的FlashID是0x00FF4017
rems_id是0xFF16
跟数据手册上辨识的值不一样
因此应该是读出来的数据有问题

使用特权

评论回复
地板
airwill| | 2014-8-22 06:20 | 只看该作者
看来有部分数据收到了. 是否先降低 SPI 频率, 增加些延时试试.

使用特权

评论回复
5
lanjackg2003|  楼主 | 2014-8-22 09:43 | 只看该作者
airwill 发表于 2014-8-22 06:20
看来有部分数据收到了. 是否先降低 SPI 频率, 增加些延时试试.

我测试过使用Fcpu / 256 ,确实数据内容也变化了,
但是也不是datasheet所标明的值.
看来只能打板回来验证一下,这个SPI调试FLASH的功能

使用特权

评论回复
6
lanjackg2003|  楼主 | 2014-8-22 09:44 | 只看该作者
另外补充一点,我自己做回环测试,结果是正确的.Fcpu / 2的频率.
所以我觉得应该跟硬件干扰有很大的关系,

使用特权

评论回复
7
lanjackg2003|  楼主 | 2014-8-23 20:49 | 只看该作者
结贴了,哈哈
找到原因了,需要SPI的读空数据,具体在我的博客
http://blog.csdn.net/lan120576664/article/details/38781157

使用特权

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

本版积分规则

56

主题

440

帖子

7

粉丝