用過stm32定時器的朋友都知道,定時器的CCR寄存器,能夠用來配置PWM的輸出,但一樣也能夠用來配置spwm。廢話很少說,直接上代碼。算法
首先,你得考慮一下幾個因素:異步
1.同步調製仍是異步調製。函數
2.載波比N設置爲多少3d
3.spwm計算法blog
4.prescaler和period的值同步
5.改變CCR仍是改變ARRit
下面是程序的大體狀況:io
1.使用同步配置
2.載波比設置爲N = 360遍歷
3.採用對稱規則採樣法
4.經過中斷時實改變CCR的值
5.使用stm32f429,它的高級定時器時鐘頻率爲180M(不分頻的狀況下)
6.計數器採用遞增遞減的方式技術
——————————————————————————————————————————
1.GPIO的複用
使用了TIM8_CH1和TIM8_CH1N,兩個引腳。
這兩個腳是複用功能,因此在配置GPIO口的時候,要調用
這段代碼在GPIO配置以前,仍是GPIO_Init()以後都沒有太大的影響。
2.ARR值與CCR
定義計數頻率,TIM_CLk,和濾波後正弦波的頻率,Sin_F那麼
prescaler = 定時器計數頻率 / TIM_CLK - 1;
period = TIM_CLK / (2*Sin_F *N) - 1;
3.定時器計數方式的設定
不要死記什麼TIM_CountMode_CenterAligned1,等,每款板子可能不同。
在這塊stm32f4的板子上面,CMS = 01 ,對應定時器遞減計數的時候,當計數的值等於CCR的值時,就觸發中斷,查看對應的寄存器
4.中斷函數的處理
首先進行中斷向量表的配置,這你們都會吧
根據對稱規則採樣的公式 D = 載波的週期 / 4 *(1 - 調製比 * sin(x)).
這裏將sin(x)離散化處理,由於sin函數的值是小於1的,因此Sin_Tab[]應該是float或者double型
若是正弦波的週期定了,那麼載波的定時器的週期也定了,參考下面的函數,
float n1_RET(float Sin_F)
{
static float temp;
temp = TIM_CLK;
temp = temp/Sin_F;
temp = temp/N;
temp = temp/4;
return temp;
}
這個函數就是計算載波週期的四分之一,當它的返回值乘以佔空比就獲得公式的第二個參數,
float n2_RET(float M,float AN_RET)
{
static float temp;
temp = AN_RET;
temp *= M;
return temp;
}
最後在中斷處理函數裏面更新CCR的值,記住一次只更新一個值,並非讓你更新N個,
因此在中斷處理函數中不須要對 i 進行 1 ~ 360 的遍歷 , 只須要 每次遞增就好了。
當 i 超過 N 時,進行復位就能夠了。
TIM_ClearITPendingBit(ADVANCE_TIM, TIM_IT_CC1);
NewChannelValue = (int)(n1_Temp - n2_Temp*Sin_Tab[i++]);
if ( i == 360) { i = 0; } TIM_SetCompare1(ADVANCE_TIM,NewChannelValue);