矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: 1038733481

艾默生“HD4830-3”改数控、可调电源,开源

[复制链接]
     
发表于 2020-10-16 10:15:13 | 显示全部楼层
正在学习单片机就关注数控部分
回复 支持 反对

使用道具 举报

     
发表于 2020-10-16 10:51:00 | 显示全部楼层
矿坛铁粉 发表于 2020-8-21 09:48
不用那么麻烦,一页擦除后所有字节都是ff,假定要保存的参数是4个字节,存储的时候再加上1个字节的标志, ...


小试了一下这个办法,写入时间过长,失败了。

硬件初始化时查找标志位、读出存储的数据,标志位清零,解锁FLASH。
触发掉电中断后,偏移量12写入标志位和电压、电流设置值,锁定FLASH。
ADC、DAC都是12位的,存储电压、电流设置值各用4个字节,共8字节,掉电后存储这8个字节还行。加上标志用的4字节,22UF滤波电容挺不住,存储失败了。

液晶屏背光耗电大,手上贴片电容最大只有22UF,可能是留给掉电后保存数据的时间不足造成写入失败。懒得动烙铁,回头再试,硬件稍微改改,这个方法应该没问题。
回复 支持 反对

使用道具 举报

     
发表于 2020-10-16 11:04:41 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-10-17 01:02:02 | 显示全部楼层
本帖最后由 1038733481 于 2020-10-17 01:05 编辑

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        int address = 0x0800E000;
        if((*(__IO uint16_t *)(0x0800E0F0)) != 0xFFFF){address = 0x0800E0F0;}
        else if((*(__IO uint16_t *)(0x0800E0E0)) != 0xFFFF){address = 0x0800E0E0;}
        else if((*(__IO uint16_t *)(0x0800E0D0)) != 0xFFFF){address = 0x0800E0D0;}
        else if((*(__IO uint16_t *)(0x0800E0C0)) != 0xFFFF){address = 0x0800E0C0;}
        else if((*(__IO uint16_t *)(0x0800E0B0)) != 0xFFFF){address = 0x0800E0B0;}
        else if((*(__IO uint16_t *)(0x0800E0A0)) != 0xFFFF){address = 0x0800E0A0;}
        else if((*(__IO uint16_t *)(0x0800E090)) != 0xFFFF){address = 0x0800E090;}
        else if((*(__IO uint16_t *)(0x0800E080)) != 0xFFFF){address = 0x0800E080;}
        else if((*(__IO uint16_t *)(0x0800E070)) != 0xFFFF){address = 0x0800E070;}
        else if((*(__IO uint16_t *)(0x0800E060)) != 0xFFFF){address = 0x0800E060;}
        else if((*(__IO uint16_t *)(0x0800E050)) != 0xFFFF){address = 0x0800E050;}
        else if((*(__IO uint16_t *)(0x0800E040)) != 0xFFFF){address = 0x0800E040;}
        else if((*(__IO uint16_t *)(0x0800E030)) != 0xFFFF){address = 0x0800E030;}
        else if((*(__IO uint16_t *)(0x0800E020)) != 0xFFFF){address = 0x0800E020;}
        else if((*(__IO uint16_t *)(0x0800E010)) != 0xFFFF){address = 0x0800E010;}
        else if((*(__IO uint16_t *)(0x0800E000)) != 0xFFFF){address = 0x0800E000;}

        UVP         = *(__IO uint16_t*)(address); //*(__IO uint16_t *)是读取该地址的参数值,其值为16位数
        OCP         = *(__IO uint16_t*)(address+0x2); //*(__IO uint16_t *)是读取该地址的参数值,其值为1
        mAS_p         = *(__IO uint32_t*)(address+0x4); //*(__IO uint16_t *)是读取该地址的参数值,其                                               
        mAS_n         = *(__IO uint32_t*)(address+0x8); //*(__IO uint16_t *)是读取该地址的参数值,其
        WS                 = *(__IO uint32_t*)(address+0xC); //*(__IO uint16_t *)是读取该地址的参数值,其


    __HAL_RCC_PWR_CLK_ENABLE();
    PWR_PVDTypeDef PWR_PVDStruct;
    PWR_PVDStruct.PVDLevel = PWR_PVDLEVEL_FALLING_6;             //
    PWR_PVDStruct.Mode = PWR_PVD_MODE_IT_FALLING;        //降至阈值电压时触发
        HAL_PWR_ConfigPVD(&PWR_PVDStruct);       
        HAL_PWR_EnablePVD();                                                                //PVD中断
