stm32f407驅動電機進行pid調速。
IMG_20200302_114307.jpg (287.75 KB, 下載次數: 59)
下載附件
2020-3-2 11:48 上傳
單片機源程序如下:
- #include "sys.h"
- #include "delay.h"
- #include "usart.h"
- #include "led.h"
- #include "lcd.h"
- #include "adc.h"
- #include "key.h"
- #include "encoder.h"
- #include "moter.h"
- #include "pwm.h"
- #include "tim.h"
- #define BYTE0(dwTemp) ( *( (char *)(&dwTemp) ) )
- #define BYTE1(dwTemp) ( *( (char *)(&dwTemp) + 1) )
- #define BYTE2(dwTemp) ( *( (char *)(&dwTemp) + 2) )
- #define BYTE3(dwTemp) ( *( (char *)(&dwTemp) + 3) )
-
- u8 testdatatosend[50];
- void Test_Send_User(uint16_t data1, uint16_t data2, uint16_t data3,uint16_t data4,uint16_t data5,uint16_t data6,uint16_t data7,uint16_t data8,uint16_t data9,uint16_t data10) ;
- void UART1_Send_Str(unsigned char *s);
- u8 temp[50];
- char i=0;
- int now;
- int aim=50000;
- int error,last_error;
- int error_sum;
- int pwm=200;
- float KP=3.0
- ,KI=0.32 //0.34
- ,KD=50.0; //55.0
-
- int main(void)
- {
- u8 key;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置系統中斷優先級分組2
- delay_init(168); //初始化延時函數
- uart_init(115200); //初始化串口波特率為115200
- LED_Init(); //初始化LED
- LCD_Init(); //LCD初始化KEY_Init(); //按鍵初始化
- TIM3_ENC_Init();
- KEY_Init();
- MOTER_Init();
- LED_Init();
- PWM_TIM4_Init(1000-1,84-1); //1000HZ
- setPWM(pwm);
- POINT_COLOR=RED;
- LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
- LCD_ShowString(30,70,200,16,16,"---PID---");
- LCD_ShowString(30,90,200,16,16,"MOTER:");
- LCD_ShowString(30,110,200,16,16,"2014/5/6");
- TIM6_Int_Init(499,1679);
-
- while(1)
- {
- key=KEY_Scan(0);
- switch(key){
- case 1: aim+=500;break;
- case 2: aim-=500;break;
- }
- sprintf((char*)temp,"pwm:=%d ",pwm);
- LCD_ShowString(30,130,200,16,16,temp);
- sprintf((char*)temp,"encoder:=%d ",read_TIM3_position());
- LCD_ShowString(30,150,200,16,16,temp);
- sprintf((char*)temp,"aim:=%d ",aim);
- LCD_ShowString(30,170,200,16,16,temp);
- sprintf((char*)temp,"error:=%d ",error);
- LCD_ShowString(30,190,200,16,16,temp);
- Test_Send_User(now,aim,0,0,0,0,0,0,0,0);
-
-
-
-
- }
- }
- void TIM6_DAC_IRQHandler(void) //100HZ 中斷函數
- {
- if(TIM_GetITStatus(TIM6,TIM_IT_Update)==SET)
- {
- if(++i==5)
- {
- i=0;
- GPIO_ToggleBits(GPIOF,GPIO_Pin_9 ); //閃燈代表正在工作
- }
-
- now=read_TIM3_position(); //get現在位置
- error=now-aim; //獲取誤差
- if(error>=0) //如果error大于0 正轉動
- { MOTER_CW();
- LCD_ShowString(30,90,200,16,16,"++++++++++++++++"); //表示正轉動
- }
- else
- { MOTER_CCW();
- LCD_ShowString(30,90,200,16,16,"----------------");//表示反轉動
- } //如果error大于0 正轉動
- error_sum+=error; //誤差累計和
- if(error_sum>1000)error_sum=1000; //積分限幅
- if(error_sum<-1000)error_sum=-1000;
- pwm=error*KP+error_sum*KI+(error-last_error)*KD; //pwm= 當前誤差*比例項 + 誤差累計*積分項 + 兩次誤差之差*微分項
- last_error=error; //誤差沖洗賦值
- setPWM(pwm); //設定PWM
-
-
- }
-
-
- TIM_ClearITPendingBit(TIM6,TIM_IT_Update);
- }
- void Test_Send_User(uint16_t data1, uint16_t data2, uint16_t data3,uint16_t data4,uint16_t data5,uint16_t data6,uint16_t data7,uint16_t data8,uint16_t data9,uint16_t data10)
- {
- u8 _cnt=0;
- u8 i;
- u8 sum = 0;
-
- testdatatosend[_cnt++]=0xAA;
- testdatatosend[_cnt++]=0x05;
- testdatatosend[_cnt++]=0xAF;
- testdatatosend[_cnt++]=0xF1;
- testdatatosend[_cnt++]=0;
-
- testdatatosend[_cnt++]=BYTE1(data1);
- testdatatosend[_cnt++]=BYTE0(data1);
-
- testdatatosend[_cnt++]=BYTE1(data2);
- testdatatosend[_cnt++]=BYTE0(data2);
-
- testdatatosend[_cnt++]=BYTE1(data3);
- testdatatosend[_cnt++]=BYTE0(data3);
-
- testdatatosend[_cnt++]=BYTE1(data4);
- testdatatosend[_cnt++]=BYTE0(data4);
-
- testdatatosend[_cnt++]=BYTE1(data5);
- testdatatosend[_cnt++]=BYTE0(data5);
-
- testdatatosend[_cnt++]=BYTE1(data6);
- testdatatosend[_cnt++]=BYTE0(data6);
-
- testdatatosend[_cnt++]=BYTE1(data7);
- testdatatosend[_cnt++]=BYTE0(data7);
-
- testdatatosend[_cnt++]=BYTE1(data8);
- testdatatosend[_cnt++]=BYTE0(data8);
-
- testdatatosend[_cnt++]=BYTE1(data9);
- testdatatosend[_cnt++]=BYTE0(data9);
-
- testdatatosend[_cnt++]=BYTE1(data10);
- testdatatosend[_cnt++]=BYTE0(data10);
-
-
-
- testdatatosend[4] = _cnt-5;
-
-
- for( i=0;i<_cnt;i++)
- sum += testdatatosend[i];
-
- testdatatosend[_cnt++]=sum;
-
- UART1_Send_Str(testdatatosend);
- }
- void UART1_Send_Str(unsigned char *s)//發送字符串 函數 應用指針 方法
- {
- unsigned char i=0; //定義一個局部變量 用來 發送字符串 ++運算
- while(s[i]!=' ') // 每個字符串結尾 都是以 結尾的
- {
- USART_SendData(USART1,s[i]); //通過庫函數 發送數據
- while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);
- //等待發送完成。 檢測 USART_FLAG_TC 是否置1; //見庫函數 P359 介紹
- i++; //i++一次
- }
- }
復制代碼
所有資料51hei提供下載:
PID教程視頻對應代碼.7z
(343.65 KB, 下載次數: 123)
2020-3-2 13:56 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|