Keil5中写的软件延时函数不起作用现象解析

您所在的位置:网站首页 写作用的电脑软件 Keil5中写的软件延时函数不起作用现象解析

Keil5中写的软件延时函数不起作用现象解析

2023-07-12 11:05| 来源: 网络整理| 查看: 265

一、问题描述

在学习野火霸天虎F407寄存器点亮LED时,出现实验现象:LED灯不亮,野火霸天虎F407资料。 在这里插入图片描述

main.c代码如下:

#include "stm32f4xx.h" void Delay(unsigned int count); int main(void) { #if 0 /* 第一步:开启GPIO端口的时钟 */ /* 打开GPIOF端口的时钟 */ *(unsigned int *)(0x40023800+0x3f0) |= (1 for(;count!=0;count--); } void SystemInit(void) { /* 函数体为空,目的是为了骗过编译器不报错 */ } /* 1-把其他两个灯也点亮 2-实现三个灯闪烁(时间的控制使用软件延时) */ 二、问题分析

通过分析main.c代码,导致出现上述现象的间接原因是延时函数没有起作用。检查延时函数的实现代码,并没有错误。这不禁使我想起《程序员的自我修养——链接、装载、库》一书所提到的程序源代码经过预编译-》编译-》汇编-》链接,所以极大可能是编译器在编译过程中优化掉了我的延时函数,使得整个程序不能按照预定功能实现。

打开keil5的调试功能,查看对应main.c的反汇编文件: 经过优化的delay函数: 在这里插入图片描述 未经过优化的delay函数: 在这里插入图片描述 优化之后的 delay 函数没有for循环延时操作,因此失去延时的效果。

三、问题解决 3.1 降低ARM Compiler version

在Target设置界面下,Code Generation默认的是ARM Compiler version 6。 在这里插入图片描述 将ARM Compiler version 6改为ARM Compiler version 5即可。在这里插入图片描述

3.2 volatile关键字修饰

volatile关键字影响编译器编译的结果,用volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错。volatile关键字最通俗的解释是,告诉编译器这个变量我有其他用,不要给我随便优化掉。

原延时函数

//延时函数 void Delay(unsigned int count) { for(;count!=0;count--); }

添加volate关键字修饰

//延时函数 void Delay(volatile unsigned int count) { for(;count!=0;count--); }

推荐使用方法2,原因如下:

1.自定义延时函数中使用 volatile 去声明 val 变量可以解决编译器优化带来的延时失效问题; 2.编译器优化可以使代码更加精炼,执行效率更高。

参考资料

1. Keil AC5 和 AC6的一些区别 2. 编译器优化对自定义延时程序的影响(volatile详解实验一) 3. C语言丨深入理解volatile关键字



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3