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就解决问题了。
这些几个问题比较困惑。
不知是否有对优化比较熟悉的朋友指点一二。
先谢!
优化等级我都设置为0,否则老是出现问题,好多变量给优化的话,程序运行就不正常了
XinLiYF 发表于 2018-3-29 08:57
里面讲的很清楚。 关注一下 一般和优化等级关系不大 KEIL的优化,的确是会导致很多奇怪的问题。
所以,一般,我使用 局部优化
#pragma OPTIMIZE(x)
来指定对某段代码的优化级别。
不同的代码,使用不同的优化级别。
使用方法,见付件第4页。
zhao.zhao 发表于 2018-3-29 09:54
一般和优化等级关系不大
请指教,特别现象3,实在想不明白。 XinLiYF 发表于 2018-3-29 08:58
里面讲的很清楚。
感谢 这个具体讲不清,只能这么说,程序要写得尽可能符合ANSI C的规范,警告尽量消除掉,当然有时警告也不碍事,但有时会不好的结果。如果警告多了,再提高优化等级就可能出问题
页:
[1]
2