1 SPWM波調制技術
??逆變電路的控制方式主要是采用SPWM(正弦脈寬調制技術),IR2104控制開關管的通斷來實現正弦調制,SPWM的基本思路是將一個正弦波按等寬間距分成N等份,對于每一個波形以一個等面積的脈沖來對應,使脈沖的中點與相應正弦波部分的中點重合,如下圖所示,由于此脈沖序列的面積分布滿足正弦規率,根據面積等效原理,將這個脈沖序列輸出至負載時,將使負載得到相當接近正弦的輸出電壓和電流。
??由于采用該方式輸出的電壓波形很接近正弦波,所以電壓中的諧波成分較少,同時也可以提高功率因數。通過改變SPWM脈沖的寬度可以改變輸出電壓的幅值,調節電路的調制周期則可以改變輸出電壓的頻率,方便對負載進行控制。
??單極性正弦脈寬調制是以一個寬度正弦規律變化的正弦脈沖序列對應交流輸出波形的正半周,再以一個寬度按正弦規率變換的負脈沖序列對應交流輸出波形的負半周,這兩個脈沖序列交替作用,控制開關器件產生近似于正弦波的輸出電壓波形。
??正弦脈寬調制的基本方法是將正弦波性的調制波與三角波形的載波進行比較,通過比較正弦波形各點的瞬時值確定該點對應的脈沖寬度。單極性正弦脈寬調制使用的三角波是單極性的,在正弦調制波為正半周時三角載波是正極性的;在正弦波為負半周時三角波載波為負極性。如下圖所示。
??雙極性正弦脈寬調制是以一個寬度按正弦規率變化的正負雙向脈沖序列對應交流輸出波形的整個周期,通過正向脈沖與負向脈沖寬度的差產生出按正弦規率變換的正半周波和負半周波。
??雙極性正弦脈寬調制使用的三角波是雙極性的,其波形的形式如下圖,通過正弦調制波與三角波比較,當正弦調制波值大于三角波時,輸出正脈沖;而當正弦調制波的值小于三角載波時,輸出負脈沖。如此得到的脈沖序列是正負交替的雙向脈沖序列。
??三相正弦脈寬調制可以使用三個相角彼此相差120°的單相調制電路來合成,但是這樣會使調制電路結構比較復雜。較簡單的方法是采用一個雙極性的三角載波對三相正弦調制波進行調制,其調制的波形如下圖。
??調制過程中,雙極性三角載波為三個正弦調制波共用,分別進行比較后獲取脈寬調制信號,方式與雙極性正弦脈寬調制方法相同。從而得到三個雙向的脈沖序列,分別對應A、B、C三相,使用此三個脈沖序列控制逆變電路的A、B、C三相開關元件,可以將直流電壓逆變為正弦波的三相交流輸出電壓。
??早期的SPWM采用模擬控制方式來實現,通過信號發生器產生所需的信號,由比較器進行信號之間的比較,隨著數字技術和微處理器在SPWM逆變技術中的應用,采用一定算法產生SPWM的數字控制方式越來越廣泛。
??波形比較法,其基本的方法是由正弦信號發生器件產生正弦調制波,由三角波信號發發生器產生的三角載波,將正弦調制波與三角載波比較,通過比較器的判斷而產生出對應的脈沖信號序列,對逆變電路進行控制從而得到所需的交流電壓。
(1)等效面積法
??其原理就是按面積等效原理構成與正弦波等效的一系列等幅但寬度按正弦規律變化的矩形脈沖。等效面積法適用于單極性控制,算法中計算的是正弦波形到橫軸間的面積,這與模擬控制方式中的單極性正弦脈沖調制的方式一致。
(2)自然采樣法與規則采樣法
??自然采樣法在算法上仿真模擬控制方式的雙極性正弦脈沖調制,通過計算正弦調制波與三角載波的交點位置,確定調制的脈沖寬度。而規則采樣法是對自然采樣法的簡化,其幾何關系如下圖。
利用單片機輸出PWM波,然后讓占空比正弦規律變化。
實現步驟可以簡單分為三步,以stm32為例:
(1)生成載波。比如要生成一個10KHZ的三角波,將計數器設置加減計數、周期設為1/10K就ok啦。這樣生成的三角波的幅值是多少呀,3.3V?其實在單片機里面都是數字信號,三角波最高點的時候可以用一個計數值來表示,比如8400,最低點是0。不用管他的電壓是多少。
(2)生成正弦波。這一步用軟件生成一個正弦表即可。比如將正弦波取200個點,即將一個正弦分割成200份,每個點代表一個幅值。用離散的數字量表達正弦模擬量。
(3)將正弦波和三角波進行比較。
a.什么時候進行比較。設置計數值達到比較值產生動作。
b.比較完之后,需要改變比較值,用于下一個周期進行比較(比較值可以理解為占空比),比較值查正弦表獲得,這樣就生成了占空比正弦規律變化的SPWM。
C.調制度m。m=正弦表最大值/三角波最大計數值。如正弦表最大值4200,三角波最大計數值8400,m=4200/8400=0.5,此時spwm最大占空比為50%,設置m=1,spwm最大占空比為100%。
例如我們要生成一個開環的三相spwm。單相逆變需生成兩組相差180度的spwm,三相即生成三組兩兩相差120度的spwm,且每組的spwm都是互補的。將生成的三組spwm分別加到1、2、3組橋臂,每組spwm互補防止了同一橋臂上下管同時導通會引起短路。
int const talab[250]=
{
100 , 102 , 108 , 116 , 126 , 140 , 154 , 172 , 194 , 216 ,
242 , 270 , 300 , 334 , 370 , 408 , 448 , 490 , 536 , 582 ,
632 , 684 , 738 , 794 , 854 , 914 , 976 ,1040 ,1108 ,1176 ,
1246 ,1320 ,1394 ,1470 ,1548 ,1626 ,1708 ,1790 ,1874 ,1960 ,
2046 ,2136 ,2224 ,2316 ,2408 ,2502 ,2596 ,2690 ,2786 ,2884 ,
2982 ,3080 ,3180 ,3280 ,3382 ,3482 ,3584 ,3686 ,3788 ,3892 ,
3994 ,4096 ,4200 ,4304 ,4406 ,4508 ,4612 ,4714 ,4816 ,4918 ,
5018 ,5120 ,5220 ,5320 ,5418 ,5516 ,5614 ,5710 ,5804 ,5898 ,
5992 ,6084 ,6176 ,6264 ,6354 ,6440 ,6526 ,6610 ,6692 ,6774 ,
6852 ,6930 ,7006 ,7080 ,7154 ,7224 ,7292 ,7360 ,7424 ,7486 ,
7546 ,7606 ,7662 ,7716 ,7768 ,7818 ,7864 ,7910 ,7952 ,7992 ,
8030 ,8066 ,8100 ,8130 ,8158 ,8184 ,8206 ,8228 ,8246 ,8260 ,
8274 ,8284 ,8292 ,8298 ,8300 ,8300 ,8298 ,8292 ,8284 ,8274 ,
8260 ,8246 ,8228 ,8206 ,8184 ,8158 ,8130 ,8100 ,8066 ,8030 ,
7992 ,7952 ,7910 ,7864 ,7818 ,7768 ,7716 ,7662 ,7606 ,7546 ,
7486 ,7424 ,7360 ,7292 ,7224 ,7154 ,7080 ,7006 ,6930 ,6852 ,
6774 ,6692 ,6610 ,6526 ,6440 ,6354 ,6264 ,6176 ,6084 ,5992 ,
5898 ,5804 ,5710 ,5614 ,5516 ,5418 ,5320 ,5220 ,5120 ,5018 ,
4918 ,4816 ,4714 ,4612 ,4508 ,4406 ,4304 ,4200 ,4096 ,3994 ,
3892 ,3788 ,3686 ,3584 ,3482 ,3382 ,3280 ,3180 ,3080 ,2982 ,
2884 ,2786 ,2690 ,2596 ,2502 ,2408 ,2316 ,2224 ,2136 ,2046 ,
1960 ,1874 ,1790 ,1708 ,1626 ,1548 ,1470 ,1394 ,1320 ,1246 ,
1176 ,1108 ,1040 , 976 , 914 , 854 , 794 , 738 , 684 , 632 ,
582 , 536 , 490 , 448 , 408 , 370 , 334 , 300 , 270 , 242 ,
216 , 194 , 172 , 154 , 140 , 126 , 116 , 108 , 102 , 100
};
uint16_t Counter_sine1 = 0; //A相
uint16_t Counter_sine2 = 83; //滯后A相120度
uint16_t Counter_sine3 = 166;//超前A相120度
/*TIM1GPIO初始化CH1--A8 CH2--A9 CH3--A10
CH1N-B13 CH2N-B14 CH3N-B15
*/
void TIM1_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9| GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13| GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
#define CKTIM ((u32)72000000uL) //主頻
#define PWM_PRSC ((u8)0) //TIM1分頻系數
#define PWM_FREQ ((u16) 10000) //PWM頻率(Hz)
#define PWM_PERIOD ((u16) (CKTIM / (u32)(2 * PWM_FREQ *(PWM_PRSC+1))))
#define MODULAT (float)0.7 //調制度
void TIM1_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM1_BDTRInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD; //計數周期
TIM_TimeBaseStructure.TIM_Prescaler = PWM_PRSC;//分頻系數
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置為PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能CHx的PWM輸出
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//互補輸出使能,使能CHxN的PWM輸出
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);//配置CH1
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC2Init(TIM1, &TIM_OCInitStructure); //配置CH2
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC3Init(TIM1, &TIM_OCInitStructure);//配置CH3
//死區時間
TIM1_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM1_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM1_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM1_BDTRInitStructure.TIM_DeadTime = 360; //設置死區時間
TIM1_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM1_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM1_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
TIM_BDTRConfig(TIM1, &TIM1_BDTRInitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //4個搶先級、4個子優先級
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM1,TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3,ENABLE); //使能中斷
TIM_CtrlPWMOutputs(TIM1, ENABLE); //PWM輸出使能
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
void TIM1_PWM_Init(void)
{
TIM1_GPIO_Config();
TIM1_Mode_Config();
}
//定時器1中斷服務函數
void TIM1_CC_IRQHandler(void)
{
if(Counter_sine1>=250) { Counter_sine1 = 0; }
if(Counter_sine2>=250) { Counter_sine2 = 0; }
if(Counter_sine3>=250) { Counter_sine3 = 0; }
if (TIM_GetITStatus(TIM1, TIM_IT_CC1)!=RESET)
{
TIM_SetCompare1(TIM1,(uint32_t)(talab[Counter_sine1])*MODULAT); //A相
Counter_sine1++;
TIM_ClearITPendingBit(TIM1 , TIM_IT_CC1);
}
if (TIM_GetITStatus(TIM1, TIM_IT_CC2) !=RESET)
{
TIM_SetCompare2(TIM1,((uint32_t)talab[Counter_sine2])*MODULAT); //B相
Counter_sine2++;
TIM_ClearITPendingBit(TIM1 , TIM_IT_CC2);
}
if (TIM_GetITStatus(TIM1, TIM_IT_CC3) !=RESET)
{
TIM_SetCompare3(TIM1,(uint32_t)(talab[Counter_sine3])*MODULAT); //C相
Counter_sine3++;
TIM_ClearITPendingBit(TIM1 , TIM_IT_CC3);
}
}
TIM1設置為中央計數模式,開啟互補通道,設置死區時間,死區時間是多少個時鐘計數周期,比如TIM1計數周期是72M,設置為72就是1000ns。spwm頻率設置為10k,然后TIM1每個通道的比較值達到時更新比較值。調制度m范圍為0~1,設為0.7。正弦調制波的頻率是自己設置的,方法是f=載波頻率/表中點數,這里設置的是載波頻率10K,取250個點得到的正弦頻率就是40HZ,改變載波頻率為50*250就得到了50hz的正弦波輸出。正弦表可以用取點工具。
??在連續時間控制系統中,PID控制器應用非常廣泛,其設計技術成熟,長期以來形成了典型的結構,參數整定方便,結構更改靈活。由于計算機程序的靈活性,數字PID控制比連續PID控制更為優越。
??連續時間PID控制系統如下圖所示,D(s)完成PID控制規律,稱為PID控制器。PID控制器是一種線性控制器,用輸出量y(t)和給定量r(t)之間的誤差的時間函數e(t)=r(t)-y(t)的比例、積分和微分的線性組合構成控制量u(t),稱為比例、積分、微分控制,簡稱PID控制。
??PID控制的三基本參數為KP、KI、KD,分別對應比例,積分,微分三個模,經實驗測試,可總結出這三項參數的實際控制作用為:
??比例調節參數(KP):按比例反映系統的偏差,系統一旦出現偏差,比例調節立即進行。比例調節是主要的控制部分,但過大的比例會使系統的穩定性下降。增大KP,系統的反應變靈敏、速度加快、穩態誤差減小,但振蕩次數也會加多、調節時間加長。
??積分調節參數(KI):消除系統靜態(穩態)誤差 ,提高系統的控制精度。積分調節會使系統的穩定性下降,動態響應變慢,超調加大。積分控制一般不單獨作用,而是與P或者PD結合作用。
??微分調節參數(KD):反映系統偏差信號的變化率,可以預見偏差的變化趨勢,產生超前控制作用,使偏差在未形成前已被消除。因此,微分控制可以提高系統的動態跟蹤性能,減小超調量,但對噪聲干擾有放大作用,過強的微分調節會使系統劇烈震蕩,對抗干擾不利。
??常規的PID控制系統中,減少超調和提高控制精度難以兩全其美。主要是積分作用有缺陷造成的。如果減少積分作用,靜差不易消除,有擾動時,消除誤差速度變慢;而加強積分作用時又難以避免超調,這也是常規PID控制中經常遇到的難題。
??P就是比例的意思。它的作用最明顯,原理也最簡單。
??需要控制的量,比如水溫,有它現在的『當前值』,也有我們期望的『目標值』。當兩者差距不大時,就讓加熱器“輕輕地”加熱一下。要是因為某些原因,溫度降低了很多,就讓加熱器“稍稍用力”加熱一下。要是當前溫度比目標溫度低得多,就讓加熱器“開足馬力”加熱,盡快讓水溫到達目標附近。
??這就是P的作用,跟開關控制方法相比,是不是“溫文爾雅”了很多.實際寫程序時,就讓偏差(目標減去當前)與調節裝置的“調節力度”,建立一個一次函數的關系,就可以實現最基本的“比例”控制了~
??KP越大,調節作用越激進,KP調小會讓調節作用更保守。
??要是你正在制作一個平衡車,有了KP的作用,你會發現,平衡車在平衡角度附近來回“狂抖”,比較難穩住。如果已經到了這一步——恭喜你!離成功只差一小步了~
??D的作用更好理解一些,所以先說說D,最后說i。
??剛才我們有了P的作用。你不難發現,只有P好像不能讓平衡車站起來,水溫也控制得晃晃悠悠,好像整個系統不是特別穩定,總是在“抖動”。
??因為我們忽視了一種重要的情況:
??還是以熱水為例。假如有個人把我們的加熱裝置帶到了非常冷的地方,開始燒水了。需要燒到50℃。
??在P的作用下,水溫慢慢升高。直到升高到45℃時,他發現了一個不好的事情:天氣太冷,水散熱的速度,和P控制的加熱的速度相等了。這可怎么辦?
??P兄這樣想:我和目標已經很近了,只需要輕輕加熱就可以了。
??D兄這樣想:加熱和散熱相等,溫度沒有波動,我好像不用調整什么。
??于是,水溫永遠地停留在45℃,永遠到不了50℃。
??作為一個人,根據常識,我們知道,應該進一步增加加熱的功率。可是增加多少該如何計算呢?
??前輩科學家們想到的方法是真的巧妙。設置一個積分量。只要偏差存在,就不斷地對偏差進行積分(累加),并反應在調節力度上。這樣一來,即使45℃和50℃相差不太大,但是隨著時間的推移,只要沒達到目標溫度,這個積分量就不斷增加。
??系統就會慢慢意識到:還沒有到達目標溫度,該增加功率啦!到了目標溫度后,假設溫度沒有波動,積分值就不會再變動。這時,加熱功率仍然等于散熱功率。但是,溫度是穩穩的50℃。
??Ki的值越大,積分時乘的系數就越大,積分效果越明顯。所以,I的作用就是,減小靜態情況下的誤差,讓受控物理量盡可能接近目標值。
??I在使用時還有個問題:需要設定積分限制。防止在剛開始加熱時,就把積分量積得太大,難以控制。
??數字PID控制是通過算法程序實現PID控制的。數字控制系統大多數是采樣數據控制系統,進入系統的連續時間信號必須經過采樣和量化后轉換為數字量,方能進行相應的計算和處理,不論是積分還是微分,只能用數值計算去逼近。當采樣周期相當短時,用求和代替積分,用差商代替微商,將描述連續時間PID算法的微分方程變為描述離散時間PID算法的差分方程。數字PID控制通常有以下兩種實現:
??當執行機構需要的不是控制量的絕對值,而是控制量的增量(例如驅動步進電動機)時,需要用PID的“增量算法”,其簡化示意圖如下圖所示。
「第一彈」電子設計大賽應該準備什么?
「第一篇」大學生電子設計競賽,等你來提問。
「第二篇」全國一等獎,經驗帖。
「第三篇」電賽,這些你必須知道的比賽細節,文末附上近十年電賽題目下載
「第四篇」電賽控制題可以準備一些什么?
「第五篇」全國電子設計競賽-電源題設計方案總結
「第六篇」對于電賽,我們應該看重什么?
電子設計競賽電源題(1)-電源題簡介
電子設計競賽電源題(2)-檢波與采樣
全國一等獎,他的學習之路。
從0開始,三個月,獲全國一等獎。
獎狀是怎么煉成的—我的電賽狂魔之旅
全國一等獎的獲得者,如今去當了人民教師。
【大學生電子設計競賽分享經驗貼】風力循跡小車
「重磅猜題之第二篇」2019年大學生電子設計競賽
最 后
若覺得文章不錯,轉發分享,也是我們繼續更新的動力。
5T資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,PCB、FPGA、DSP、labview、單片機、等等!
在公眾號內回復「
更多資源
」,即可免費獲取,期待你的關注~
長按識別圖中二維碼關注