【文件属性】:
文件名称:自动循迹小车原理图
文件大小:95KB
文件格式:PDF
更新时间:2017-04-13 06:05:24
msp430
#include
#include "qudong.h"
#include "duankou.h"
#include "lcd1602.h"
#include "celv.h"
#define uchar unsigned char
#define uint unsigned int
#define CPU_F ((double)8000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
//******************************************************************************
//全局变量
//******************************************************************************
float voltage=6.0; //实际电压值
int RS1=100;
int LS1=100;
int RS0=100;
int LS0=100;
char heixian=0x03; //不等于0x03表示检测到信号,等于0x03表示没检测到信号
char ji_shu=0; //表示第几次检测到黑线
char youxinhao=0; //=1表示检测到信号,=0表示没有检测到信号
uint total_time_count=0;//时间相关变量
uint start_low_speed=0;
uint end_low_speed=0;
uint end_all=0;
uint start_all=0;
uint LM_cap_new=0; //测速相关变量
uint LM_cap_old=0;
uint LM_cap_count=0;
uint LM_mai_kuai=0;
float real_LM_speed=0.0;
float top_speed=0;
float average_speed=0;
uint RM_cap_new=0;
uint RM_cap_old=0;
uint RM_cap_count=0;
uint RM_mai_kuai=0;
float real_RM_speed=0.0;
float total_distance=0; //测量值转化为实际值相关变量
float dis1=0;
float dis0=0;
uint low_speed_time=0;
uint total_time=0;
//******************************************************************************
//系统时钟初始化,aclk=32768k,mclk=XT2,SMCLK = XT2。
//******************************************************************************
void Init_clock(void)
{
DCOCTL = DCO0 + DCO1 + DCO2; // Max DCO数字晶振最高频率
BCSCTL1 = RSEL0 + RSEL1 + RSEL2; // XT2on, max RSEL选择高速晶振最高频率
BCSCTL2 |=SELM_2+SELS; //MCLK=8M,SMCLK = XT2,系统主时钟选择高速晶振
do //清除振荡器失效标志,等振荡器稳定。
{
IFG1&=~OFIFG;
for(unsigned int i=0XFF;i>0;i--);
}
while((IFG1&OFIFG)!=0);
}
#pragma vector=ADC_VECTOR //ADC12 interrupt service routine
__interrupt void ADC12_ISR (void)
{
if(ADC12MEM0<2816)P6OUT&=~BIT3; //欠压指示灯亮
else P6OUT|=BIT3;
}
//******************************************************************************
//标志线控制策略
//******************************************************************************
/*void ce_lve_2(char biao_zhi)
{
switch(biao_zhi)
{
case 0://低速寻线至开始线
{
LM_speed=LM_speed*0.5;
RM_speed=RM_speed*0.5;
break;
}
///////////////////////////////////////////等磁钢
case 1://起跑线制动
{
dian_ji(-100,-100);//反转制动
delay_ms(50);
dian_ji(0,0);
char i=0;//定时10s
do
{
delay_ms(500);
P6OUT|=BIT6;//关停止灯
P6OUT^=BIT4;//启动指示灯1S闪一次
i++;
}
while(i<21);
LM_speed=100;//全速启动
RM_speed=100;
start_all=total_time_count;//捕获当前总时间计数
ji_shu=ji_shu+1;
break;
}
case 2://开始线至减速线区间
{
break;
}
/////////////////////////////////////////////等磁钢
case 3://减速区开始
{
start_low_speed=total_time_count;//记录减速区开始时间
ji_shu=ji_shu+1;//只运行一次
break;
}
case 4://减速区
{
dian_ji(5,100);
delay_ms(4);
dian_ji(5,5);
delay_ms(40);
dian_ji(100,5);
delay_ms(4);
dian_ji(5,5);
delay_ms(40);
LM_speed=5;
LM_speed=5;
if(total_time_count-start_low_speed>24)ji_shu=ji_shu+1;//25秒到进入下一状态
break;
}
case 5:
{
break;//减速区内
}
////////////////////////////////////////////////等磁钢
case 6://减速区结束
{
end_low_speed=total_time_count;//记录减速区结束时间
LM_speed=100; //恢复全速
RM_speed=100;
ji_shu=ji_shu+1;//只运行一次
break;
}
case 7:
{
break;//减速区结束线至终点线区间
}
//////////////////////////////////等磁钢
case 8: //终止线制动
{
dian_ji(-100,-100);//反转制动
delay_ms(150);
dian_ji(0,0);
end_all=total_time_count;//捕获结束时间
dis0=(LM_cap_count*0.01833+RM_cap_count*0.01833)/2.0;//捕获结束位置
char j=0;//10s定时
do
{
delay_ms(500);
P6OUT|=BIT4;//关启动灯
P6OUT^=BIT6;//停止指示灯1S闪一次
j++;
}
while(j<21); //20次退出
LM_speed=60;
RM_speed=60;
ji_shu=ji_shu+1;//执行一次
break;
}
case 9://0.5m
{
dis1=(LM_cap_count*0.01833+RM_cap_count*0.01833)/2.0;//捕获当前位置
LM_speed=LM_speed*0.4;
RM_speed=RM_speed*0.4;
if(dis1-dis0>=0.53) //判断是否大于0.5m
{
dian_ji(-100,-100);//反转制动
delay_ms(50);
dian_ji(0,0);
LM_speed=0;
RM_speed=0;
ji_shu=ji_shu+1; //执行一次
}
break;
}
case 10:
{
LM_speed=0;
RM_speed=0;
break;
}
default://其他情况停车处理
{
LM_speed=0;
RM_speed=0;
break;
}
}
}*/
//***********************************************************************
//干簧管部分
//***********************************************************************
/*void gan_huang_guan(void)
{
if(youxinhao==1)
{
return;
}
else
{
heixian=P3IN&0X03;
if(heixian!=0x03)//有磁铁
{
ji_shu++;
youxinhao=1;
TBCCR0=TBR+32768;
TBCCTL0=CCIE;//开CCR0中断
//Init_timerB0();
}
else
{
youxinhao=0;
}
}
}
//INIT_TIMER_B
void Init_timer_B(void)
{
TBCTL = TBSSEL_1 + MC_2+TBIE + TBCLR;
//ACLK +连续计数+TB中断允许+清TBR
TBCCTL0 = CCIE; //TBCCR0 中断使能//干簧管用
TBCCTL1 = CM_1 + CCIS_1 + CAP + CCIE;//左轮测速用
//上升沿计数 + CCI1B (P4.1) + 捕获功能 + 捕获中断允许
TBCCTL2 = CM_1 + CCIS_1 + CAP + CCIE;//右轮测速用
//上升沿计数 + CCI2B (P4.2) + 捕获功能 + 捕获中断允许
TBCCTL3 = CCIE;//TBCCR3 中断使能//总时间计数用
TBCCR0 =TBR+32768;//干簧管定时1s
TBCCR3 =TBR+32768;//干簧管定时1s
_EINT();//开总中断
}
//中断服务程序
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B0(void)//干簧管1S中断
{
youxinhao=0; //表示可以继续检测
TBCCTL0&=~CCIE;//关TBCCR0中断
}
#pragma vector=TIMERB1_VECTOR
__interrupt void Timer_B1(void)//测速及总时间计数中断
{
switch( TBIV )
{
case 2://左轮上升沿捕获
{
P3OUT^=BIT4;//进中断指示
LM_cap_new=TBR;
LM_cap_count++;
if(LM_cap_newtop_speed)top_speed=real_LM_speed;//寻找最高速
average_speed=(average_speed+real_LM_speed)/2.0;//计算平均速度
break;
}
case 4://右轮上升沿捕获
{
P3OUT^=BIT5;//进中断指示
RM_cap_new=TBR;
RM_cap_count++;
if(RM_cap_newtop_speed)top_speed=real_RM_speed;//寻找最高速
average_speed=(average_speed+real_RM_speed)/2.0;//计算平均速度
break;
}
case 6://timer b3中断,总时间计数
{
total_time_count++;//总时间计数
TBCCR3+=32768;//定时1s
break;
}
default:break;
}
}*/
//******************************************************************************
//指示灯部分
//******************************************************************************
/*void LED_out(void)
{
if(LM_speedRM_speed)//右转指示灯亮
{
P6OUT|=BIT5;
P6OUT&=~BIT7;
}
if(ji_shu==2)//启动指示灯亮
{
P6OUT|=BIT6;
P6OUT&=~BIT4;
}
if(ji_shu==9)//if((LM_speed==0)&&(RM_speed==0))//停车指示灯亮
{
P6OUT&=~BIT6;
P6OUT|=BIT4;
}
if((LM_speed<0)&&(RM_speed<0))P6OUT&=~BIT2;//倒车指示灯亮
else P6OUT|=BIT2;
//P6OUT^=BIT2;//程序正常运行闪
}*/
//******************************************************************************
//主函数
//******************************************************************************
void main()
{
//////////////////////////////////初始化部分
WDTCTL = WDTPW + WDTHOLD; //Disable the Watchdog.
delay_ms(300); //延时
Init_clock(); //系统时钟初始化,MCLK=XT2,ACLK=XT1
Init_port(); //端口初始化
//Init_voltage();//电压检测
Init_timer_A();//定时器A初始化,包括PWM产生
//Init_timer_B();//定时器B初始化,包括测速,时间测量
//////////////////////////////////循迹部分 ji_shu<10
while(1)
{
xun_ji(); //循迹输入
//gan_huang_guan();//干簧管输入
ce_lve_0(wei_zhi); //偏差控制策略
//ce_lve_2(ji_shu); //标志线控制策略
//start_AD(); //电压采样开始
//LED_out(); //指示灯输出
dian_ji(LM_speed,RM_speed);//电机输出
if(wei_zhi==8||wei_zhi==9)
{delay_ms(25);}
delay_ms(30);
}
//////////////////////////////////结束显示部分
/*total_distance=(LM_cap_count*0.01833+RM_cap_count*0.01833)/2.0;//计算总路程
low_speed_time=end_low_speed-start_low_speed; //计算减速区行驶时间
total_time=end_all-start_all;//总时间
Voltage_ave(); //电压平均值
B_vol=voltage; //将实际值送显示缓冲区
T_top=total_time;
T_low=low_speed_time;
S_top=top_speed;
S_ave=average_speed;
D_tol=total_distance;
while(1)
{
Disp(B_vol,T_top,T_low,S_top,S_ave,D_tol);
}*/
}//完