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文章
5588浏览量
129057 -
PWM
+关注
关注
116文章
5847浏览量
223787 -
定时器
+关注
关注
23文章
3360浏览量
121734 -
STM32单片机
+关注
关注
59文章
553浏览量
60309
发布评论请先 登录
定义IO初始化结构体
esp32调试MQTT的程序,如何对.host初始化?
QT解决串口数据接收不完整问题
【原创分享】变量的初始化技巧
怎样去解决stm32串口DMA数据接收不完整的问题呢
结构体数组的初始化
FAQ0066结构体成员未完全初始化导致程序异常的解决方法
结构体的定义、初始化和赋值
在51平台下初始化文件的引入导致全局变量无法初始化的问题如何解决
Keil使用结构体数组的奇怪问题
stm32串口DMA数据接收不完整问题说明

结构体成员初始化不完整从而受到栈污染导致奇怪bug
评论