huangxuejia-292 发表于 2018-3-28 22:38:45

MDK优化等级问题--基于STM32F407

这几天在做SMT32F407 ADC转换功能,遇到一些个人觉得比较诡异的问题,抛出给大家看看,不知道哪位遇到过,盼指导。

用STM32F407的ADC采样触摸屏信号。
MDK 2级优化
在单独做ADC功能的时候,完全正常。
后面加入了其他功能,例如文件系统,SD卡驱动。
现象1
加入这些后,ADC读到的数据全部不对,理论上ADC最大就是4095,现在确能读出几万的值(ADC读回来的是U16)。
这时如果屏蔽一些代码,例如WM8978的代码,ADC又正常了。
就算不屏蔽代码,将优化等级改为0,也正常。
当时没有再深入处理。
现象2
到今天,决定解决这个问题。优化等级保留2。
多次调试后发现,只要把nvic配置直接放到adc初始化里面,从ADC读出来的数值就不对。只要单独封一个函数,在ADC初始化里面调用,就正常。

s32 mcu_adc_config_nvic(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
       
        NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;       
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;      //响应优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/**
*@brief:      mcu_adc_init
*@details:    adc初始化,用于电阻触摸屏检测
*@param   void
*@param无
*@retval:   static
*/
void mcu_adc_init(void)
{
    ADC_InitTypeDef ADC_InitStructure;
        ADC_CommonInitTypeDef ADC_CommonInitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);//使能ADC 时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使用GPIOB时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//---模拟模式
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//---不上下拉
    GPIO_Init(GPIOB, &GPIO_InitStructure);//---初始化 GPIO

        ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
        ADC_CommonInitStructure.ADC_TwoSamplingDelay =         ADC_TwoSamplingDelay_20Cycles;//两个采样阶段之间的延迟 5 个时钟
        ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA 失能
        ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;//预分频 6分频。
        ADC_CommonInit(&ADC_CommonInitStructure);//初始化

        ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12 位模式
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//非连续转换
        ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
        ADC_InitStructure.ADC_NbrOfConversion = 1;//1 个转换在规则序列中, 也就是说一次转换一个通道
        ADC_Init(ADC2, &ADC_InitStructure);//ADC 初始化

        mcu_adc_config_nvic();
        ADC_ITConfig(ADC2,ADC_IT_EOC, ENABLE);
        ADC_ClearFlag(ADC2, ADC_FLAG_EOC);
        ADC_Cmd(ADC2, ENABLE);

               
}用CMSIS DAP看了一下汇编,如果不封成函数的情况如下,出现两次重复(实际是不是重复,不确定,看不太懂),如果封成函数,就只有一次。
0x0800BC4C 9402      STR         r4,
    58:         ADC_InitStructure.ADC_NbrOfConversion = 1;//1 ¸öת»»ÔÚ¹æÔòÐòÁÐÖÐ, Ò²¾ÍÊÇ˵һ´Îת»»Ò»¸öͨµÀ
0x0800BC4E 9404      STR         r4,
    59:         ADC_Init(ADC2, &ADC_InitStructure);//ADC ³õʼ»¯
    60:
0x0800BC50 4C09      LDR         r4,; @0x0800BC78
    58:         ADC_InitStructure.ADC_NbrOfConversion = 1;//1 ¸öת»»ÔÚ¹æÔòÐòÁÐÖÐ, Ò²¾ÍÊÇ˵һ´Îת»»Ò»¸öͨµÀ
0x0800BC52 F88D5014STRB          r5,
    59:         ADC_Init(ADC2, &ADC_InitStructure);//ADC ³õʼ»¯

现象3
请教下面两种写法对代码编译优化有什么影响?
代码1,功能正常
s32 dev_touchscreen_init(void)
{
        return dev_ts_adc_init();
}代码2,功能不正常
s32 dev_touchscreen_init(void)
{
        dev_ts_adc_init();
        return 0;
}

通常我们要的优化问题,都是变量被优化,只要加上volatile就解决问题了。
这些几个问题比较困惑。
不知是否有对优化比较熟悉的朋友指点一二。
先谢!


wudianjun2001 发表于 2018-3-29 08:32:40

优化等级我都设置为0,否则老是出现问题,好多变量给优化的话,程序运行就不正常了

XinLiYF 发表于 2018-3-29 08:57:35






XinLiYF 发表于 2018-3-29 08:58:39

XinLiYF 发表于 2018-3-29 08:57


里面讲的很清楚。

板子粉丝 发表于 2018-3-29 09:20:02

关注一下

zhao.zhao 发表于 2018-3-29 09:54:49

一般和优化等级关系不大

无薪税绵 发表于 2018-3-29 10:17:41

KEIL的优化,的确是会导致很多奇怪的问题。
所以,一般,我使用 局部优化 
#pragma OPTIMIZE(x)
来指定对某段代码的优化级别。

不同的代码,使用不同的优化级别。
使用方法,见付件第4页。


huangxuejia-292 发表于 2018-3-29 10:37:49

zhao.zhao 发表于 2018-3-29 09:54
一般和优化等级关系不大

请指教,特别现象3,实在想不明白。

huangxuejia-292 发表于 2018-3-29 10:38:31

XinLiYF 发表于 2018-3-29 08:58
里面讲的很清楚。

感谢

zhao.zhao 发表于 2018-3-29 10:48:45

这个具体讲不清,只能这么说,程序要写得尽可能符合ANSI C的规范,警告尽量消除掉,当然有时警告也不碍事,但有时会不好的结果。如果警告多了,再提高优化等级就可能出问题
页: [1] 2
查看完整版本: MDK优化等级问题--基于STM32F407