ps2手柄控制 stm32f4zgt6芯片驱动麦克纳姆轮资料
这里使用的是PWM调速来完成的,简单的程序,资料和源码在下面。
麦克纳姆轮3D图纸:
单片机源程序如下:
- #include <sys.h>
- #include <pwm.h>
- #include <delay.h>
- #include <usart.h>
- #include <pstwo.h>
- int main(void)
- {
- u16 L11=0;
- u16 L12=0;
- u16 L21=0;
- u16 L22=0;
- u16 R11=0;
- u16 R12=0;
- u16 R21=0;
- u16 R22=0;
- u8 key;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
- delay_init(168); //初始化延时函数
- uart_init(115200); //初始化串口波特率为115200
- PWM_init(500-1,84-1); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
- PS2_Init();
- PS2_SetInit();
-
- while(1)
- {
- key=PS2_DataKey();
- if(key!=0)
- {
- switch(key)
- {
- case 5: //前进
- {
- L11=300;
- L12=0;
- L21=300;
- L22=0;
- R11=300;
- R12=0;
- R21=300;
- R22=0;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- case 6: //右平移
- {
- L11=0;
- L12=300;
- L21=300;
- L22=0;
- R11=300;
- R12=0;
- R21=0;
- R22=300;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- case 8: //左平移
- {
- L11=300;
- L12=0;
- L21=0;
- L22=300;
- R11=0;
- R12=300;
- R21=300;
- R22=0;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- case 7: //后退
- {
- L11=0;
- L12=300;
- L21=0;
- L22=300;
- R11=0;
- R12=300;
- R21=0;
- R22=300;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- case 9: //逆时针旋转
- {
- L11=0;
- L12=300;
- L21=0;
- L22=300;
- R11=300;
- R12=0;
- R21=300;
- R22=0;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- case 10: //顺时针旋转
- {
- L11=300;
- L12=0;
- L21=300;
- L22=0;
- R11=0;
- R12=300;
- R21=0;
- R22=300;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- case 13: //左前
- {
- L11=0;
- L12=0;
- L21=300;
- L22=0;
- R11=300;
- R12=0;
- R21=0;
- R22=0;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- case 14: //右前
- {
- L11=300;
- L12=0;
- L21=0;
- L22=0;
- R11=0;
- R12=0;
- R21=300;
- R22=0;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- case 16: //左后
- {
- L11=0;
- L12=0;
- L21=0;
- L22=300;
- R11=0;
- R12=300;
- R21=0;
- R22=0;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- case 15: //右后
- {
- L11=0;
- L12=300;
- L21=0;
- L22=0;
- R11=0;
- R12=0;
- R21=0;
- R22=300;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- break;
- }
- }
- else//停止
- {
- L11=0;
- L12=0;
- L21=0;
- L22=0;
- R11=0;
- R12=0;
- R21=0;
- R22=0;
- TIM_SetCompare1(TIM14,L11);
- TIM_SetCompare1(TIM13,L12);
- TIM_SetCompare1(TIM11,L21);
- TIM_SetCompare1(TIM10,L22);
- TIM_SetCompare1(TIM3,R11);
- TIM_SetCompare2(TIM3,R12);
- TIM_SetCompare3(TIM3,R21);
- TIM_SetCompare4(TIM3,R22);
- }
- delay_ms(50);
- }
- }
复制代码
- #include "main.h"
- #include "PID.h"
- #include<stdio.h>
- #include<math.h>
- #include<systick.h>
- #include<main.h>
- #define Kp 10 //比例系数
- #define Ki 10 //积分系数
- #define Kd 0 //微分系数
- #define PID_MAX 12800
- uint8_t last_error; //上次误差
- uint8_t last_error1; //上次误差
- uint8_t last_error2; //上次误差
- float I_term; //前面温差和
- float I_term1; //前面温差和
- float I_term2; //前面温差和
- u16 PWMA_Num =0;
- u16 PWMB_Num =0;
- u16 PWMC_Num =0;
- //unsigned int out;//,PWMT;
- //unsigned int out1//,PWMT;
- int PID(int Set_value,int Real_value) //标准PID温度控制算法
- {
- int error;
- float P_term, D_term;
- int pid_out;
- error=Set_value - Real_value; //误差量
- //if(error<1000)
- //{
- P_term =Kp*error; //比例量
- I_term+=Ki*error; //积分量
- if(I_term>PID_MAX) I_term=PID_MAX; //限定积分量上限
- else if(I_term<0) I_term=0; //限定积分量下限
- D_term =Kd*(error - last_error); //微分量
- last_error=error; //缓存当前误差量
- if(error<20)I_term=130;
- else I_term=0;
- pid_out=(signed int)(P_term+I_term+D_term); //PID控制量计算
-
- if(pid_out>PID_MAX) pid_out=PID_MAX; //控制量上限=PID_MAX
- else if(pid_out<0) pid_out=0; //控制量下限=0
- //return(pid_out);
- //}
- //else if(error>=1000) pid_out=12800;
-
- return(pid_out);
- }
- int PID1(int Set_value,int Real_value) //标准PID温度控制算法
- {
- int error;
- float P_term, D_term;
- int pid_out;
- error=Set_value - Real_value; //误差量
- //if(error<1000)
- //{
- P_term =Kp*error; //比例量
- I_term1+=Ki*error; //积分量
- if(I_term1>PID_MAX) I_term1=PID_MAX; //限定积分量上限
- else if(I_term1<0) I_term1=0; //限定积分量下限
- D_term =Kd*(error - last_error1); //微分量
- last_error1=error; //缓存当前误差量
- if(error<20)I_term1=130;
- else I_term1=0;
- pid_out=(signed int)(P_term+I_term1+D_term); //PID控制量计算
-
- if(pid_out>PID_MAX) pid_out=PID_MAX; //控制量上限=PID_MAX
- else if(pid_out<0) pid_out=0; //控制量下限=0
- //return(pid_out);
- //}
- //else if(error>=1000) pid_out=12800;
-
- return(pid_out);
- }
- int PID2(int Set_value,int Real_value) //标准PID温度控制算法
- {
- int error;
- float P_term, D_term;
- int pid_out;
- error=Set_value - Real_value; //误差量
- //if(error<1000)
- //{
- P_term =Kp*error; //比例量
- I_term2+=Ki*error; //积分量
- if(I_term2>PID_MAX) I_term2=PID_MAX; //限定积分量上限
- else if(I_term2<0) I_term2=0; //限定积分量下限
- D_term =Kd*(error - last_error2); //微分量
- last_error2=error; //缓存当前误差量
- if(error<20)I_term2=130;
- else I_term2=0;
- pid_out=(signed int)(P_term+I_term2+D_term); //PID控制量计算
-
- if(pid_out>PID_MAX) pid_out=PID_MAX; //控制量上限=PID_MAX
- else if(pid_out<0) pid_out=0; //控制量下限=0
- //return(pid_out);
- //}
- //else if(error>=1000) pid_out=12800;
-
- return(pid_out);
- }
- void jiare_pid_kongzhi(void)
- {
- uint16_t goal_temp=0;//目标温度
- //PWMT=12800; //128级步进PWM控制
- //PID_MAX=PWMT;
- uint16_t out=0;
- I_term=0;
- last_error=0;
- if (WorkFaceDisBuff[10]==0)//现场测试华氏不加热 增加温度单位转换 目标温度是摄氏和华氏分开存放的 2017年12月6日 09:16:22
- {
- goal_temp = (WorkFaceDisBuff[3]+0)*100;//之前的是+3 会导致PWM值超过目标温度值3度的时候才停止 可能需要PID数值才是正确方法 2017年11月30日 15:04:01
- }
- else
- {
- goal_temp = (WorkFaceDisBuff[11]+0)*100;//之前的是+3 会导致PWM值超过目标温度值3度的时候才停止 可能需要PID数值才是正确方法 2017年11月30日 15:04:01
- }
- out=PID(goal_temp,WorkFaceDisBuff[4]); //PID程序
- PWMA_Num= (out/100); //PWM值
- }
- void jiare_pid_kongzhi1(void)
- {
- uint16_t goal_temp=0;//目标温度
- //PWMT=12800; //128级步进PWM控制
- //PID_MAX=PWMT;
- uint16_t out=0;
- I_term1=0;
- last_error1=0;
-
- if (WorkFaceDisBuff[10]==0)//现场测试华氏不加热 增加温度单位转换 目标温度是摄氏和华氏分开存放的 2017年12月6日 09:16:22
- {
- goal_temp = (WorkFaceDisBuff[5]+0)*100;//之前的是+3 会导致PWM值超过目标温度值3度的时候才停止 可能需要PID数值才是正确方法 2017年11月30日 15:04:01
- }
- else
- {
- goal_temp = (WorkFaceDisBuff[12]+0)*100;//之前的是+3 会导致PWM值超过目标温度值3度的时候才停止 可能需要PID数值才是正确方法 2017年11月30日 15:04:01
- }
- out=PID1(goal_temp,WorkFaceDisBuff[6]); //PID程序
- PWMB_Num= (out/100); //PWM值
- }
- void jiare_pid_kongzhi2(void)
- {
- uint16_t goal_temp=0;//目标温度
- // //PWMT=12800; //128级步进PWM控制
- // //PID_MAX=PWMT;
- // uint16_t out=0;
- // I_term2=0;
- // last_error2=0;
-
- if (WorkFaceDisBuff[10]==0)//现场测试华氏不加热 增加温度单位转换 目标温度是摄氏和华氏分开存放的 2017年12月6日 09:16:22
- {
- goal_temp = (WorkFaceDisBuff[7]+0)*100;//之前的是+3 会导致PWM值超过目标温度值3度的时候才停止 可能需要PID数值才是正确方法 2017年11月30日 15:04:01
- }
- else
- {
- goal_temp = (WorkFaceDisBuff[13]+0)*100;//之前的是+3 会导致PWM值超过目标温度值3度的时候才停止 可能需要PID数值才是正确方法 2017年11月30日 15:04:01
- }
- // out=PID1(goal_temp,WorkFaceDisBuff[8]); //PID程序
- // PWMC_Num= (out/100); //PWM值
- if (goal_temp>WorkFaceDisBuff[8])//将PWM转化为开关量了 因为C路是继电器控制的
- {
- PWMC_Num=129;//永远大于128
- }
- else
- {
- PWMC_Num=0;
- }
- }
复制代码
所有资料51hei提供下载:
2018.9.28 TIM3backup.rar
(459.3 KB, 下载次数: 76)
纳姆车资料 STM32源码+3D图纸.7z
(4.45 MB, 下载次数: 99)
|