stm32f407驱动电机进行pid调速。
单片机源程序如下:
- #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)
|