//        HAL_PWR_DisablePVD();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void HAL_PWR_PVD_Falling_Callback(void){                                                                //PVD回调
       
        FLASH_EraseInitTypeDef My_Flash;  //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash                               
        HAL_FLASH_Unlock();               //解锁Flash
        int address = 0x0800E000;
        if((*(__IO uint16_t *)(0x0800E000)) == 0xFFFF){address = 0x0800E000;}
        else if((*(__IO uint16_t *)(0x0800E010)) == 0xFFFF){address = 0x0800E010;}
        else if((*(__IO uint16_t *)(0x0800E020)) == 0xFFFF){address = 0x0800E020;}
        else if((*(__IO uint16_t *)(0x0800E030)) == 0xFFFF){address = 0x0800E030;}
        else if((*(__IO uint16_t *)(0x0800E040)) == 0xFFFF){address = 0x0800E040;}
        else if((*(__IO uint16_t *)(0x0800E050)) == 0xFFFF){address = 0x0800E050;}
        else if((*(__IO uint16_t *)(0x0800E060)) == 0xFFFF){address = 0x0800E060;}
        else if((*(__IO uint16_t *)(0x0800E070)) == 0xFFFF){address = 0x0800E070;}
        else if((*(__IO uint16_t *)(0x0800E080)) == 0xFFFF){address = 0x0800E080;}
        else if((*(__IO uint16_t *)(0x0800E090)) == 0xFFFF){address = 0x0800E090;}
        else if((*(__IO uint16_t *)(0x0800E0A0)) == 0xFFFF){address = 0x0800E0A0;}
        else if((*(__IO uint16_t *)(0x0800E0B0)) == 0xFFFF){address = 0x0800E0B0;}
        else if((*(__IO uint16_t *)(0x0800E0C0)) == 0xFFFF){address = 0x0800E0C0;}
        else if((*(__IO uint16_t *)(0x0800E0D0)) == 0xFFFF){address = 0x0800E0D0;}
        else if((*(__IO uint16_t *)(0x0800E0E0)) == 0xFFFF){address = 0x0800E0E0;}
        else if((*(__IO uint16_t *)(0x0800E0F0)) == 0xFFFF){address = 0x0800E0F0;}
        else {
                My_Flash.TypeErase = FLASH_TYPEERASE_PAGES;         //标明Flash执行页面只做擦除操作
//                My_Flash.Page = 0x0800E000;                                        //声明要擦除的地址                //STM32F0       
                My_Flash.Page = 28;                                                         //声明要擦除的块                        //STM32G0
                My_Flash.NbPages = 1;                                                //说明要擦除的页数,此

                uint32_t PageError = 0;                                                //设置PageError,如果出现错
                HAL_FLASHEx_Erase(&My_Flash, &PageError);                //调用擦除函数擦除
        }

        uint64_t uvpocp = UVP + (OCP << 16) ;
        uvpocp = uvpocp + (mAS_p <<32) ;
        uint64_t masws = mAS_n + (WS << 32) ;
        HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, uvpocp ); //对Flash进行烧写,
        HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address+0x8, masws ); //对Flash进行烧写
                       
                                                                                                                //F0最少写入两个字节,G0最少写入两个字

        HAL_FLASH_Lock(); //锁住Flash
       
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

单片机是stm32g031 电流大概20mA 电容100uf电解
擦除的时候也可以写入成功 貌似不应该把擦除放在掉电中断里 能用就懒得改了
回复 支持 反对

使用道具 举报

     
发表于 2023-12-8 10:04:50 | 显示全部楼层
太深奥了,都是大神级别
回复 支持 反对

使用道具 举报

     
发表于 2024-3-19 11:02:09 | 显示全部楼层
学习学习!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-27 03:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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