当前位置:文档之家› 智能循迹小车详细源代码程序MSPID

智能循迹小车详细源代码程序MSPID

巡线车程序(完整版)1 #ifndef _Macro.h_2 #define _Macro.h_3 #include <msp430x14x.h>4 #include <intrinsics.h>5 #define uchar unsigned char6 #define uint unsigned int7 #define one 11.118 #define LMAX 19999 #define RMAX 399910 #define CPU_F ((double)8000000)11 #define delay_us(x)__delay_cycles((long)(CPU_F*(double)x/1000000.0))1213 #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))14 #define PC 20 // 比例放大系数15 #define IC 0 //积分放大系数16 #define DC 85 //大系数17 #define LEFTOUT TACCR118 #define RIGHTOUT TACCR219 #define SensorIn P5IN20 #define F 5000//5000hz21 #define Period (8000000/F)22 #define EnableLeftPos P3OUT|=BIT123 #define UnenableLeftPos P3OUT&=~BIT12425 #define EnableLeftNeg P3OUT|=BIT026 #define UnenableLeftNeg P3OUT&=~BIT02728 #define EnableRightPos P3OUT|=BIT229 #define UnenableRightPos P3OUT&=~BIT23031 #define EnableRightNeg P3OUT|=BIT332 #define UnenableRightNeg P3OUT&=~BIT33334 #define Basic_Left 100//百分之八十35 #define Basic_Right 100//Basic_Left36 #define MAX (100)37 #define MIN (-100)38 #define foreward 139 #define backward 040 #define max_speed 10041 #define min_speed -10042 #define key 0434445 #define left_1 146 #define left_2 247 #define left_3 348 #define left_4 449 #define left_5 550 #define left_6 651 #define left_7 7//右直角5253 #define right_1 -154 #define right_2 -255 #define right_3 -356 #define right_4 -457 #define right_5 -558 #define right_6 -659 #define right_7 -7//左直角60 #endif[cpp]view plaincopy61 #include "Macro.h"62 #include "sensor.h"63 void Motorstop()64 {65 LEFTOUT=0;66 RIGHTOUT=0;67 }68 void MotorLeft(int speed,int direction)69 {70 if(speed>max_speed)speed=max_speed;71 if(direction==backward)//反转72 {73 EnableLeftNeg;74 UnenableLeftPos;75 }76 else if(direction==foreward)//正转77 {78 EnableLeftPos;79 UnenableLeftNeg;80 }81 LEFTOUT=Period/100*speed;82 }83 void MotorRight(int speed,int direction)84 {85 if(speed>max_speed)speed=max_speed;8687 if(direction==backward)//反转88 {89 EnableRightNeg;90 UnenableRightPos;91 }92 else if(direction==foreward)//正转93 {94 EnableRightPos;95 UnenableRightNeg;96 }97 RIGHTOUT=Period/100*speed;98 }99 void MotorDrive(int PIDout)100 {101 int speedleft,speedright;102 speedleft=Basic_Left PIDout;103 speedright=Basic_Right-PIDout;104105 if(speedleft<0)106 MotorLeft(speedleft,backward);//反转107 else MotorLeft(speedleft,foreward);//正转108109 if(speedright<0)110 MotorRight(speedright,backward);//反转111 else MotorRight(speedright,foreward);//正转112 }113 void Rangle(float angle)114 {115 // TBCTL|=TBCLR;116 TBCCR1=LMAX (unsigned int)(angle*one);117 }[cpp]view plaincopy118 //下面是小车的程序。

用定时器A来输出两路PWM波。

119 //选用输出模式7(首先输出高电平。

在TAR=CCRX时,电平自动变低。

这样可以输出任意占空比的PWM波)120 // 传感器接在P5口,电机的驱动接在P3口。

121 #include "Macro.h"122 #include "motor.h"123 typedef struct p124 {125 float error_1;//上次的误差126 float sumerror;127 }PID;128 PID Pid;129 PID *pid=&Pid;130 uchar detection,sample=0,corner,k,flag,tt=0;131 int weight1[]={-8,-5,-3,-2,0,2,3,5,8};//传感器的权值132 float sensorin;133 int num,tag=1;134 void IO_inti()//io口初始化135 {136 P1SEL|=BIT2 BIT3;//p1为定时器输出端。

137 P1DIR|=BIT2 BIT3;//设置为输出模式。

P5为传感器输入。

138 P3DIR|=BIT0 BIT1 BIT2 BIT3 BIT4;//0,1,2,3,作为电机控制的输出端,其他的作为传感器的输入端139 P5DIR=0X00;//P5为传感器输入端。

设置P5为输入端。

普通IO口。

140 P5SEL=0x00;141142143 P2DIR=0X00;//输入144145 P2IE|=BIT3;146 P2IES|=BIT3;147148 P6DIR=0XFF;//纯粹是为了调试用的。

149 P6OUT=0X00;150151 }152 void delay(int t)153 {154 unsigned int i;155 while(t--)156 {157 i=65535;158 while(i--);159 }160 }161 void CLK_inti()//时钟初始化162 {163 BCSCTL1=0X00;//打开XT2164 do{165 IFG1&=~OFIFG;166 for(int i=0x20;i>0;i--);167 }while((IFG1&OFIFG)==OFIFG);//如果起震失败。

继续起震。

知道成功为止168 BCSCTL2=0X00;169 BCSCTL2|=SELM_2|SELS;//mclk,sMCLK的时钟源为XT2,0分频。

170 }171172 void PID_inti()//PID初始化173 {174 pid->error_1=0;175 pid->sumerror=0;176 }177178 void PWM_inti()//PWM初始化179 {180 TACTL|=TASSEL_2|ID_0|MC_1|TACLR;//时钟源采用SMCLK,增计数模式。

清空TAR,0分频181 TACCR0=8000000/F;//0分频。

所以Period=8000000/5000182 TACCTL1|=OUTMOD_7;//两个PWM输出口的输出模式。

183 TACCTL2|=OUTMOD_7;//184 LEFTOUT=0;185 RIGHTOUT=0;186 }187188 float abs(float a)189 {190 return a<0?-a:a;191 }192193 void timer_inti()//用定时器B1来确定采样周期194 {195 TBCTL|=TBSSEL_2|CNTL_0|ID_3|MC_1|TBCLR;//定时器B:SMCLK,16位,8分频,增计数196 TBCCTL0|=CCIE;//使能timerb1的中断。

197 TBCCR0=5000;//八分频,1MHz,5000表示5ms。

198 _EINT();//打开总中断。

199 }200 void num_inti()201 {202 sensorin=0;203 num=0;204 }205 void inti()//总初始化函数206 {207 PID_inti();208 CLK_inti();209 PWM_inti();210 IO_inti();211 timer_inti();212 num_inti();213 }214 float ReadSensor2()215 {216 int state=0,i,num=0;217 float sum=0;218 static float output=0;219 state=P3IN&0X80;220 state<<=1;221 state|=P5IN;222 for(i=0;i<9;i )223 if(((1<<i)&state)==0)224 {225 sum =weight1[i];226 num ;227 }228 if(num>0&&num<7)//不是全白或者全黑229 {230 corner=0;231 if(num>=3)232 {233 corner=1;234 if(sum>0)235 output=10;236 else output=-10;237 return output;238 }239 output=sum/num;240 }241 else if(num>=7)//如果是全黑。

相关主题