STM32学习笔记4(失败的尝试)-掉电检测+Flash存取

看到STM32有PVD的掉电检测功能,flash也可以直接存取;就动了用flash掉电保存参数的念头。

1、搞定Flash擦、写函数。

void  F_ErasePage(u32 Page_Address)
{
 U32 tmp;
 while((FLASH->SR&FLASH_FLAG_BSY)==FLASH_FLAG_BSY)
 {  //PutCnstStr2Usart1("waiting\n"); }
 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("waiting\n"); }
 FLASH->CR &= ~CR_PER_Set;//这个不能忘
 }
void FLASH_Program(u32 Address, u16 Data)
{
 U32 tmp;
Fstart:
 if((FLASH->CR&CR_LOCK_Set)==CR_LOCK_Set)  //如果写被锁死
 {
  FLASH->KEYR = FLASH_KEY1;
    FLASH->KEYR = FLASH_KEY2;
    //PutCnstStr2Usart1("Unclock\n");
 }
  while((FLASH->SR&FLASH_FLAG_BSY)==FLASH_FLAG_BSY)
 {
  //PutCnstStr2Usart1("waiting\n");
 }
 FLASH->CR |= CR_PG_Set;
 *(vu16*)Address = Data; 
 FLASH->CR &= ~CR_PG_Set;
 if((FLASH->SR&FLASH_FLAG_PGERR)==FLASH_FLAG_PGERR)
 {    
  //PutCnstStr2Usart1("No earase\n");
  F_ErasePage(Address);
  goto Fstart;//竟然用了goto,咳咳^_^
 }
}

有了这两个函数基本就行了,反正一次要擦一个page,全拿过来保存参数就行了,比较可靠。

U16 const flashdata[1024]__at(0x08001000);//因为flash一次能且只能写16bit,另外访问奇地址会出错。

还有不要忘了#include ,绝对定位全靠它了。

将要保存的参数放到一个结构里面,每次上电复位的时候加载,需要存储时写入flash

2、搞定掉电检测


void PVD_Init(void)
{
 NVIC_InitTypeDef NVIC_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、联合工作,失败

void PVD_IRQHandler(void)
{
 U16 i;
 U32 tmp;
 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,可以用稳压器前的电压用于检测。

由于目前还不能对电路板进行破坏性改造,手头也没有示波器,可调电源,暂时放弃对此做进一步的研究。

套用某大人物的逻辑,这次尝试是部分失败,


http://blog.sina.com.cn/s/blog_7077264c0100lvwe.html

你可能感兴趣的:(STM32学习笔记4(失败的尝试)-掉电检测+Flash存取)