你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
huangxuejia-292 提问时间:2018-3-28 22:38 /
这几天在做SMT32F407 ADC转换功能,遇到一些个人觉得比较诡异的问题,抛出给大家看看,不知道哪位遇到过,盼指导。

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

  1. s32 mcu_adc_config_nvic(void)
  2. {
  3.         NVIC_InitTypeDef NVIC_InitStructure;
  4.        
  5.         NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;       
  6.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
  7.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;      //响应优先级
  8.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  9.     NVIC_Init(&NVIC_InitStructure);
  10. }

  11. /**
  12. *@brief:      mcu_adc_init
  13. *@details:    adc初始化,用于电阻触摸屏检测
  14. *@param[in]   void  
  15. *@param[out]  无
  16. *@retval:     static
  17. */
  18. void mcu_adc_init(void)
  19. {
  20.     ADC_InitTypeDef ADC_InitStructure;
  21.         ADC_CommonInitTypeDef ADC_CommonInitStructure;
  22.     GPIO_InitTypeDef GPIO_InitStructure;


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

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

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

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

  41.         mcu_adc_config_nvic();
  42.         ADC_ITConfig(ADC2,  ADC_IT_EOC, ENABLE);
  43.         ADC_ClearFlag(ADC2, ADC_FLAG_EOC);
  44.         ADC_Cmd(ADC2, ENABLE);

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


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


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


收藏 3 评论19 发布时间:2018-3-28 22:38

举报

19个回答
wudianjun2001 回答时间:2018-3-29 08:32:40
优化等级我都设置为0,否则老是出现问题,好多变量给优化的话,程序运行就不正常了

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

XinLiYF 回答时间:2018-3-29 08:57:35
KEIL-MDK优化设置.pdf (192.72 KB, 下载次数: 585)

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

XinLiYF 回答时间:2018-3-29 08:58:39

里面讲的很清楚。
板子粉丝 回答时间:2018-3-29 09:20:02
关注一下
zhao.zhao 回答时间:2018-3-29 09:54:49
一般和优化等级关系不大

评分

参与人数 1蝴蝶豆 +1 收起 理由
zero99 + 1

查看全部评分

无薪税绵 回答时间:2018-3-29 10:17:41
KEIL的优化,的确是会导致很多奇怪的问题。
所以,一般,我使用 局部优化 
#pragma OPTIMIZE(x)
来指定对某段代码的优化级别。

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

keil优化等级设置(指定函数的优化级别#pragma OPTIMIZE(x) ).pdf (209.06 KB, 下载次数: 327)

评分

参与人数 1蝴蝶豆 +4 收起 理由
zero99 + 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 收起 理由
zero99 + 2

查看全部评分

12下一页
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版