(1)用keil编辑STM32点灯---遇到灯常亮不闪烁的问题

本文介绍了使用STM32F047ZET6通过寄存器控制LED灯闪烁的程序编写过程,针对LED灯不闪烁的问题进行了调试,并找到了解决方案。问题主要由编译器优化级别设置不当和未正确使用volatile关键字引起。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:我自己装了MDK后,按照讲课老师讲解,编写了一个stm32通过寄存器控制LED灯闪烁的程序,结果发现led灯不闪烁,但是程序写的没问题啊,和视频中讲师的源码一模一样,但就是,运行不成功,led灯常亮,并没有闪烁。百思不得其解。后来发现是volatile的问题,和keil优化级别设置问题导致的。

我的keil工程优化级别的默认设置如下图:优化级别设置默认为-O1

优化级别设置默认为-O1

解决stm32点亮LED不闪烁问题方法有两个:
方法一:更改优化级别为-O0

方法二:while循环中出现的变量,定义时加上关键字volatile


/*
所用芯片---STM32F047ZET6
LED0 --->PF9---->GPIOF组的第9个引脚
LED_ON  ---0
LED_OFF ---1
寄存器设置套路,见参考手册
*/

#define RCC_BASEADDR       (0x40023800)
#define	RCC_AHB1ENR         (*( unsigned int *)(RCC_BASEADDR+0x30))


#define GPIOF_BASEADDR      (0x40021400)
#define GPIOF_MODER 		(*( unsigned int *)(GPIOF_BASEADDR+0x00)) //端口模式
#define GPIOF_OTYPE         (*( unsigned int *)(GPIOF_BASEADDR+0x04)) //输出类型
#define GPIOF_OSPEEDR       (*( unsigned int *)(GPIOF_BASEADDR+0x08)) //输出速度
#define GPIOF_PUPDR         (*( unsigned int *)(GPIOF_BASEADDR+0x0C)) //上下拉

#define GPIOF_ODR           (*(volatile unsigned int *)(GPIOF_BASEADDR+0x14))//输出控制,这里要加volatile,因为该变量出现在while循环中,有可能被编译器优化
	

 static void delay(volatile unsigned int ns) //这里要加volatile ,该变量出现在while循环中,有可能被编译器优化
{
	while(ns--);
}

int main(void)
{
	//1.使能F组时钟,必须操作以下这一步:开启 GPIOF 组时钟!!!
		RCC_AHB1ENR |= (unsigned int)(0x01<<5);
	//debug:如果时钟不使能的话,所有寄存器的值都不会改变

	//2.设置 PF9 引脚为输出模式
	GPIOF_MODER &= ~(unsigned int)(0x03<<9*2);
	GPIOF_MODER |= (unsigned int)(0x01<<9*2);	
	
	//3.配置 PF9 引脚的输出类型为:推挽输出
	
	GPIOF_OTYPE &= ~(unsigned int)(0x1<<9);
	
	//4.配置 PF9 引脚的输出速度为:25MHz  ,这个影响不大可以忽略
		GPIOF_OSPEEDR &= ~(unsigned int)(0x03<<9*2);
	    GPIOF_OSPEEDR |= (unsigned int)(0x01<<9*2);	
	
	//5.配置 PF9 引脚为上拉 ,这个影响不大可以忽略
	
	GPIOF_PUPDR &= ~(unsigned int)(0x03<<9*2);
	GPIOF_PUPDR |= (unsigned int)(0x01<<9*2);
	//输出
	
	//6、配置 PF9 引脚的输出数据寄存器的值,目的就是为了控制PF9引脚高低电平
	while(1)
	{
		GPIOF_ODR &= ~(unsigned int)(0x01<<9);//置0亮
		delay(0xFFFFF);
		GPIOF_ODR |= (unsigned int)(0x01<<9);//置1灭
		delay(0xFFFFF);	
	}
	
	
	
	return 0;
	
}

debug:没有勾选reset and run。发现下载完程序后不运行。
总结:当程序出现反常现象,说明有自己不知道知识,或有自己没有观察到的信息。要冷静,相信事出反常必有妖,冷静的进行程序的调试,敏锐细心的观察不寻常之处。当然,通过调试解决问题也需要知识和经验,当自己不知如何调试时,可以向身边懂得人请教,或者去百度搜索问题,问题描述要尽可能的包括关键信息,如自己通过什么代码编辑器,调试的是什么样的程序,现象等等。不把问题当回事,耐心,冷静面对。

针对查找有关野火霸道V2点亮D6 LED的相关信息,以下是整合后的指导内容: 为了实现野火霸道 V2 开发板上 D6 引脚控制LED亮起的功能,可以参考如下步骤配置和编程: 选择合适的开发环境 确保安装了适合STM32系列MCU的集成开发环境(IDE),例如Keil MDK、IAR Embedded Workbench或者使用CubeMX结合CLion等。 硬件连接确认 检查电路图以确定D6引脚是否直接连有一个LED。一般情况下,该LED可能串联一个限流电阻接地(GND)。如果D6确实用于驱动外部LED,则继续下一步;如果是,请根据实际接线调整代码中的GPIO设置。 初始化GPIO端口 利用官方提供的HAL库函数来设定D6对应的GPIO模式为输出。这可以通过CubeMX图形界面完成初步配置,之后生成项目框架代码。 编写主循环逻辑 在main()函数内的无限循环里加入必要的延时处理以及对目标GPIO电平状态的操作语句,比如`HAL_GPIO_TogglePin()`来回切换高低电平使LED闪烁,或是简单地将其设为高电平让其常亮。 编译并下载固件至设备 完成以上编码工作后,通过调试接口(如SWD/SWDIO)将最终版本的应用程序传输给微控制器执行即可看到预期效果。 若遇到困难或想要获取更详细的教程,建议访问CSDN博客或其他技术论坛寻找类似案例分享的文章阅读学习。此外,也可以查阅官方文档了解具体型号芯片的数据手册与应用笔记获得更多帮助和支持。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值