问答

汇集网友智慧,解决技术难题

21ic问答首页 - GD32F470配置了LVD怎么知道它进没进中断啊

单片机 国产芯片

GD32F470配置了LVD怎么知道它进没进中断啊

小熊猫1232025-10-27
①测试程序里给外部flash写1A,LVD中断里写3C,烧录后重新开机,再去仿真,值还是1A啊,这是没进LVD中断?
VCC从3.3v到2.6v也有几毫秒也够了吧?
②还有LVD中断咋仿真啊?仿真状态下关电源仿真也断了……
回答 +关注 0
53人浏览 5人回答问题 分享 举报
5 个回答
  • 仿真时若直接关闭电源,仿真器会断开连接,导致无法观察中断行为。
  • 在中断服务函数中调用exti_interrupt_flag_clear(EXTI_16)清除标志。
  • 是不是中断未使能
  • 可能LVD中断确实没有触发或者中断触发了但写操作失败(电压太低导致Flash写入失败)LVD配置可能有问题


    改进的检测方法


    // 定义检测变量
    volatile uint32_t lvd_int_count = 0;
    volatile uint32_t lvd_status = 0;

    // LVD中断服务函数
    void LVD_IRQHandler(void)
    {
        if(lvd_interrupt_flag_get() != RESET) {
            lvd_int_count++;  // 中断计数
            lvd_status = 0xAA55AA55;  // 设置特殊标记
            
            // 不要在这里写Flash,电压可能已经不稳定
            // 改为设置标志,在主循环中处理
            
            lvd_interrupt_flag_clear();
        }
    }

    // 主循环中检测
    while(1) {
        if(lvd_status == 0xAA55AA55) {
            // LVD中断已触发
            printf("LVD中断已触发,计数: %lu\n", lvd_int_count);
            lvd_status = 0; // 清除标志
            
            // 这里可以执行安全操作,如保存关键数据
        }
    }

    完整的LVD配置示例

    void lvd_config(void)
    {
        /* 配置LVD */
        // 选择LVD阈值,根据你的需求选择
        lvd_deinit();
        lvd_select(LVD_SEL_0); // 例如2.6V
       
        /* 使能LVD中断 */
        lvd_interrupt_enable();
       
        /* 使能LVD */
        lvd_enable();
       
        /* 配置NVIC */
        nvic_irq_enable(LVD_IRQn, 0, 0);
       
        printf("LVD配置完成\r\n");
    }

    实用的仿真调试技巧
    方法一:使用备份寄存器

    // 在LVD中断中写入备份寄存器
    void LVD_IRQHandler(void)
    {
        if(lvd_interrupt_flag_get() != RESET) {
            // 写入备份寄存器,掉电后仍能保持
            BKP_DATA0 = 0x3C3C3C3C;
            lvd_interrupt_flag_clear();
        }
    }

    // 开机时检查
    if(BKP_DATA0 == 0x3C3C3C3C) {
        printf("上次发生了LVD中断!\n");
        BKP_DATA0 = 0; // 清除标记
    }

    方法二:使用内部Flash标记

    #define LVD_MARK_ADDR 0x0800F000  // Flash最后一页的某个地址

    void set_lvd_mark(void)
    {
        // 在LVD中断中调用此函数
        fmc_unlock();
        fmc_page_erase(LVD_MARK_ADDR);
        fmc_word_program(LVD_MARK_ADDR, 0x12345678);
        fmc_lock();
    }

    uint8_t check_lvd_mark(void)
    {
        if((*(__IO uint32_t*)LVD_MARK_ADDR) == 0x12345678) {
            // 清除标记
            fmc_unlock();
            fmc_page_erase(LVD_MARK_ADDR);
            fmc_lock();
            return 1;
        }
        return 0;
    }


    硬件调试建议

    使用可调电源:缓慢降低电压,观察LVD触发点
    添加LED指示:在LVD中断中点亮LED
    使用串口输出:在中断中通过串口发送消息(确保串口在低电压下仍能工作)


    检查LVD状态寄存器
    void check_lvd_status(void)
    {
        if(lvd_flag_get(LVD_FLAG_OUT) != RESET) {
            printf("当前电压低于LVD阈值\n");
        } else {
            printf("当前电压高于LVD阈值\n");
        }
    }


  • LVD阈值配置错误?

您需要登录后才可以回复 登录 | 注册