1.原因源于大家平时对网上大量不规范的例程的拷贝使用
2.比如在配置定时器输出pwm时候,一般网上抄的例程如下:
//4、初始化输出比较模式、配置输出比较模式的结构体参数
TIM_OCStructInit(&TIM_OCInitStruct);//配置输出比较结构体的参数
TIM_OCInitStruct.TIM_Pulse=50; //配置CCR寄存器,控制占空比
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; //配置输出比较模式
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;//控制输出的极性
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;//输出使能
TIM_OC1Init(TIM2,&TIM_OCInitStruct);
这里是有问题的,因为结构体TIM_OCInitStruct的成员不止这几个,如果不写全,那其他几个的值是栈里面的数据,栈数据是之前的函数执行后留下的,这样其他几个没写出来的成员就成了栈污染的受害者了。此时如果就这么初始化了,有时候会出现奇怪的BUG:比如通道关闭后IO仍然维持高电平。
3.正确的做法, 写全所有的结构体成员 :
//初始化TIM8 Channel3 PWM模式
/*
在PWM模式(模式1或模式2)下, TIMx_CNT和TIMx_CCRx始终在进行比较,
(依据计数器的计数方向)以确 定是否符合TIMx_CCRx≤TIMx_CNT或者TIMx_CNT≤TIMx_CCRx。
*/
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputState_Disable; //所有成员初始化,否则数据不确定
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High; //所有成员初始化,否则数据不确定
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; //所有成员初始化,否则数据不确定
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
// TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //输出空闲状态是互补输出和死区插入那一节里面的知识,这里没影响
TIM_OCInitStructure.TIM_Pulse=0;
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //根据指定的参数初始化外设TIM8 OC3
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH1预装载使能,预装载值在更新事件到来时被加载至当前寄存器中
4.辩论:
1)不明写,编译器也会给局部变量赋为0
答:
(1)或许有的编译器会将未幅值的局部变量赋0,但不能保证每个编译器都这么做。总之未幅值其值是不确定的(很容易验证:搞两个函数执行打印一下实测出来)
(2)在单片机程序里面,没写的寄存器不等于就是要赋0,所以即使编译器帮忙赋0了,也是不对的
2)可以用类似stm32单片机库函数中的deinit规避栈污染
答:
deinit只是将寄存器的值恢复到默认,不能清栈数据。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
寄存器
+关注
关注
31文章
5357浏览量
120639 -
PWM
+关注
关注
114文章
5193浏览量
214211 -
定时器
+关注
关注
23文章
3251浏览量
115005 -
STM32单片机
+关注
关注
59文章
549浏览量
58741
发布评论请先 登录
相关推荐
esp32调试MQTT的程序,如何对.host初始化?
esp_mqtt_client_config_t mqtt_cfg这个结构体的时候,你们例程里面只初始化url,但是我在网上看到很多地方的参考程序都是初始化这些
发表于 06-11 07:55
QT解决串口数据接收不完整问题
1. 相关文章汇总(1)QT解决串口数据接收不完整问题(貌似贴出的代码可以存下串口接受的全部数据)(2)qt中使用串口类接收数据不完整 (3)Qt5.7串口接收数据不完整因为串口本来就不是一次接收
发表于 08-18 06:58
【原创分享】变量的初始化技巧
,第二种使用对结构体成员变量赋值的方式。实质上,第1种方式编译器将自动生成一些指令完成变量a的初始化,而第2种方式编译器在处理Score a语句的时候只需要开辟
发表于 09-08 15:28
Keil使用结构体数组的奇怪问题相关资料下载
今天用keil的时候发现一个很奇怪的点,是关于结构体数组的。首先说明我的keil版本是:V5.28.0.0问题是这样的:我在a.h文件定义了一个结构
发表于 11-30 06:47
怎样去解决stm32串口DMA数据接收不完整的问题呢
stm32串口DMA数据接收不完整问题说明最近做了一个项目需要用串口来接收模块端的应答数据,由于使用了实时操作系统,考虑中断嵌套或被打断的问题导致数据接收不完整的问题,使用串口dma接收数据,但
发表于 02-21 06:19
结构体数组的初始化
char i; TEST data1[5] = {{1,2},{3,4},{5,6},{7,8},{9,10}};//经常使用的初始化方式TEST data2[5] ={0};//初始全为0,否则
发表于 05-21 15:24
FAQ0066结构体成员未完全初始化导致程序异常的解决方法
使用非官方程序,由于某些外设驱动在配置结构体时,未完全初始化所有成员,导致程序运行异常。以 FSMC 为例,FSMC_NORSRAMInit
发表于 10-20 06:59
结构体的定义、初始化和赋值
type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为
发表于 11-20 09:29
•5.5w次阅读
在51平台下初始化文件的引入导致全局变量无法初始化的问题如何解决
本文档的主要内容详细介绍的是在51平台下初始化文件的引入导致全局变量无法初始化的问题如何解决。
发表于 08-20 17:31
•0次下载
Keil使用结构体数组的奇怪问题
今天用keil的时候发现一个很奇怪的点,是关于结构体数组的。首先说明我的keil版本是:V5.28.0.0问题是这样的:我在a.h文件定义了一个结构
发表于 11-21 16:36
•3次下载
stm32串口DMA数据接收不完整问题说明
stm32串口DMA数据接收不完整问题说明最近做了一个项目需要用串口来接收模块端的应答数据,由于使用了实时操作系统,考虑中断嵌套或被打断的问题导致数据接收不完整的问题,使用串口dma接收数据,但
发表于 12-24 19:37
•21次下载
浅谈C语言中的三种不完整类型
不完整类型(Incomplete types)是缺少足够信息来确定该类型对象大小的对象类型,不完整类型可以在翻译单元的某些点完整。
发表于 12-16 09:52
•515次阅读
如何获取ChatGPT回答不完整的内容
____tz_zs 对于 ChatGPT 回答不完整的情况(篇幅限制,没有说完),可以输入“继续”指令,让其继续回答下去,获得完整内容。 如下图,发问 “使用web3js 调用 eth链智能合约” 直到这里才是获得了刚刚问题 “使用web3js 调用 eth链智能合约”
发表于 02-10 10:48
•0次下载
评论