CH32V103 Flash我怎么弄不对呢
#define FLASH_POWERDATA_ADDR           ((uint32_t)0x0800E000)

void Save_ConfigData(void)
{
    FLASH_Unlock_Fast();
    FLASH_ErasePage_Fast(FLASH_POWERDATA_ADDR);
    FLASH_BufReset();
    FLASH_BufLoad(FLASH_POWERDATA_ADDR, (u32)ConfigInfo.iMaxVoltage, (u32)ConfigInfo.iMaxCurrent, (u32)ConfigInfo.iTime1, (u32)ConfigInfo.iTime2);
    FLASH_ProgramPage_Fast(FLASH_POWERDATA_ADDR);
    FLASH_Lock_Fast();
}

void Read_ConfigData(void)
{
    ConfigInfo.iMaxVoltage = *(u32 *)(FLASH_POWERDATA_ADDR);
    ConfigInfo.iMaxCurrent = *(u32 *)(FLASH_POWERDATA_ADDR+0x04);
    ConfigInfo.iTime1 = *(u32 *)(FLASH_POWERDATA_ADDR+0x08);
    ConfigInfo.iTime2 = *(u32 *)(FLASH_POWERDATA_ADDR+0x0C);

	if(0xFFFF == ConfigInfo.iMaxVoltage)
	{
	    InitPowerInfo();
	    Save_ConfigData();
	}
}


一共就这几行代码,每次Read出来都是0XFFFF。 有没有跟ST-LINK Utility类似的工具啊,可以外部读取Flash内容,从而先确定是没写进去,还是读出问题了啊,函数接口又都是void类型,完全不知道问题出在哪里。

您好,若你需要读取FLASH的存储内容,只需要读对应的地址就可以了。附件为CH32V103 FLASH读操作例程,你可以参考下。注意下,若你在读之前有解除读保护操作,且解除之后并没有写入,那读出来就会是0xFFFF。

icon_rar.gifCH32V103 FLASH读操作.zip



我换到标准读写了,目前写入的时候,在FLASH_Lock的时候卡住,出不来。


保存前,禁用中断,LOCK后再恢复,目前看效果一样。


您好,若你是FLASH写入出现问题,当采用快速编程方式时,需要先执行快速编程模式解锁操作,然后再进行操作,如下图。具体可参考我们手册闪存操作流程和EVT FLASH例程。

CH32V103应用手册:/downloads/CH32xRM_PDF.html

CH32V103EVT例程:/downloads/CH32V103EVT_ZIP.html

image.png

image.png


我用demo代码,没问题。


然后用自己的代码,就不行了。 用到了ADC-DMA中断, 外部中断,Freertos.

EXTI0_IRQHandler中调用的Flash写入,为了排除是不是中断函数里不能读写Flash。 我把代码加在Main中了


main读了Flash,不过出来全部是0xFF。  随后执行写入操作(标准写,不是Fast)。 这时候暂停代码,发现停止在

FLASH_WaitForLastOperation函数入口。

void Read_ConfigData(void)
{
    ConfigInfo.iMaxVoltage = *(__IO uint16_t *)(FLASH_POWERDATA_ADDR);
    ConfigInfo.iMaxCurrent = *(__IO uint16_t *)(FLASH_POWERDATA_ADDR+0x04);
    ConfigInfo.iTime1 = *(__IO uint16_t *)(FLASH_POWERDATA_ADDR+0x08);
    ConfigInfo.iTime2 = *(__IO uint16_t *)(FLASH_POWERDATA_ADDR+0x0C);
    ConfigInfo.iAutoTime = *(__IO uint16_t *)(FLASH_POWERDATA_ADDR+0x10);
    ConfigInfo.iInterval= *(__IO uint16_t *)(FLASH_POWERDATA_ADDR+0x014);

	if(0xFFFF == ConfigInfo.iMaxVoltage)
	{
	    InitPowerInfo();
	    Save_ConfigData();
	}
}


