新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32掉電檢測+Flash存取

        STM32掉電檢測+Flash存取

        作者: 時間:2016-11-17 來源:網絡 收藏
        STM32有PVD的掉電檢測功能,flash也可以直接存取;就動了用flash掉電保存參數的念頭。
        1、搞定Flash擦、寫函數。
        voidF_ErasePage(u32Page_Address)
        {
        U32tmp;
        while((FLASH->SR&FLASH_FLAG_BSY)==FLASH_FLAG_BSY)
        {//PutCnstStr2Usart1("waitingn");}
        FLASH->SR|=FLASH_FLAG_PGERR;
        FLASH->CR|=CR_PER_Set;
        FLASH->AR=Page_Address;
        FLASH->CR|=CR_STRT_Set;
        while((FLASH->SR&FLASH_FLAG_BSY)==FLASH_FLAG_BSY)
        {//PutCnstStr2Usart1("waitingn");}
        FLASH->CR&=~CR_PER_Set;//這個不能忘
        }
        voidFLASH_Program(u32Address,u16Data)
        {
        U32tmp;
        Fstart:
        if((FLASH->CR&CR_LOCK_Set)==CR_LOCK_Set)//如果寫被鎖死
        {
        FLASH->KEYR=FLASH_KEY1;
        FLASH->KEYR=FLASH_KEY2;
        //PutCnstStr2Usart1("Unclockn");
        }
        while((FLASH->SR&FLASH_FLAG_BSY)==FLASH_FLAG_BSY)
        {
        //PutCnstStr2Usart1("waitingn");
        }
        FLASH->CR|=CR_PG_Set;
        *(vu16*)Address=Data;
        FLASH->CR&=~CR_PG_Set;
        if((FLASH->SR&FLASH_FLAG_PGERR)==FLASH_FLAG_PGERR)
        {
        //PutCnstStr2Usart1("Noearasen");
        F_ErasePage(Address);
        gotoFstart;//竟然用了goto,咳咳^_^
        }
        }
        有了這兩個函數基本就行了,反正一次要擦一個page,全拿過來保存參數就行了,比較可靠。
        U16constflashdata[1024]__at(0x08001000);//因為flash一次能且只能寫16bit,另外訪問奇地址會出錯。
        還有不要忘了#include,絕對定位全靠它了。
        將要保存的參數放到一個結構里面,每次上電復位的時候加載,需要存儲時寫入flash
        2、搞定掉電檢測

        voidPVD_Init(void)
        {
        NVIC_InitTypeDefNVIC_InitStruct;
        NVIC_InitStruct.NVIC_IRQChannel=PVD_IRQChannel;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0x00;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority=0x00;
        NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM3|
        RCC_APB1Periph_TIM4|RCC_APB1Periph_USART2|RCC_APB1Periph_PWR,ENABLE);//_PWR,ENABLE);//這個是必需的
        PWR->CR|=1<<4;//使能
        PWR->CR|=0xE0;//2.9V檢測
        NVIC_Init(&NVIC_InitStruct);//借用一下庫,允許中斷
        }
        寄存器設置有效,手動置相應中斷標志可進入中斷
        3、聯合工作,失敗
        voidPVD_IRQHandler(void)
        {
        U16i;
        U32tmp;
        tmp=0x08001000;

        if((PWR->CSR&PWR_FLAG_PVDO)==PWR_FLAG_PVDO)//低于閾值(電壓回升也會中斷)
        {
        F_ErasePage(tmp);
        for(i=0;i<2000;i++)
        {
        FLASH_Program(tmp,i);
        tmp+=2;
        }
        }

        }
        分析:1、Vdda經過LC濾波可能會比Vdd掉的慢,而據說stm32會因此產生檢測問題。2、電源回路電容量小,時間來不及。
        嘗試:從ATX電源上拆了一個1000uF的電容,接上,無改善。
        思考:把掉電檢測跟電源腳做在一起實在意義不大,一般情況下MCU的電源都是經過LDO穩壓的,掉電檢測使用專門的IO,可以用穩壓器前的電壓用于檢測。
        由于目前還不能對電路板進行破壞性改造,手頭也沒有示波器,可調電源,暫時放棄對此做進一步的研究。
        套用某大人物的邏輯,這次嘗試是部分失敗


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 云梦县| 连山| 长岛县| 巫山县| 白水县| 黄平县| 郴州市| 克什克腾旗| 临漳县| 乐陵市| 旺苍县| 保亭| SHOW| 苏尼特右旗| 房产| 介休市| 温州市| 嘉祥县| 河南省| 桃江县| 高雄县| 阜新市| 塘沽区| 景宁| 和田县| 噶尔县| 名山县| 晋江市| 宕昌县| 兴宁市| 安达市| 历史| 阿拉尔市| 旬邑县| 渑池县| 托里县| 莒南县| 曲水县| 承德县| 宝山区| 天峨县|