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

[复制链接]
360|14
小熊猫123 发表于 2025-10-27 16:23 | 显示全部楼层 |阅读模式
①测试程序里给外部flash写1A,LVD中断里写3C,烧录后重新开机,再去仿真,值还是1A啊,这是没进LVD中断?
VCC从3.3v到2.6v也有几毫秒也够了吧?
②还有LVD中断咋仿真啊?仿真状态下关电源仿真也断了……
stormwind123 发表于 2025-10-27 16:45 | 显示全部楼层
LVD阈值配置错误?

评论

已经是最高的3.1v了  发表于 2025-10-28 09:01
classroom 发表于 2025-10-27 17:46 | 显示全部楼层
是不是中断未使能
cr315 发表于 2025-10-27 19:46 | 显示全部楼层
在中断服务函数中调用exti_interrupt_flag_clear(EXTI_16)清除标志。
duo点 发表于 2025-10-27 20:47 | 显示全部楼层
仿真时若直接关闭电源,仿真器会断开连接,导致无法观察中断行为。
sunjd 发表于 2025-10-27 16:48 | 显示全部楼层

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

可能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");
    }
}


psx09 发表于 2025-10-28 10:33 | 显示全部楼层
坐等大神指导,一起学习学习
dffzh 发表于 2025-10-28 10:52 | 显示全部楼层
本帖最后由 dffzh 于 2025-10-28 10:56 编辑

用直流稳压可调电源给板子供电,然后手动从3.3V慢慢下降,看会不会进入LVD中断?这种电压下降速度慢,如果LVD中断的程序配置正常,应该会进中断;先排查LVD中断,再排查flash写入问题。

评论

因为开发版和自己板子cpu外围电路不一样  发表于 2025-10-28 11:18
好的,我试试,我早上用开发版烧官方历程,额外供电从3.3降到2.8v,我仿真里看是进中断的。然后同样的程序烧现在自己的CPU,发现降了电压却没有进中断,这情况是不是硬件上问题啊,vdd/vdda问题?   发表于 2025-10-28 11:18
dffzh 发表于 2025-10-28 11:25 | 显示全部楼层
从你的对比测试结果来看,问题确实偏向硬件;那你把自己的LVD部分的程序烧写到开发板上测试是什么结果?可以试试。

评论

官方例程对了,我自己程序里就直接抄官方例程的了,现在还是先找硬件上不同了,开发板vdd和3.3v都引出来的,自己的CPU板得看看怎么引出来量了  发表于 2025-10-28 13:33
dffzh 发表于 2025-10-28 14:20 | 显示全部楼层
这个检测逻辑应该就只是用VDD来和你设置的低电压阈值进行比较,逻辑也不复杂,你可以仿真读取一下下面这个寄存器的LVDF位,看有木有变成1:

338286900603c78605.png
221856900604c9f122.png
你设置的电压应该是2.9V吧:
283916900609492e70.png
dffzh 发表于 2025-10-28 14:21 | 显示全部楼层
用示波器监测一下电压下降时VDD和3.3V的变化情况也是正确的分析思路。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

14

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部