void Save_ConfigData(void)
{
    /*FLASH_Unlock_Fast();
    FLASH_ErasePage_Fast(FLASH_POWERDATA_ADDR);
    FLASH_BufReset();
    FLASH_BufLoad(FLASH_POWERDATA_ADDR, (u32)ConfigInfo.iMaxVoltage, (u32)ConfigInfo.iMaxCurrent, (u32)ConfigInfo.iTime1, (u32)ConfigInfo.iTime2);
    FLASH_ProgramPage_Fast(FLASH_POWERDATA_ADDR);
    FLASH_Lock_Fast();*/
    volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
    volatile TestStatus MemoryEraseStatus = PASSED;

    uint32_t              EraseCounter = 0x0, Address = 0x0;
    uint32_t              WRPR_Value = 0xFFFFFFFF;
    uint32_t              NbrOfPage;

    __disable_irq();
    FLASH_Unlock();
    WRPR_Value = FLASH_GetWriteProtectionOptionByte();
    NbrOfPage = (PAGE_WRITE_END_ADDR - FLASH_POWERDATA_ADDR) / FLASH_PAGE_SIZE;

    if((WRPR_Value & FLASH_PAGES_TO_BE_PROTECTED) != 0x00)
    {
        FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

        for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
        {
            FLASHStatus = FLASH_ErasePage(FLASH_POWERDATA_ADDR + (FLASH_PAGE_SIZE * EraseCounter));
            if(FLASHStatus != FLASH_COMPLETE)
            {
                printf("FLASH Erase ERR at Page%d\r\n", EraseCounter + 60);
            }
            printf("FLASH Erase Page%d...\r\n", EraseCounter + 60);
        }

        Address = FLASH_POWERDATA_ADDR;
        while((Address < PAGE_WRITE_END_ADDR) && (MemoryEraseStatus != FAILED))
        {
            if((*(__IO uint16_t *)Address) != 0xFFFF)
            {
                MemoryEraseStatus = FAILED;
            }
            Address += 2;
        }
        if(MemoryEraseStatus == FAILED)
        {
            printf("Erase Flash FAIL!\r\n");
            printf("\r\n");
        }
        else
        {
            printf("Erase Flash PASS!\r\n");
        }

        Address = FLASH_POWERDATA_ADDR;
        //while((Address < PAGE_WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE))
        FLASHStatus = FLASH_ProgramHalfWord(Address, ConfigInfo.iMaxVoltage);
        Address = Address + 2;
        FLASHStatus = FLASH_ProgramHalfWord(Address, ConfigInfo.iMaxCurrent);
        Address = Address + 2;
        FLASHStatus = FLASH_ProgramHalfWord(Address, ConfigInfo.iTime1);
        Address = Address + 2;
        FLASHStatus = FLASH_ProgramHalfWord(Address, ConfigInfo.iTime2);
        Address = Address + 2;
        FLASHStatus = FLASH_ProgramHalfWord(Address, ConfigInfo.iAutoTime);
        Address = Address + 2;
        FLASHStatus = FLASH_ProgramHalfWord(Address, ConfigInfo.iInterval);
        Address = Address + 2;
        while((Address < PAGE_WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE))
        {
            FLASHStatus = FLASH_ProgramHalfWord(Address, 0xAA);
        }

        /*
        Address = PAGE_WRITE_START_ADDR;
        while((Address < PAGE_WRITE_END_ADDR) && (MemoryProgramStatus != FAILED))
        {
            if((*(__IO uint16_t *)Address) != Data)
            {
                MemoryProgramStatus = FAILED;
            }
            Address += 2;
        }
        if(MemoryProgramStatus == FAILED)
        {
            printf("Memory Program FAIL!\r\n");
        }
        else
        {
            printf("Memory Program PASS!\r\n");
        }
        */
    }

    FLASH_Lock();
    __enable_irq();
}



您好,我们FLASH标准库函数中有多处调用到FLASH_WaitForLastOperation这个函数,你可以通过打印调试的方式看程序具体是停止在哪个函数里了,若需要,可将例程发到我的邮箱(lzs@wch.cn),这边可以帮你看一下


只有登录才能回复,可以选择微信账号登录