1.原因源于大家平時(shí)對(duì)網(wǎng)上大量不規(guī)范的例程的拷貝使用
2.比如在配置定時(shí)器輸出pwm時(shí)候,一般網(wǎng)上抄的例程如下:
//4、初始化輸出比較模式、配置輸出比較模式的結(jié)構(gòu)體參數(shù)
TIM_OCStructInit(&TIM_OCInitStruct);//配置輸出比較結(jié)構(gòu)體的參數(shù)
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);
這里是有問(wèn)題的,因?yàn)榻Y(jié)構(gòu)體TIM_OCInitStruct的成員不止這幾個(gè),如果不寫全,那其他幾個(gè)的值是棧里面的數(shù)據(jù),棧數(shù)據(jù)是之前的函數(shù)執(zhí)行后留下的,這樣其他幾個(gè)沒(méi)寫出來(lái)的成員就成了棧污染的受害者了。此時(shí)如果就這么初始化了,有時(shí)候會(huì)出現(xiàn)奇怪的BUG:比如通道關(guān)閉后IO仍然維持高電平。
3.正確的做法, 寫全所有的結(jié)構(gòu)體成員 :
//初始化TIM8 Channel3 PWM模式
/*
在PWM模式(模式1或模式2)下, TIMx_CNT和TIMx_CCRx始終在進(jìn)行比較,
(依據(jù)計(jì)數(shù)器的計(jì)數(shù)方向)以確 定是否符合TIMx_CCRx≤TIMx_CNT或者TIMx_CNT≤TIMx_CCRx。
*/
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputState_Disable; //所有成員初始化,否則數(shù)據(jù)不確定
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High; //所有成員初始化,否則數(shù)據(jù)不確定
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; //所有成員初始化,否則數(shù)據(jù)不確定
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //選擇定時(shí)器模式:TIM脈沖寬度調(diào)制模式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; //輸出空閑狀態(tài)是互補(bǔ)輸出和死區(qū)插入那一節(jié)里面的知識(shí),這里沒(méi)影響
TIM_OCInitStructure.TIM_Pulse=0;
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //根據(jù)指定的參數(shù)初始化外設(shè)TIM8 OC3
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH1預(yù)裝載使能,預(yù)裝載值在更新事件到來(lái)時(shí)被加載至當(dāng)前寄存器中
4.辯論:
1)不明寫,編譯器也會(huì)給局部變量賦為0
答:
(1)或許有的編譯器會(huì)將未幅值的局部變量賦0,但不能保證每個(gè)編譯器都這么做。總之未幅值其值是不確定的(很容易驗(yàn)證:搞兩個(gè)函數(shù)執(zhí)行打印一下實(shí)測(cè)出來(lái))
(2)在單片機(jī)程序里面,沒(méi)寫的寄存器不等于就是要賦0,所以即使編譯器幫忙賦0了,也是不對(duì)的
2)可以用類似stm32單片機(jī)庫(kù)函數(shù)中的deinit規(guī)避棧污染
答:
deinit只是將寄存器的值恢復(fù)到默認(rèn),不能清棧數(shù)據(jù)。
-
寄存器
+關(guān)注
關(guān)注
31文章
5363瀏覽量
120918 -
PWM
+關(guān)注
關(guān)注
114文章
5196瀏覽量
214522 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3255瀏覽量
115158 -
STM32單片機(jī)
+關(guān)注
關(guān)注
59文章
549瀏覽量
58760
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論