打印
[应用相关]

在线调试时运行代码正确、关闭重启电源代码运行不正确

[复制链接]
676|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gwsan|  楼主 | 2021-9-6 14:08 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
上电时电压小于芯片POR电平,导致在线调试时运行代码正确重启电源代码运行不正确,通过在初始化前面加适当延时解决.

一、BUG现象
项目换了平台,移植代码的时候,现象是:

1、STM32板子烧写程序之后,重启电源,程序运行现象与预期的不符合;

2、为了排除重启电源板子没有复位,在进入主函数开始增加软件复位,测试结果和1一致;

3、使用Keil软件在线调试Dubug,程序运行符合预期,PB1和TXCAN均有正常波形输出。


使用特权

评论回复
沙发
gwsan|  楼主 | 2021-9-6 14:08 | 只看该作者
二、测试代码和硬件原理图
运行的代码框架如下,首先初始化SPI3,再通过SPI3控制芯片MCP2517初始化,在主循环里面,每过20ms翻转一次PB1,并通过SPI控制MCP2517发送一次数据。

int main(void)
{   
    MX_SPI3_Init();    //SPI3控制CANFD芯片MCP2517            
    CANFDSPI_Init();   //初始化CAN FD
    while(1)
    {
        HAL_Delay(20);    //延时20ms
        GPIO_PB1_CHANGE();//翻转PB1引脚查看程序是否在运行
        test_fdcan_send();//测试CANFD发送
    }

}
硬件原理图如图1所示,STM32通过SPI3控制MCP2517


图1
预期的现象是烧写程序后:测试PB1引脚每20ms翻转一次,在MCP2517的1Pin-TXCAN1可以测试到发送的波形,但是重启电源发现只能测试到PB1引脚的波形20ms翻转一次(说明代码运行到主函数,刚开始猜想重启电源不能使代码运行,只有Debug才能使代码运行,但是重启电源和Debug都是复位板子,并且重启电源测试到了PB1翻转说明板子在运行,所以这个猜想排除掉),在TXCAN引脚并没有测试到发送的数据,到此确定为是CANFDSPI_Init(); 的问题。首先这个初始化代码是之前已经验证过的,经过对比分析,之前的代码里因为在SPI初始化之后CANFDSPI_Init();之前加了500ms的延时所以可以正常工作,难道是不加延时MCP2517上电启动时间比STM32慢,导致在运行CANFDSPI_Init();代码的时候,MCP2517并没有处于工作状态。所以更改代码,在SPI初始化后,CANFDSPI_Init();前面,增加100ms延时(500ms太多了,3V3的上电时间预估没有那么慢)。重启电源重新测试TXCAN引脚,测试到了预期波形,问题解决。

int main(void)
{   
    MX_SPI3_Init();    //SPI3控制CANFD芯片MCP2517
    HAL_Delay(100);    //延时100ms,用以MCP2517上电启动            
    CANFDSPI_Init();   //初始化CAN FD
    while(1)
    {
        HAL_Delay(20);    //延时20ms
        GPIO_PB1_CHANGE();//翻转PB1引脚查看程序是否在运行
        test_fdcan_send();//测试CANFD发送
    }

}


使用特权

评论回复
板凳
gwsan|  楼主 | 2021-9-6 14:09 | 只看该作者
三、故障复现
通过增加延时,解决问题之后,我们回到开始发现不加延时是怎么导致BUG出现的,并出现了重启电源和增加软件复位不可以的原因:都是因为上电时序,上电启动时间没有设置好导致的。而在线Debug可以的原因:因为在线Debug的时候,STM32和MCP2517都已经上电一定的时间,此时板子各个模块都已经启动完毕,再进行Debug的时候,运行CANFDSPI_Init();代码时,MCP2517已经启动完毕(主要是图1中VDD_MCP2517,是3V3,和STM32的3V3来自于同一个地方,因为两个模块使用同一电压,并没有上电时序这一说法,只能是两个芯片的POR电压不一致)。查看MCP2517数据手册和STM32H743数据手册,查看两个器件的POR电平,发现MCP2517的。

首先查看MCP2517数据手册如图2所示。对于VDD的描述是RAM数据保留(即RAM可以用的最小电压是2.7V,CANFDSPI_Init是需要对芯片的RAM进行操作的),V-PORH的最大电压是2.65V,V-PORI的最小电压是2.2V;所以MCP2517正常工作的电压是2.7V。



