OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3669|回复: 2

【请教】stm32L151c8t6使用硬件IIC后无法擦除FLASH

[复制链接]

24

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
377
金钱
377
注册时间
2013-6-19
在线时间
53 小时
发表于 2016-9-10 16:12:04 | 显示全部楼层 |阅读模式
1金钱
rt,最近一个项目中使用stm32L151c8t6这个片子,单独使用硬件IIC进行加速传感器的配置,可以正常通信。单独使用内部flash保存配置变量也是可以正常保存的。
但是如果两个同时使用,iic可以正常读写,但是flsh擦除返回FLASH_ERROR_PROGRAM 错误,查看FLASH_CR寄存器,SIZVERR位被置位了,但是直接清掉再写也是
有问题的。
IIC写函数如下
[mw_shl_code=applescript,true]uint8_t I2cMcuWriteBuffer( I2c_t *obj, uint8_t deviceAddr, uint16_t addr, uint8_t *buffer, uint16_t size )
{
    uint32_t timeOut;

    __disable_irq( );

    /* Test on BUSY Flag */
    timeOut = TIMEOUT_MAX;
    while( I2C_GetFlagStatus( obj->I2c, I2C_FLAG_BUSY) )
    {
        if( ( timeOut-- ) == 0 )
        {
            I2cResetBus( obj );

            __enable_irq( );
            return( FAIL );
        }
    }
        

    /* Send START condition */
    I2C_GenerateSTART( obj->I2c, ENABLE );

    /* Test on EV5 and clear it */
    timeOut = TIMEOUT_MAX;
    while( !I2C_CheckEvent( obj->I2c, I2C_EVENT_MASTER_MODE_SELECT ) )
    {
            //log_d("----------------->I2C_EVENT_MASTER_MODE_SELECT");
        if( ( timeOut-- ) == 0 )
        {
            I2cResetBus( obj );

            __enable_irq( );
            return( FAIL );
        }
    }


    /* Send device's address for write */
    I2C_Send7bitAddress( obj->I2c, deviceAddr, I2C_Direction_Transmitter );

    /* Test on EV6 and clear it */
    timeOut = TIMEOUT_MAX;
    while( !I2C_CheckEvent( obj->I2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) )
    {
        if( ( timeOut-- ) == 0 )
        {
            I2cResetBus( obj );

            __enable_irq( );
            return( FAIL );
        }
    }

    if( I2cInternalAddrSize == I2C_ADDR_SIZE_16 )
    {
        /* Send the device's internal address MSB to write to */
        I2C_SendData( obj->I2c, ( uint8_t )( ( addr & 0xFF00 ) >> 8 )  );

        /* Test on EV8 and clear it */
        timeOut = TIMEOUT_MAX;
        while( !I2C_CheckEvent( obj->I2c, I2C_EVENT_MASTER_BYTE_TRANSMITTING ) )
        {
            if( ( timeOut-- ) == 0 )
            {
                I2cResetBus( obj );

                __enable_irq( );
                return( FAIL );
            }
        }
    }

    /* Send the device's internal address LSB to write to */
    I2C_SendData( obj->I2c, ( uint8_t )( addr & 0x00FF ) );

    /* Test on EV8 and clear it */
    timeOut = TIMEOUT_MAX;
    while( !I2C_CheckEvent( obj->I2c, I2C_EVENT_MASTER_BYTE_TRANSMITTING ) )
    {
        if( ( timeOut-- ) == 0 )
        {
            I2cResetBus( obj );

            __enable_irq( );
            return( FAIL );
        }
    }

    while( size )
    {
        /* Send the byte to be written */
        I2C_SendData( obj->I2c, *buffer );

        /* Test on EV8 and clear it */
        timeOut = TIMEOUT_MAX;
        while( !I2C_CheckEvent( obj->I2c, I2C_EVENT_MASTER_BYTE_TRANSMITTING ) )
        {
            if( ( timeOut-- ) == 0 )
            {
                I2cResetBus( obj );

                __enable_irq( );
                return( FAIL );
            }
        }

        if( size == 1 )
        {
            I2C_GenerateSTOP( obj->I2c, ENABLE );
        
            /* Wait to make sure that STOP control bit has been cleared */
            timeOut = TIMEOUT_MAX;
            while(obj->I2c->CR1 & I2C_CR1_STOP)
            {
                if( ( timeOut-- ) == 0 )
                {
                    I2cResetBus( obj );

                    __enable_irq( );
                    return( FAIL );
                }
            }
        } /* STOP */

        buffer++;
        size--;
    }

    __enable_irq( );
    return( SUCCESS );
}[/mw_shl_code]


FLASH擦写函数如下:
[mw_shl_code=applescript,true]        __disable_irq();

    /* start erase */
    FLASH_Unlock();

        //FLASH->ACR%=~(1<<10);                                       
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGAERR | FLASH_FLAG_WRPERR);
    for (i = 0; i < erase_pages; i++) {
        flash_status = FLASH_ErasePage(addr + (PAGE_SIZE * i));
        if (flash_status != FLASH_COMPLETE) {
            result = EF_ERASE_ERR;
                        log_d("i:%d,erase_pages:%d,flash_status:%d",i,erase_pages,flash_status);
            break;
        }
    }
                //FLASH->ACR|=1<<10;                //FLASH????,????fetch
    FLASH_Lock();
        RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE );
        __enable_irq();[/mw_shl_code]


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

24

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
377
金钱
377
注册时间
2013-6-19
在线时间
53 小时
 楼主| 发表于 2016-9-13 19:35:54 | 显示全部楼层
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-9-13 20:40:02 | 显示全部楼层
帮顶
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 16:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表