STM8SPWM應用
前幾天有個項目用到PWM,今天整理下,弄個氛圍燈;記錄下,以後忘記了返回來還能看看。
思路就是在硬件端設置個按鍵,按下全局變量Key_num的值+1,按鍵一開始我用輪詢法做的,後來覺得輪詢法延時可能導致未知的問題,現在用中斷法做;根據Key_num的值,用switch語句選擇要變換的模樣。
上代碼:
/*****************************************************************************
* @function : Tim2_Init
* @brief : TIM2初始化函數 CH1用作出LED——G的呼吸變化燈
* @note : STM8S005
* @param : null
* @retval : null
* @author : 2016.03.23 by Steam.Yang
2016.11.02 RPP 學習並增加註釋
******************************************************************************/
void Tim2_Init(void) //TIM2的初始化語句們
{
//配置通道1
TIM2_TimeBaseInit(TIM2_PRESCALER_8, 999); //第一步配置時基單元,先設置預分頻PSCRH/L高低八位 寄存器,再設置自動裝載寄存器ARRH/L。
TIM2_OC1Init(TIM2_OCMODE_PWM1,
TIM2_OUTPUTSTATE_ENABLE,
0,
TIM2_OCPOLARITY_LOW); //然後配置通道的輸出模式爲PWM,啓用輸出比較,佔空比設置爲0,輸出爲低電平
TIM2_OC1PreloadConfig(ENABLE);
TIM2_Cmd(ENABLE);
//配置通道2
TIM2_TimeBaseInit(TIM2_PRESCALER_8, 999); //第一步配置時基單元,先設置預分頻PSCRH/L高低八位 寄存器,再設置自動裝載寄存器ARRH/L。
TIM2_OC2Init(TIM2_OCMODE_PWM1,
TIM2_OUTPUTSTATE_ENABLE,
0,
TIM2_OCPOLARITY_LOW); //然後配置通道的輸出模式爲PWM,啓用輸出比較,佔空比設置爲0,輸出爲(低電平).105s4是低電平點亮
TIM2_OC2PreloadConfig(ENABLE); //開啓預裝載寄存器
TIM2_Cmd(ENABLE); //最後的開啓 啓用定時器
//配置通道3
TIM2_TimeBaseInit(TIM2_PRESCALER_8, 999); //第一步配置時基單元,先設置預分頻PSCRH/L高低八位 寄存器,再設置自動裝載寄存器ARRH/L。
TIM2_OC3Init(TIM2_OCMODE_PWM1,
TIM2_OUTPUTSTATE_ENABLE,
0,
TIM2_OCPOLARITY_LOW); //然後配置通道的輸出模式爲PWM,啓用輸出比較,佔空比設置爲0,輸出爲低電平
TIM2_OC3PreloadConfig(ENABLE);
TIM2_Cmd(ENABLE);
}
這段代碼爲PWM初始化代碼,被折騰了好幾天,手頭上的105S4跟別人就是不一樣,他非要低電平點亮小燈。。。。,心累這段代碼比較重要。
下面的是主函數
int main( void )
{
CLK_HSICmd(ENABLE); //配置個時鐘先
GPIO_Init(GPIOC, GPIO_PIN_7, GPIO_MODE_IN_PU_NO_IT);//初始化按鍵的GPIO口 上拉輸入
Tim2_Init(); //再初始化TIM2 PWM1輸出模式
while(1)
{
Key_Press(); //再調用按鍵
//再給PWM呼吸燈佔空比的值
if((!sta) && (PWM<1000)) //比較好的循環
{
PWM++;
if(PWM == 1000) sta = 1;
}
if((sta) && (PWM>0))
{
PWM--;
if(PWM == 0) sta = 0;
}
Delay_Us(500); //延時調整呼吸的速度
switch(Key_num){
case 0: //沒有按下 或者按到第7下時 全滅,進行清零
TIM2_SetCompare1(0);
TIM2_SetCompare2(0);
TIM2_SetCompare3(0);
break;
case 1:
TIM2_SetCompare1(1000); //按第一下,計數1, W燈常亮1 (1000常亮 PWM呼吸 0關閉)
break;
case 2: //按第二下,計數2,W燈呼吸2
//TIM2_Cmd(DISABLE);//本來想關掉PWM來進行關閉燈亮,結果不能關,關了後面就不執行了 要重新做初始化 要做其他處理
TIM2_SetCompare1(PWM);
break;
case 3:
TIM2_SetCompare1(0);
TIM2_SetCompare2(1000); //按三下,計數3,G燈常亮 ,同時要關掉前面亮着的
break;
case 4: //按四下,計數4,G燈呼吸
TIM2_SetCompare2(PWM); //
break;
case 5:
TIM2_SetCompare2(0); //按第五下,計數5,B燈常亮
TIM2_SetCompare3(1000); //
break;
case 6: //按第六下,計數6,B燈呼吸
TIM2_SetCompare3(PWM); //
break;
case 7: //全呼吸
TIM2_SetCompare1(PWM);
TIM2_SetCompare2(PWM);
`
TIM2_SetCompare3(PWM);
}
}
}
PWM不能關 關了就要重新初始化,所以選變成0 他就不亮了。這個循環結構是非常好的循環結構,很多書上的循環結構都是從0-100 沒有100-0 燈呼吸很突兀,所以建議用這種。
中斷的按鍵函數
放在中斷裏面
if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_7) == 0) { delay_us(5000); //去抖延時 if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_7) == 0) { while(GPIO_ReadInputPin(GPIOC, GPIO_PIN_7) == 0); Key_num++; if(Key_num == 2) { Key_num=0; } } }
寫完了,有什麼再補充吧,
吐槽這鬼編譯器,噁心 好幾次都代碼上不去
補充:
我師父教我的 哈哈
首先該計數器,循環技術,例如從0到ARR,那麼這個ARR就決定了PWM的週期,
PWM週期=(ARR+1)*計數器時鐘的週期.
PWM頻率=計數器時鐘的頻率/(ARR+1)
在計數器模塊中還有一個比較器,比較器有兩個輸入,一個是計數器的當前值,另一個是可以設置的數,這個數來着一個比較寄存器.當計數器的值小於比較寄存器的值時,輸出爲1(也可以是0),當計數器的值大於或者等於比較器寄存器的值時,輸出爲0(也可以是1,與前面對應).
STM8–PWM初始化流程
1、時基初始化,得出PWM的頻率(週期)
2、初始化輸出比較通道,確定是哪個模式、通道、脈衝寬度(確定佔空比)、和電平。
3、輸出比較通預裝載使能
4、允許主輸出(TIM1)
5、使能定時器
隨時改變PWM頻率:
void TIM1_SetAutoreload(uint16_t Autoreload);//設置自動重裝寄存器的值
隨時改變佔空比:
TIM1_SetCompare1(0x0000);//設置捕獲比較寄存器的值