图2
STM32H743的POR电平为1.67V,但是需要加上t-RSTTEMPO时间377us(结合图3和图4),所以去推导STM32开始运行的时间不合适,需要考虑的额外时间太多(晶振、硬件初始化等),所以最好是实测在运行某行代码的时候,3V3上升到几V更为合适,具体测试方法对应的代码见第四部分。


图3

图4
测试了3V3电源的上电时间,从0V到3V3的时间大概为10ms如图5所示。


图5


使用特权

评论回复
地板
gwsan|  楼主 | 2021-9-6 14:10 | 只看该作者
四、优化延时时间
延时100ms保证了在运行代码CANFDSPI_Init的时候,MCP2517一定是准备好的。为了减少板子的上电初始化时间做了下面的工作。因为STM32和MCP2517都是使用3V3,对于MCP2517,只要3V3电源上升到2.7V即可正常工作(POR电压为2.65V),对于STM32的POR电压为1.67V。针对这一个BUG,解决方法的核心是:在运行代码CANFDSPI_Init的时候,3V3的电压一定要上升到2V7以上,这样子才能完成对MCP2517的初始化。

与其推导加多少延时,MCP2517可以正常工作,不妨进行验证,延迟xms时,运行到CANFDSPI_Init时,VDD_MCP2517的电压为为多少。确定了方案之后进行多次测试,发现不延时异常,加延时1ms正常。

首先测试加延时1ms,运行改行代码时,3V3的电源上升到电压多少。代码如下,使用示波器触发功能触发PB2,下降沿触发,同时测试3V3。加1ms延时测试到的VDD_MCP2517结果如图6,电压为2.88V>2.7V,所以可以正常工作。

int main(void)
{   
    MX_GPIO_Init();    //GPIO初始化,PB1和PB2默认输出低
    MX_SPI3_Init();    //SPI3控制CANFD芯片MCP2517
    PB2_Low();         //拉高PB2
    HAL_Delay(1);      //延时1ms
    CANFDSPI_Init();   //初始化CAN FD
    while(1)
    {
        HAL_Delay(20);    //延时20ms
        GPIO_PB1_CHANGE();//翻转PB1引脚查看程序是否在运行
        test_fdcan_send();//测试CANFD发送
    }
}
图6

  注释掉延时1ms,此时重启电源后,MCP2517不能正常工作,测试结果如图7所示,VDD_MCP2517的电平为2.52V<2.7V,所以不正常。

int main(void)

{   

    MX_GPIO_Init();    //GPIO初始化,PB1和PB2默认输出低

    MX_SPI3_Init();    //SPI3控制CANFD芯片MCP2517

    PB2_Low();         //拉高PB2

    //HAL_Delay(1);    //延时1ms

    CANFDSPI_Init();   //初始化CAN FD

    while(1)

    {

        HAL_Delay(20);    //延时20ms

        GPIO_PB1_CHANGE();//翻转PB1引脚查看程序是否在运行

        test_fdcan_send();//测试CANFD发送

    }

}



使用特权

评论回复
5
gwsan|  楼主 | 2021-9-6 14:10 | 只看该作者
五、总结
1、对于STM32使用CUBE生成的,这部分不需要考虑上电时间的问题,对于其他模块的初始化需要增加测试在运行初始化代码的时候,芯片供电电压是否达到了最低要求,测试方法就是使用触发测试,测试代码可以参考第四部分的代码

2、在调试另外一个模块时,STM32使用了外部基准源,在初始化的时候需要对内部ADC进行校准,也发现了重启电源ADC测试不对,在线调试的时候ADC测试是正确的现象。可以归结为一类问题,就是重启电源代码运行不正确,在线调试时OK的,都可以从上电初始化太快,导致芯片供电还没有上升到最小阈值,就运行了初始化代码,导致初始化失败;在线调试的时候,因为已经上电很长时间,DEBUG了之后,运行对应代码的时候芯片供电是正常的。

3、因为MCP2517的供电是3V3,而3V3的上电时间大概是10ms,就上电到90%以上,我们不能卡着1ms的时间去延时,为了保证代码一定可以正常运行,增加延时到10ms。这个只是针对MCP2517,对于其他的模块,如果也是3V3供电,其实大可不必每个模块的延时时间都测试,只用关注3V3电源的上电时间t-3V3,统一加一个延时,这个延时略微大于t-3V3即可保证所有3V3供电的模块都正常,如果还有其他电压类型,对应的测试其上电时间,统一加延时。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

3426

帖子

1

粉丝