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

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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版