有需要的可以直接下載
51hei.png (187.36 KB, 下載次數: 51)
下載附件
2020-12-15 18:42 上傳
單片機源程序如下:
- //#include "iostm8s103k3.h"
- #include "iostm8s207r8.h"
- //STM8S207單片機; 連上仿真器后,ST-LINK-->Option Bytes: AFR5,右鍵-->Alternate Active,使PB0/PB1/PB2為PWM輸出端口功能。
- //下載運行后,View-->Livewatch,觀察PID控制參數的變化,觀察LED1的亮度;
- //TIM2中斷作為計時時間;PE0作為外中斷輸入;把外部頻率信號與PE0連接,進行脈沖計數(頻率測量)
- //開發板上用杜邦線把PB0與PD5連接起來;
- //單片機PC1(PWM輸出)與焊的電路板PC1端子連接;電機編碼器轉速信號(黃線)與單片機PE0連接;
- //電機編碼器供電正極(藍線)接+5V;電機編碼器供電負極(黑線)接GND;
- //電機本身供電正極(紅線)接+12V,電機本身供電負極(白線)接焊的電路板的P1排針的第3腳(功率三極管集電極),
- //焊的電路板接線參考《直流電機PWM調速電路圖》
- unsigned long pulsecount=0;
- unsigned long frequency=0;
- static const unsigned int ArrPwmVal = 16000; //PWM信號周期:1ms, 1KHz
- int pwmvalue=8000; //pwm1value取值范圍0~16000;
- float Kp=10,Ki=0.1,Kd=0; //PID參數
- float set_velocity=1000.0, sample_velocity=0;
- float PIDoutvalue=0; //PID運算輸出值
- int duty=0; //PWM波占空比
- void Delay1ms(unsigned int c ) //1ms延遲函數
- {
- unsigned int i;
-
- while(c--!=0) //一個while循環占用3個機器周期
- for(i=0;i<3000;i++); //一條for循環占用4個機器周期
- }
- void InitLED(void)
- {
- PD_DDR|=0x60; //設置PD5、PD6為輸出模式
- PD_CR1|=0x60; //設置PD5、PD6為推挽輸出
- }
- //1KHZ PWM頻率;//上橋臂PWM---PC1\PC2\PC3;下橋臂PWM---PB0\PB1\PB2
- void InitTIM1_PWM(void) //16 位高級控制定時器(TIM1);定時器16MHz基準; 只使用了CC1P通道
- {
- //分頻,1分頻; 計數器的時鐘頻率(fCK_CNT)等于fCK_PSC/( PSCR[15:0]+1)
- TIM1_PSCRH=0; //預分頻器高8位(TIM1_PSCRH)
- TIM1_PSCRL=0; //預分頻器低8位(TIM1_PSCRL)
-
- TIM1_ARRH=ArrPwmVal/256;
- TIM1_ARRL=ArrPwmVal%256;
-
- TIM1_CR1 = 0x04; //DIR0:向上計數;URS=1:寄存器被更新時,產生更新中斷
- TIM1_CCMR1 = 0x60; //PWM1模式,禁止預裝載
-
- TIM1_CCER1=0x01; //CH1通道輸出PWM使能,高電平有效
- TIM1_BKR|=0x80; //使能PWM輸出 //0x80;使能OC和OCN輸出;MOE: 主輸出使能
-
-
- TIM1_CR1 |= 0x01; //使能定時計數器
- }
- void TIM2_Init(unsigned int psc,unsigned int arr) //psc 分頻系數 arr 計數值
- {
- TIM2_CR1 = 0x00; //向上計數 中斷繼續計數 關閉計數器
- TIM2_IER = 0x01; //UIE=1:允許更新中斷
- TIM2_PSCR = psc; //fMASTER/2^psc;
- TIM2_ARRH = arr/256;
- TIM2_ARRL = arr%256;
- TIM2_CR1 |=0x01; //開始計數
-
- }
- void InitEXTI(void) //PE0作為外中斷輸入
- { //PEx對應EXTI4_IRQHandler
- EXTI_CR2=0x02; //PE端口下降沿觸發中斷
- PE_DDR&=0xFE; //PE0為輸入模式
- PE_CR1|=0x01; //PE0上拉
- PE_CR2|=0x01; //PE0使能外部中斷
- }
- /**************************************************************************
- 函數功能:位置式PID控制器
- 入口參數:編碼器測量位置信息,目標位置
- 返回 值:sum
- 根據位置式離散PID公式
- pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
- e(k)代表本次偏差
- e(k-1)代表上一次的偏差
- ∑e(k)代表e(k)以及之前的偏差的累積和;
- pwm代表輸出
- **************************************************************************/
- float Position_PID (float set_value,float feedback_value)
- {
- static float error,sum,Integral_part,pre_error;
-
- error=set_value-feedback_value; //計算偏差
- Integral_part+=error; //求出偏差的積分
- if(Integral_part>15000) Integral_part=15000;
- if(Integral_part<0) Integral_part=0;
- sum=Kp*error+Ki*Integral_part+Kd*(error-pre_error); //位置式PID控制器
- pre_error=error; //保存上一次偏差
-
- if(sum<0)
- sum=0;
-
- PIDoutvalue=sum;
-
- return sum; //增量輸出
- }
- void main( void )
- {
- CLK_CKDIVR=0x00; //HSI不分頻,主時鐘16M
-
- InitLED();
- InitTIM1_PWM();
- InitEXTI();
-
- asm("sim"); //disable all interrupt EA=0;
- TIM2_Init(8,62499); // 定時器2中斷周期: 2^8/16M *62500=1s;
- asm("rim"); //開中斷
-
- frequency=0;
-
- while(1)
- {
- sample_velocity=frequency;
- // pwmvalue=(int)Position_PID(set_velocity,sample_velocity);
-
- if(pwmvalue<0)
- pwmvalue=0;
- if(pwmvalue>15900)
- pwmvalue=15900; //PWM限幅
-
-
- TIM1_CCR1H = pwmvalue/256; //PWM1通道占空比寄存器賦值
- TIM1_CCR1L = pwmvalue%256;
-
- duty=pwmvalue/160; //占空比duty=pwmvalue/16000 *100%;
-
- Delay1ms(10); //轉速閉環控制周期:10ms;
- }
- }
- #pragma vector=0x09 // 9: EXTI4 端口E外部中斷
- __interrupt void EXTI4_IRQHandler(void) //PE
- {
- pulsecount++;
- }
- #pragma vector=15
- __interrupt void TIM2_OVER_INT(void)
- {
- TIM2_SR1 = 0x00;
-
- frequency=pulsecount; //電機旋轉1周輸出6個脈沖
- pulsecount=0;
-
- PD_ODR ^=0x60; //PD5、PD6閃爍
-
- }
復制代碼- //#include "iostm8s103k3.h"
- #include "iostm8s207r8.h"
- //207單片機; 連上仿真器后,ST-LINK-->Option Bytes: AFR5,右鍵-->Alternate Active,使PB0/PB1/PB2為PWM輸出端口功能。
- //16KHZ PWM頻率
- //上橋臂PWM---PC1\PC2\PC3
- //下橋臂PWM---PB0\PB1\PB2
- //用杜邦線把PB0與PD5連接起來;先下載程序,再連線;
- //下載運行后,View-->Livewatch,改變pwmvalue1的值,改變PWM1占空比,觀察LED1的亮度;
- static const unsigned int ArrPwmVal = 1000; //PWM信號周期; 1000
- unsigned int pwm1value=500;
- void InitTIM1_PWM(void) //16 位高級控制定時器(TIM1);1us定時器時鐘基準
- {
- //分頻,1分頻; 計數器的時鐘頻率(fCK_CNT)等于fCK_PSC/( PSCR[15:0]+1)
- TIM1_PSCRH=0; //預分頻器高8位(TIM1_PSCRH)
- TIM1_PSCRL=15; //預分頻器低8位(TIM1_PSCRL)
-
- TIM1_ARRH=ArrPwmVal/256;
- TIM1_ARRL=ArrPwmVal%256;
-
- TIM1_CR1 = 0x04; //DIR0:向上計數;URS=1:寄存器被更新時,產生更新中斷
- TIM1_CCMR1 = 0x60; //PWM1模式,禁止預裝載
-
- TIM1_CCER1=0x05; //CH1、CH2通道輸出PWM使能,高電平有效
- TIM1_BKR|=0x80; //使能PWM輸出 //0x80;使能OC和OCN輸出;MOE: 主輸出使能
- TIM1_DTR=16; //死區62.5ns*16=1us
-
-
- TIM1_CR1 |= 0x01; //使能定時計數器
- }
- void main( void )
- {
-
- CLK_CKDIVR=0x00;//HSI不分頻,主時鐘16M
- InitTIM1_PWM();
-
- while(1)
- {
- TIM1_CCR1H = pwm1value/256; //PWM1通道占空比10%
- TIM1_CCR1L = pwm1value%256;
-
- }
- }
復制代碼
51hei.png (3.47 KB, 下載次數: 49)
下載附件
2020-12-15 18:40 上傳
所有資料51hei提供下載:
直流電機伺服控制設計訓練.zip
(1.29 MB, 下載次數: 23)
2020-12-15 09:37 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|