PWM调速+循迹--智能小车程序

合集下载

智能循迹避障小车完整程序(亲测好使)

智能循迹避障小车完整程序(亲测好使)

智能循迹避障小车完整程序(亲测好使)/*******************************************//利用51定时器产生PWM波来调节电机速度//速度变化范围从0-100可调//使用三路做寻迹使用,哪一路检测在黑线哪一路为//高电平//没检测到黑线表示有反射对应输出低电平信号*********************************************/#include<>#define uint unsigned int#define uchar unsigned char/*电机四个接口定义*/sbit in1=P0^0;sbit in2=P0^1;sbit in3=P0^2;sbit in4=P0^3;/*计时器*/uchar j,k,i,a,A1,A2,second,minge,minshi;sbit dula=P2^6;sbit wela=P2^7;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar code table2[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};void delay(uchar i){for(j=i;j>0;j--)for(k=110;k>0;k--);}void display(uchar sh_c,uchar g_c,uchar min_ge,uchar min_shi) {dula=1;P0=table[sh_c];dula=0;P0=0xff;wela=1;P0=0xfb;wela=0;delay(5);dula=1;P0=table[g_c];dula=0;P0=0xff;wela=1;P0=0xf7;wela=0;delay(5);dula=1;P0=table[min_shi];dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delay(5);dula=1;P0=table2[min_ge];dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delay(5);}/*左、中、右三路循迹传感器接口定义*/ sbit zuo=P1^0; sbit zhong=P1^1;sbit you=P1^2;/*避障接口定义*/sbit bz_zuo=P1^3;sbit bz_zhong=P1^4;sbit bz_you=P1^5;uchar count = 0;/*利用定时器0定时中断,产生PWM波*/ void Init_timer() {TH0 = (65535-10)/256;TL0 = (65535-10)%256;TMOD = 0x01;TR0 = 1;ET0 = 1;EA = 1;}/*左轮速度调节程序*/void zuolun(uchar speed){if(count <= speed) //count计数变量{in1 = 1;in2 = 0;}else{in1 = 0;in2 = 1;}}void youlun(uchar speed) //同上{if(count<= speed){in3 = 1;in4 = 0;}else{in3 = 0;in4 = 1;}}void Inline() //检测黑线信号{uchar temp;temp =P1;switch(temp){case 0x01:zuolun(0); youlun(90);break; //左侧循迹传感器压线,小车向左前修正case 0x02:zuolun(100);youlun(100);break; //中间循迹传感器压线,保持直走此处两值使电机速度保持相同case 0x04:zuolun(90); youlun(0);break; //右侧循迹传感器压线,小车向右前修正case 0x08:zuolun(90); youlun(0);break; //左侧避障传感器有信号小车右转case 0x10:zuolun(90); youlun(0);break; //中间避障传感器有信号小车左转case 0x20:zuolun(90); youlun(0);break; //右侧避障传感器有信号小车左转}/*if(zuo==1){zuolun(10);youlun(50);}else if(zhong==1){zuolun(99);youlun(99);}else if(you==1){zuolun(50);youlun(10);} */}void main() //主函数{Init_timer(); //调用函数while(1){Inline();minge=0;minshi=0;second++;if(second==60)second=0,minge++;A1=second/10;A2=second%10;if(minge==10)minge=0,minshi++;for(a=200;a>0;a--){display(A1,A2,minge,minshi);};}}void Timer0_int()interrupt 1 //定时器中断计数{TH0 = (65535-10)/256;TL0 = (65535-10)%256;count ++;if(count >= 100){count = 0;}}。

pwm控制的小车

pwm控制的小车
{
T2MOD=0x00;
T2CON=0x00;
TH2 = (65536-100)/256;
TL2 = (65536-100)%256;
RCAP2H =(65536-100)/256; //上面两个装满之后,系统自动重装
RCAP2L =(65536-100)%256;
{
PWM_right=5;
PWM_left=35;
right_1=0;
right_2=1;
left_1=1;
left_2=0;
}
// 小车左转
void turn_left()
{
PWM_right=35;
{
flag_key=1;
}
else if((right_electric==1 && left_electric==0)||(right1_electric ==1 && left_electric ==0)|| (right_electric==1 && left1_electric==0)||(right1_electric ==1 && left1_electric ==0) )
right_2=1;
left_1=1;
left_2=0;
delay(4000);
}
//循迹左右轮控制
void r_l_electric()
{
if( (left_electric==1 && right1_electric==0) || (left1_electric==0 && right1_electric==0)||(left_electric==1 && right_electric==0) || (left1_electric==1 && right_electric==0))

循迹小车程序(三路循迹)

循迹小车程序(三路循迹)

#include "reg51.h"typedef unsigned int uint;typedef unsigned char uchar;sbit p2_0 = P2^0; //开关sbit p2_1 = P2^1; //红外检测sbit p2_2 = P2^2;sbit p2_3 = P2^3;sbit p1_0 = P1^0; //电机驱动sbit p1_1 = P1^1;sbit p1_2 = P1^2;sbit p1_3 = P1^3;sbit pwm1 = P1^4; //pwm调速sbit pwm2 = P1^5;unsigned char timer1;/******************************************************************** ************ 函数名 : Time1Config* 函数功能 : 设置定时器* 输入 : 无* 输出 : 无********************************************************************* **********/void Time1Config(){TMOD|= 0x10; //设置定时计数器工作方式1为定时器//--定时器赋初始值,12MHZ下定时0.5ms--//TH1 = 0xFE;TL1 = 0x0C;ET1 = 1; //开启定时器1中断EA = 1;TR1 = 1; //开启定时器}/************************************************ 延时函数总共延时1ms乘以count************************************************/ void DelayX1ms(uint count){uint j;while(count--!=0){for(j=0;j<72;j++);}}/************************************************ 电机转动函数定义************************************************/ void ZhiXing( ){p1_0=0;p1_1=0;p1_2=0;p1_3=0;DelayX1ms(10);p1_0=0;p1_1=1;p1_2=0;p1_3=1;DelayX1ms(15);}void ZuoZhuan( ){pwm1=0;pwm2=0;DelayX1ms(10); p1_0=0;p1_1=1;p1_2=1;p1_3=0;DelayX1ms(20); }void YouZhuan( ){pwm1=0;pwm2=0;DelayX1ms(10);p1_0=1;p1_1=0;p1_2=0;p1_3=1;DelayX1ms(20); }void HouTui( ){p1_0=0;p1_1=0;p1_2=0;p1_3=0;DelayX1ms(6); p1_0=1;p1_1=0;p1_2=1;p1_3=0;DelayX1ms(20);}/************************************************ 主函数************************************************/ void main( ){Time1Config();while(1){if( p2_1==0 && p2_2==0 && p2_3==1){YouZhuan( );}else if(p2_1==1 && p2_2==0 && p2_3==0){ZuoZhuan( );}else{ZhiXing( );}}}/******************************************************************** ************ 函数名 : Time1* 函数功能 : 定时器1的中断函数* 输入 : 无* 输出 : 无********************************************************************* **********/void Time1(void) interrupt 3 //3 为定时器1的中断号 1 定时器0的中断号 0 外部中断1 2 外部中断2 4 串口中断{timer1++;if(timer1>100) //PWM周期为100*0.5ms{timer1=0;}if(timer1 < 85) //改变30这个值可以改变直流电机的速度{pwm1=1;pwm2=1;}else{pwm1=0;pwm2=0;}TH1 = 0xFE; //重新赋初值TL1 = 0x0C;}。

pwm调速控制小车循迹壁障c程序

pwm调速控制小车循迹壁障c程序

pwm调速控制小车循迹壁障c程序#include< reg51.h >#define uchar unsigned char#define uint unsigned int#define MOTOR_C P1 //P1口作为电机的控制口。

//#define SIGNAL P3 //P3口的低两位为循迹传感器输入口。

#define SHELVES 10 //速度总档数。

#define BACK 0xfa //后退。

#define FORWARD 0xf5 //前进。

sbit senserr = P3^2; //(右)循迹。

sbit senserl = P3^3; //(左)循迹。

sbit hwf = P3^0; //(前)红外壁障传感器入口。

sbit hwb = P3^1; //(后)红外壁障传感器入口。

sbit PWM_R = P1^0; //右电机PWM输入口。

sbit PWM_L = P1^2; //左电机PWM输入口。

sbit PWM_HR = P1^1; //(后退)右电机。

sbit PWM_HL = P1^3; //(后退)左电机。

void timer0_init( void ); //定时器0初始化函数。

void timer1_init( void ); //定时器1初始化函数。

void right( void ); //前进右转弯函数。

void left( void ); //前进左转弯函数。

void forward( void ); //前进函数。

void hright(void); //后退右转函数。

void hleft(void); //后退左转函数。

void back(void); //后退函数。

uchar percent_l = 0; //(前进)左轮占空比。

uchar percent_r = 0; //(前进)右轮占空比。

uchar percent_hl = 0; //(后退)左轮占空比。

51单片机智能小车按键调速前进程序源代码、电路原理图和电路器件表

51单片机智能小车按键调速前进程序源代码、电路原理图和电路器件表

51单片机智能小车按键调速前进程序源代码、电路原理图、电路器件表智能小车PWM调速是通过设置pwmval_left_init的和pwmval_right_init这2个变量的值来实现的,需要通过修改程序代码中这2个变量的值,这2个变量的值设置好后,在程序运行的过程中是不能修改的。

而智能小车的按键调速通过按键达到修改这2个变量的值,从而达到对智能小车调速的目的。

每按下K3按键一次,变量pwmval_left_init和pwmval_right_init减1,智能小车减速。

每按下K4按键一次,变量pwmval_left_init和pwmval_right_init加1,智能小车加速。

具体实现方法见下文的程序源代码。

下文主要提供了智能小车按键调速前进完整程序原代码、电路原理图以及电路器件表。

智能小车核心板原理图STC15W4K56S4智能小车核心板器件(BOM)表实物图060306030603PIN插针PIN2x1406030603直插LQFP7x7-48 STC15W4K56S4智能小车核心板正面STC15W4K56S4智能小车核心板背面智能小车驱动板原理图51单片机(STC15W4K56S4)智能小车驱动板器件(BOM)表实物图直插直插直插直插直插直插直插直插直插直插PIN与PIN之间的间隔2.54mm插电池盒PIN与PIN间隔2.54mm,插电机3PIN插针,针与针间隔2.54mm插舵机红色插针和黑色插针3.3V红色插针、GND黑色插针PIN红色插针和黑色插针5V PIN红色插针和黑色插针VINPIN与PIN之间的间隔2.54mm 插MQ2模块针与针间隔2.54mm插GP2Y1014AU模块针与针间隔2.54mm语音播报实验时,串口4插语音播报模块针与针间隔2.54mmIO扩展用,没有必要不要焊接针与针间隔2.54mm插DHT11模块用4PIN插针,针与针间隔2.54mm用杜邦线连接超声波模块针与针间隔2.54mm插蓝牙模块(要原厂原装的)用8PIN插针,针与针间隔2.54mm杜邦线连接红外循迹避障模块用4PIN插针,针与针间隔2.54mm用杜邦线连接测速模块针与针间隔2.54mm插5V的LCD1602液晶MPU6050不要焊接。

PWM调速循迹智能小车程序精编

PWM调速循迹智能小车程序精编

P W M调速循迹智能小车程序精编Lele was written in 202132m/*-------------------------------- 控速模块-----------------------------------*/#defineP03 P0_3 . ");DisplayString(0x0,1,"DesignedBy202");Delay(300);WriteCmd(LCD_CLS);EA=1; ");Delay(50);WriteCmd(LCD_CLS);IsSelectingMode=True;while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0," LineMode ");DisplayString(0x0,1,"Next Yes");Delay(300); . ");DisplayString(0x0,1,"Designedby202");if(SelectedMode==Line&&AutoMode==0)flag=Area0;elseflag=1;while(flag<5){if(AutoMode==1) ;DisplaySingleChar(0x07,1,PassTime2); DisplaySingleChar(0x08,1,PassTime3);}else{DisplaySingleChar(0x04,1,PassTime1); DisplaySingleChar(0x05,1,PassTime2); DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,PassTime3); DisplaySingleChar(0x08,1,PassTime4);}}/*------------------------------------ 显示平均速度----------------------------------------*/ voidDisplayAVGSpeed(void){intSpeed1=0x30; ;DisplaySingleChar(0x07,1,Speed2); DisplaySingleChar(0x08,1,Speed3);}/*------------------------------------- 显示路程----------------------------------------*/ voidDisplayDistance(void){intDistance1=0x30;intDistance2=0x30;intDistance3=0x30;intDistance4=0x30;if((int)(Distance*100)<100){Distance1+=0;Distance2+=(int)(Distance*100)/10;Distance3+=(int)(Distance*100)%10;}elseif((int)(Distance*100)>100&&(int)(Distance*100)<1000){Distance1+=(int)(Distance*100)/100;Distance2+=(int)(Distance*100)/10%10;Distance3+=(int)(Distance*100)%10;}else{Distance1+=(int)(Distance*100)/1000; Distance2+=(int)(Distance*100)/100%10; Distance3+=(int)(Distance*100)/10%10; Distance4+=(int)(Distance*100)%10;}if((int)(Distance*100)<1000){DisplaySingleChar(0x05,1,Distance1); DisplaySingleChar(0x06,1,'.'); DisplaySingleChar(0x07,1,Distance2); DisplaySingleChar(0x08,1,Distance3); }else{DisplaySingleChar(0x04,1,Distance1); DisplaySingleChar(0x05,1,Distance2); DisplaySingleChar(0x06,1,'.'); DisplaySingleChar(0x07,1,Distance3); DisplaySingleChar(0x08,1,Distance4); }}/*------------------------------------- 中断初始化-------------------------------------*/voidINTInit(void){EA=1; //开总中断IT0=1; //INTO边沿触发PX0=1; //INTO优先级为高级EX1=1; //开INT1中断IT1=1; //INT1边沿触发PX1=1; //INT1优先级为高级Clock0_Init(); //初始化时钟中断TMOD=0x11; //T0/T1定时方式1ET0=0x01; //开T0中断ET1=0x01; //开T1中断}voidClock0_Init(void){TR0=0x01; //启动T0TH0=Thx0; //定时初值TL0=Tlx0;}voidClock1_Init(void){TR1=0x01; //启动T1TH1=0x3C; //定时初值-50ms中断一次TL1=0x0B0;}/************************************************** *****************************************\** 中断处理程序**\************************************************** *****************************************//*----------------------------------- 外部中断0----------------------------------------*\外部中断0有两个功能(1)作为菜单选择的Next键(2)作为测速的计数器\*-----------------------------------------------------------------------------------------*/ voidSpeedINT(void)interrupt0 //中断INT0{if(SelectedAll==False) //如果模式和速度还没有选择完毕,则此中断作为Next键Next=True;if(Running==True) //如果模式和速度已经选择完毕,则此中断作为测速中断SpeedCount++;if(ChoosingDisplay==True) //如果是在选择要显示的内容Next=True;}/*----------------------------------- 外部中断----------------------------*\外部中断1有两个功能(1)作为菜单选择的确定键/返回键(2)控速\*-----------------------------------------------------------------------------------------*/ voidCtrSpeedINT(void)interrupt2 //中断INT1{if(SelectedAll==False) //如果模式和速度还没有选择完毕,则此中断作为确定键{if(IsSelectingMode==True) //模式选择标志ModeSelected=True;if(IsSelectingSpeed==True) //速度选择标志SpeedSelected=True;}if(Running==True) //如果模式和速度选择已经完毕,则此中断作为控速中断{if(Area0==0) //经过第一条铁线(即起跑线),开始计时,开始测速{EX0=1;Clock1_Init();P31=0; //过起跑线,背光灭}if(Area0==1)LowSpeedArea1StartTime=PassTime; //读取进入第一个低速区的时刻if(Area0==2)LowSpeedArea1EndTime=PassTime;//读取离开第一个低速区的时刻,也就是进入高速区的时刻if(Area0==3)HighSpeedAreaEndTime=PassTime;//读取离开高速区的时刻,也就是进入第二个低速区的时刻if(Area0==4)LowSpeedArea2EndTime=PassTime; //读取离开第二个低速去的时刻if(AutoMode==1) //自动模式{PassLine++;switch(PassLine){case5 :PassLineID=1;break;case10:PassLineID=2;break;default:PassLineID=PassLineID;break;}else{if(SelectedMode==Line) //直线模式{Thx0=Thx[Area0++];Tlx0=Tlx[Area1++];if(Area0==5)EX1=0;}else //S型模式{Nocurve++;Round++;if(Roundid==1&&Round==2){Round++;Roundid=0;}Back=0;Back0=0;EX1=0;}}IE1=0;if(AutoDisplay==True){GoToChoosingDisplay=True;}if(ChoosingDisplay==True){SelectedShow=True;SelectedReturn=True;Selected=True;}}/*-------------------------------------- T0中断----------------------------------------*\T0中断用来输出方波以控制速度\*-----------------------------------------------------------------------------------------*/voidTime0INT(void)interrupt1 //T0中断{if(AutoMode==1){IsT0INT*=-1;switch(PassLine){ case2 :PrepareDistance=Distance;break;case3 :FirstDistance=Distance-PrepareDistance;break; case4 :SecondDistance=Distance-PrepareDistance-FirstDistance;break;case5 :ThirdDistance=Distance-PrepareDistance-FirstDistance-SecondDistance;break;default:break;}switch(PassLineID){case0 :{if(IsT0INT==1){TR0=0x01;TH0=0xec;TL0=0x78;} //5mselse{TR0=0x01;TH0=0xb1;TL0=0xe0;} //20ms}break;case1 :{if(PassLine==5){FirstHigh=(int)(65536-20*FirstDistance/(15*Count*Rate-FirstDistance)*1000);SecondHigh=(int)(65536-20*SecondDistance/(15*Rate-SecondDistance)*1000);ThirdHigh=(int)(65536-20*FirstDistance/(15*Count*Rate-FirstDistance)*1000);TR0=0x01;TH0=0xf4;TL0=0x48;}}break;case2 :{AutoMode=0;SelectedMode=Line;Area0=Area1=0;PassTime =0;Distance=0;TR0=0x01;TH0=0xf4;TL0=0x48;Thx[0]=Thx[1]=((FirstHigh &0xf0)>>8);Tlx[0]=Tlx[1]=(FirstHigh&0x0f);Thx[2]=Thx[2]=((SecondHigh&0xf0)>>8);Tlx[2]=Tlx[2]= (SecondHigh&0x0f);Thx[3]=Thx[3]=((ThirdHigh &0xf0)>>8);Tlx[3]=Tlx[3]=(ThirdHigh&0x0f);Thx[4]=Thx[4]=0xff;Tlx[4]=Tlx[4]=0xff;}break;default:break;}}else{if(SelectedMode==Line) {IsT0INT*=-1;if(Area0<5){if(IsT0INT==1)Clock0_Init();else{TR0=0x01; //启动T0TH0=Thx1; //定时初值TL0=Tlx1;}}elseIsT0INT=-1;else{IsT0INT2*=-1;if(IsT0INT2==1){TR0=0x01;TH0=0xd8;TL0=0xf0;} //10ms else{TR0=0x01;TH0=0xb1;TL0=0xe0;} //20ms Back++;if(Back>=90)Back0=70;if((Nocurve<2)&&(Back0>0)&&Back!=0) {if(Back0<=65)Roundid=1;Back0--;}if((Nocurve>2)&&Back>=450){Stop=1;IsT0INT2=-1;}if(Stop==1)flag=6;}TF0=0;}/*----------------------------------- T1中断----------------------------------------*\T1中断用来定时\*-----------------------------------------------------------------------------------------*/voidTime1INT(void)interrupt3 //T1中断{Clock1_Init();Time1INTCount++;if(Time1INTCount==10) //500ms扫描一次{IsT1INT=1;if(Area0>5)P03=0;Time1INTCount=0;}TF1=0;}。

智能循迹小车程序

智能循迹小车程序

智能小车程序(共三个)第一个:#include "reg52.h"#define det_Dist 2.55 //单个脉冲对应的小车行走距离,其值为车轮周长/4#define RD 9 //小车对角轴长度#define PI 3.1415926#define ANG_90 90#define ANG_90_T 102#define ANG_180 189/*============================全局变量定义区============================*/sbit P10=P1^0; //控制继电器的开闭sbit P11=P1^1; //控制金属接近开关sbit P12=P1^2; //控制颜色传感器的开闭sbit P07=P0^7; //控制声光信号的开启sbit P26=P2^6; //接收颜色传感器的信号,白为0,黑为1sbit P24=P2^4; //左sbit P25=P2^5; //右接收左右光传感器的信号,有光为0unsigned char mType=0; //设置运动的方式,0 向前1 向左2 向后3 向右unsigned char Direction=0; //小车的即时朝向0 朝上1 朝左2 朝下3 朝右unsigned sX=50; unsigned char sY=0; //小车的相对右下角的坐标CM(sX,sY)unsigned char StartTask=0; //获得铁片后开始执行返回卸货任务,StartTask置一unsigned char Inter_EX0=0; // 完成一个完整的任务期间只能有一次外部中断// Inter_EX0记录外部中断0的中断状态// 0 动作最近的前一次未中断过,// 1 动作最近的前一次中断过unsigned char cntIorn=0; //铁片数unsigned char bkAim=2; //回程目的地,0为A仓库,1为B仓库,2为停车场,//(在MAIN中接受铁片颜色判断传感器的信号来赋值)unsigned char Light_Flag=0;//进入光引导区的标志(1)unsigned int cntTime_5Min=0;//时间周期数,用于T0 精确定时unsigned int cntTime_Plues=0; //霍尔开关产生的脉冲数/*============================全局变量定义区============================*//*------------------------------------------------*//*-----------------通用延迟程序-------------------*//*------------------------------------------------*/void delay(unsigned int time) // time*0.5ms延时{unsigned int i,j;for(j=0;j<time;j++){for(i=0;i<60;i++){;}}}/*-----------------------------------------------*//*-------------------显示控制模块----------------*//*-----------------------------------------------*//*数码管显示,显示铁片的数目(设接在P0,共阴)*/void Display(unsigned char n){char Numb[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x37,0x77}; P0=Numb[n];}/*-----------------------------------------------*//*-------------------传感器模块------------------*//*-----------------------------------------------*//*光源检测程序: *//*用于纠正小车运行路线的正确性*/unsigned char LightSeek(){ void Display(unsigned char);bit l,r;l=P24;r=P25;if(l==0&&r==1){//Display(1);return (3); //偏左,向右开}if(r==0&&l==1){//Display(3);return(1); //偏右,向左开}if((l==1&&r==1)||(l==0&&r==0)){//Display(9);return(0); //没有偏离,前进}}/*铁片检测程序: *//*判断铁片的颜色,设定bkAim,0为A仓库,1为B仓库,2为停车场*/ void IornColor(){delay(4000);bkAim=(int)(P26);Display((int)(P26)+2);}/*-----------------------------------------------*//*------------------运动控制模块-----------------*//*-----------------------------------------------*//*====基本动作层:完成基本运动动作的程序集====*//*运动调整程序: *//*对小车的运动进行微调*/void ctrMotor_Adjust(unsigned char t){if(t==0){P2=P2&240|11; //用来解决两电机不对称的问题delay(6);}if(t==3){P2=P2&250; //向左走delay(1);}if(t==1){P2=(P2&245);delay(1); //向右走}P2=((P2&240)|15);delay(10);}/*直走程序: *//*控制小车运动距离,dist为运动距离(cm),type为运动方式(0 2)*/ /*只改变小车sX 和sY的值而不改变Direction的值. */ void ctrMotor_Dist(float dist,unsigned char type){unsigned char t=0;mType=type;P2=((P2&240)|15);cntTime_Plues=(int)(dist/det_Dist);while(cntTime_Plues){if(Inter_EX0==1&&StartTask==0){cntTime_Plues=0;break;}if(Light_Flag==1) t=LightSeek();if(type==0) //向前走{P2=P2&249;delay(40);ctrMotor_Adjust(t);}if(type==2) //向后退{P2=P2&246;delay(50);ctrMotor_Adjust(t);}P2=((P2&240)|15);if(mType==2) delay(60);//刹车制动0.5mselse delay(75);}}/*拐弯程序: *//*控制小车运动角度,type为运动方式(1 3)*//*只改变小车Direction的值而不改变sX 和sY的值*/void ctrMotor_Ang(unsigned char ang,unsigned char type,unsigned char dir) {unsigned char i=0;mType=type;P2=((P2&240)|15);cntTime_Plues=(int)((PI*RD*90/(180*det_Dist)*1.2)*ang/90);while(cntTime_Plues){if(Inter_EX0==1&&StartTask==0){cntTime_Plues=0;break;}if(type==1) //向左走{P2=P2&250;delay(100);ctrMotor_Adjust(0);}if(type==3) //向右走{P2=P2&245;delay(100);ctrMotor_Adjust(0);}P2=((P2&240)|15);delay(50);//刹车制动0.5ms}if(!(Inter_EX0==1&&StartTask==0)){Direction=dir;}}/*====基本路线层:描述小车基本运动路线的程序集====*//*当小车到达仓库或停车场时,放下铁片或停车(0,1为仓库,2为停车场)*/void rchPlace(){unsigned int time,b,s,g;time=(int)(cntTime_5Min*0.065535);//只有一个数码管时,轮流显示全过程秒数个十百b=time%100;s=(time-b*100)%100;g=(time-b*100-s*10)%10;if(bkAim==2){//到达停车场了,停车EA=0;P2=((P2&240)|15);while(1){Display(10); //Ndelay(2000);Display(cntIorn);delay(2000);Display(11);//Adelay(2000);Display(b);delay(2000);Display(s);delay(2000);Display(g);delay(2000);}}else{if(Inter_EX0==1&&StartTask==1)P10=0; //到达仓库,卸下铁片}}/*无任务模式: *//*设置小车的固定运动路线,未发现铁片时的运动路线*/void BasicRoute(){ //Light_Flag=1;ctrMotor_Dist(153,0);//Light_Flag=0;ctrMotor_Ang(ANG_90,1,1);ctrMotor_Dist(100-sX,0);ctrMotor_Dist(125,2);ctrMotor_Dist(73,0);ctrMotor_Ang(ANG_90,1,2);//Light_Flag=1;ctrMotor_Dist(153,0);//Light_Flag=0;ctrMotor_Ang(ANG_180,1,0);rchPlace();}/*任务模式: *//*设置小车的发现铁片后的运动路线*/void TaskRoute(){//基本运行路线表,记载拐弯0 向前1 左拐2 向后3 右拐,正读去A区;反读去B区StartTask=1;ctrMotor_Ang(ANG_90_T,1,2);if(bkAim==1) //仓库A{ctrMotor_Dist(10,0);P2=((P2&240)|15);delay(60);ctrMotor_Ang(ANG_90_T,1,3);ctrMotor_Dist(100-sX,2);ctrMotor_Ang(ANG_90_T,1,2);Light_Flag=1;ctrMotor_Dist(153,2);Light_Flag=0;// ctrMotor_Ang(208,1,0);}else if(bkAim==0) //仓库B{ctrMotor_Dist(10,0);P2=((P2&240)|15);delay(60);ctrMotor_Ang(ANG_90_T,1,3);ctrMotor_Dist(100-sX,0);ctrMotor_Ang(ANG_90_T,1,0);Light_Flag=1;ctrMotor_Dist(153,2);Light_Flag=0;//ctrMotor_Ang(208,1,0);}delay(5000);rchPlace();}/*---------------------------------------------*//*-------------------主程序段------------------*/ /*---------------------------------------------*/void main(){delay(4000);P2=0xff; //初始化端口P07=0;P1=0;TMOD=0x01; //初始化定时器0/1 及其中断TL0=0;TH0=0;TR0=1;ET0=1;ET1=1;IT0=1; //初始化外部中断EX0=1;IT1=1;EX1=1;EA=1;P11=1;while(1){Display(cntIorn);bkAim=2;BasicRoute();if(Inter_EX0==1){TaskRoute();//按获得铁片后的路线运动IE0=0;EX0=1;}Inter_EX0=0;}}/*----------------------------------------------------*//*----------------------中断程序段--------------------*//*----------------------------------------------------*//*定时器0中断程序: *//*当时间过了5分钟,则就地停车并进入休眠状态*/ void tmOver(void) interrupt 1{cntTime_5Min++;TL0=0;TH0=0;if(cntTime_5Min>=4520){Display(5);P2=((P2&240)|15);EA=0; //停车程序P07=1;delay(4000);PCON=0X00;while(1);}}/*外部中断0中断程序: *//*发现铁片,发出声光信号并将铁片吸起,发光二极管和蜂鸣器*//*并联在一起(设接在P07). 0为A仓库,1为B仓库,2为停车场*/ void fndIorn(void) interrupt 0{unsigned char i;P10=1;P2=((P2&240)|15); //停车P07=1;delay(1000);//刹车制动0.5msP07=0;Inter_EX0=1;cntIorn++;Display(cntIorn);for(i=0;i<40;i++){P2=P2&249;delay(2);P2=((P2&240)|15);delay(2);}P2=P2&249;delay(100);P2=((P2&240)|15); //停车IornColor(); //判断铁片黑白,设置bkAimfor(i=0;i<95;i++)P2=P2&249;delay(3);P2=((P2&240)|15);delay(2);}P2=((P2&240)|15); //停车delay(4000); //把铁片吸起来EX0=0;}/*外部中断1中断程序: *//*对霍尔开关的脉冲记数,对小车的位置进行记录,以便对小车进行定位*/ void stpMove(void) interrupt 2{cntTime_Plues--;if(Direction==0) //向上{if(mType==0) sY+=det_Dist;else if(mType==2)sY-=det_Dist;}else if(Direction==1) //向左{if(mType==0) sX+=det_Dist;else if(mType==2)sX-=det_Dist;}else if(Direction==2) //向下{if(mType==0) sY-=det_Dist;else if(mType==2)sY+=det_Dist;}else if(Direction==3) //向右{if(mType==0) sX-=det_Dist;else if(mType==2)sX+=det_Dist;}第二个:#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit moto1=P1^5;sbit moto2=P1^6;sbit moto3=P2^0;sbit moto4=P2^1;sbit en1=P1^7;sbit en2=P2^2;//*循迹口七个红外传感器*///////////////sbit left1=P1^0;//*左边传感器*//sbit left2=P1^1;sbit left3=P1^2;sbit mid=P1^3;//*黑线位置*//sbit right1=P1^4;sbit right2=P2^3;sbit right3=P2^4;//*右边传感器*//////////////// sbit hled=P0^0;sbit bled=P0^1;sbit lled=P0^2;sbit rled=P0^3;sbit bizhang=P2^5;uchar pro_head;uchar pro_back;uchar i;uchar j; //前后占空比标志void delay(uint z){uchar i;while(z--){for(i=0;i<121;i++);}}/********初始化定时器,中断************/ void init(){TMOD=0x01;TH0=(65536-100)/256;TL0=(65536-100)%256;EA=1;TR0=1;en1=1;en2=1;}void time0(void) interrupt 1{i++;j++;if(i<=pro_back){en1=1;}else{en1=0;}if(i==40){en1=~en1;i=0;}if(j<=pro_head){en2=1;}else{en2=0;}if(j==40){en2=~en2;j=0;}TH0=(65536-100)/256;TL0=(65536-100)%256;}void qianjin()//*直行*///////////////////// {pro_back=15;pro_head=5;moto1=0;moto2=0;moto4=0;lled=1;rled=1;bled=1;}void turn_right1()//*右转1函数*//{pro_back=10;pro_head=15;moto1=0;moto2=1;moto3=1;moto4=0;}。

智能循迹小车程序代码

智能循迹小车程序代码

/****************************************************************************硬件连接P1_4接驱动模块ENA使能端,输入PWM信号调节速度P1_5接驱动模块ENB使能端,输入PWM信号调节速度P1_0 P1_1接IN1 IN2 当P1_0=1,P1_1=0; 时左电机正转驱动蓝色输出端OUT1 OUT2接左电机P1_0 P1_1接IN1 IN2 当P1_0=0,P1_1=1; 时左电机反转P1_2 P1_3接IN3 IN4 当P1_2=1,P1_3=0; 时右电机正转驱动蓝色输出端OUT3 OUT4接右电机P1_2 P1_3接IN3 IN4 当P1_2=0,P1_3=1; 时右电机反转P1_0接四路寻迹模块接口第一路输出信号即中控板上面标记为OUT1P1_1接四路寻迹模块接口第二路输出信号即中控板上面标记为OUT2P1_2接四路寻迹模块接口第三路输出信号即中控板上面标记为OUT3P1_3接四路寻迹模块接口第四路输出信号即中控板上面标记为OUT4八路寻迹传感器有信号(白线)为0 没有信号(黑线)为1****************************************************************************/#include<AT89x51.H>#define Right_moto_pwm P1_4 //接驱动模块ENA使能端,输入PWM信号调节速度#define Left_moto_pwm P1_5 //接驱动模块ENB使能端,输入PWM 信号调节速度#define Left_1_led P2_0 //四路寻迹模块接口第一路#define Left_2_led P2_1 //四路寻迹模块接口第二路#define Right_1_led P2_2 //四路寻迹模块接口第三路#define Right_2_led P2_3 //四路寻迹模块接口第四路#define Left_moto_go {P1_0=0,P1_1=1;} //左电机前进#define Left_moto_back {P1_0=1,P1_1=0;} //左电机后退#define Left_moto_stop {P1_0=1,P1_1=1;} //左电机停转#define Right_moto_go {P1_2=0,P1_3=1;} //右电机前转#define Right_moto_back {P1_2=1,P1_3=0;} //右电机后退#define Right_moto_stop {P1_2=1,P1_3=1;} //右电机停转#define uchar unsigned char#define uint unsigned intuchar pwm_val_left =0;uchar push_val_left =0; //左电机占空比N/10uchar pwm_val_right =0;uchar push_val_right=0; //右电机占空比N/10bit Right_moto_stp=1;bit Left_moto_stp =1;/**************************************************************** ********/void run(void)//前进函数{push_val_left =13; //PWM 调节参数1-20 1为最慢,20是最快改这个值可以改变其速度push_val_right =15; //PWM 调节参数1-20 1为最慢,20是最快改这个值可以改变其速度Left_moto_go ;//左电机前进Right_moto_go ; //右电机前进}/**************************************************************** ********/void left(void) //左转函数{push_val_left =8;push_val_right =9;Right_moto_go;//右电机继续Left_moto_stop;//左电机停走}/************************************************************************/void right(void)//右转函数{push_val_left =8;push_val_right =9;Right_moto_stop;//右电机停走Left_moto_go;//左电机继续}void Delayms(uint x){uchar i;while(x--)for(i=0;i<120;i++);}void stop(void){Right_moto_stop;//右电机停走Left_moto_stop;//左电机停走Delayms(3000);run();Delayms(100);}/*************************PWM调制电机转速********************************/void pwm_out_left_moto(void) //左电机调速,调节push_val_left的值改变电机转速,占空比{if(Left_moto_stp){if(pwm_val_left<=push_val_left)Left_moto_pwm=1;elseLeft_moto_pwm=0;if(pwm_val_left>=20)pwm_val_left=0;}elseLeft_moto_pwm=0;}void pwm_out_right_moto(void) //右电机调速,调节push_val_left的值改变电机转速,占空比{if(Right_moto_stp){if(pwm_val_right<=push_val_right)Right_moto_pwm=1;elseRight_moto_pwm=0;if(pwm_val_right>=20)pwm_val_right=0;}elseRight_moto_pwm=0;}/***************************************************/void xunji(){switch(P2&0x0f){case 0x00: // 全部没有压线,直走run(); break;case 0x01:// 右压线,左转left(); break;case 0x02: // 右压线,左转left(); break;case 0x04: // 左压线,转右right(); break;case 0x08: // 左压线,右转right();break;case 0x0f:stop();break;default:run(); break;}}/***********TIMER0中断服务子函数产生PWM信号**********/ void timer0()interrupt 1 using 2{TH0=0XF8; //2Ms定时TL0=0X30;pwm_val_left++;pwm_val_right++;pwm_out_left_moto();pwm_out_right_moto();}/***************************************************/ void main(void){TMOD=0X01;TH0= 0XF8; //2ms定时TL0= 0X30;TR0= 1;ET0= 1;EA = 1;while(1)/*无限循环*/{xunji();} }。

PWM调速 循迹__智能小车程序文件

PWM调速 循迹__智能小车程序文件

//T0产生双路PWM信号,L298N为直流电机调速,接L298N时相应的管脚上最好接上10K 的上拉电阻。

/* 晶振采用12M,产生的PWM的频率约为100Hz */#include<reg51.h>#include<math.h>#define uchar unsigned char#define uint unsigned intsbit en1=P3^4; /* L298的Enable A */sbit en2=P3^5; /* L298的Enable B */sbit s1=P1^0; /* L298的Input 1 */sbit s2=P1^1; /* L298的Input 2 */sbit s3=P1^3; /* L298的Input 3 */sbit s4=P1^2; /* L298的Input 4 */sbit R=P2^0;sbit C=P2^1;sbit L=P2^2;sbit key=P1^4;uchar t=0; /* 中断计数器 */uchar m1=0; /* 电机1速度值 */uchar m2=0; /* 电机2速度值 */uchar tmp1,tmp2; /* 电机当前速度值 *//* 电机控制函数 index-电机号(1,2); speed-电机速度(0-100) */void motor(uchar index, char speed){if(speed<=100){if(index==1) /* 电机1的处理 */{m1=abs(speed); /* 取速度的绝对值 */s1=1;s2=0;}if(index==2) /* 电机2的处理 */{m2=abs(speed); /* 电机2的速度控制 */s3=1;s4=0;}}}void Back(void){s1=0;s2=1;s3=1;s4=0;}void GO(void){s1=1;s2=0;s3=1;s4=0;}void TL(void){s1=1;s2=0;s3=0;s4=1;}void TR(void){s1=0;s2=1;s3=1;s4=0;}void STOP(void){s1=1;s2=1;s3=1;s4=1;}/*void delay(uint j) /* 简易延时函数 */ {for(j;j>0;j--);} */void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void main(){uchar i=0,j=0;TMOD=0x02; /* 设定T0的工作模式为2 ,8位自动重置定时器,每过几个机器周期,计数器加一*/TH0=0x9B; /* 装入定时器的初值,计数100次溢出 */TL0=0x9B; /*装入时间常数*/EA=1; /* 开中断 */ET0=1; /* 定时器0允许中断 */TR0=1; /* 启动定时器0 */while(1){if(key==1){/* 电机实际控制演示 */if(i<=100) // 正转加速{motor(1,i);motor(2,i);delay(5000);i++;}else{GO();}}else{EA=0;while(1){if((L|C|R)==0)STOP();if(L&R)GO();if(L==0){while(C){TL();}}if(R==0){while(C){TR();}}}}}}void timer0() interrupt 1 /* T0中断服务程序 */{if(t==0) /* 1个PWM周期完成后才会接受新数值 */{ tmp1=m1;tmp2=m2;}if(t<tmp1) en1=1; else en1=0; /* 产生电机1的PWM信号 */ if(t<tmp2) en2=1; else en2=0; /* 产生电机2的PWM信号 */ t++;if(t>=100) t=0; /* 1个PWM信号由100次中断产生 */}#include<intrins.h>#include<AT89X52.h>/****************************************************************************** **\** 宏定义区**\****************************************************************************** **//*------------------------------- LCD模块------------------------------------*/ #defineLCD_RW P2_6 //读写控制端#defineLCD_RS P2_7 //数据命令选择端#defineLCD_E P2_5 //执行使能端#defineLCD_Data P1 //P1口#defineWrite 0x00 //低电平写入#defineRead 0x01 //高电平读出#defineData 0x01 //高电平选择数据#defineCmd 0x00 //低电平选择命令#defineEnable 0x00 //跃变到低电平时执行命令#defineDisable 0x01#defineTrue 0x01#defineFalse 0x00#defineLCD_Init 0x38 //初始化模式#defineLCD_DispCtr 0x0C //开显示及光标设置#defineLCD_CloseCtr 0x08 //关显示#defineLCD_CLS 0x01 //清屏幕#defineLCD_EnterSet 0x06 //显示光标#defineBusy P1_7 //忙信号/*-------------------------- 测速/测距/测时模块-------------------------------*/#defineCircleLength 0.132 //小车转一轮的长度为.132m/*-------------------------------- 控速模块-----------------------------------*/#defineP03 P0_3 //后电机#defineP04 P0_4 //后电机#defineP01 P0_1 //前电机#defineP02 P0_2 //前电机#defineP31 P0_5 //控制液晶背光#defineP33 P3_3/*------------------------------ 菜单选择模块---------------------------------*/#defineLine 0x00 //0代表直线模式#defineCurve 0x01 //1代表S型模式#defineNormal 0x00 //0 代表正常速度#defineLow 0x01 //1 代表低速#defineHigh 0x02 //2 代表高速/****************************************************************************** ***\** 全局函数声明区 **\****************************************************************************** ***//*------------------------------- LCD模块-------------------------------------*/voidLCDInit(void); //LCD初始化voidSetWriteCmd(void); //设置写命令模式voidSetReadCmd(void); //设置读命令模式voidSetWriteData(void); //设置写数据模式voidWriteCmd(charcmd); //写命令voidWriteData(charddata); //写数据voidExecuteCmd(void); //执行命令voidSetXY(charx,chary); //定位显示地址voidDisplaySingleChar(charx,chary,charcchar); //显示单个字符voidDisplayString(charx,chary,char*str); //显示一段字符串voidDelay(unsignedinttime); //延时主程序voidDelayUs(unsignedinttime); //延时子程序bit IsBusy(void); //判断忙标志函数voidDisplayTime(void); //显示时间voidDisplayAVGSpeed(void); //显示平均速度voidDisplayDistance(void); //显示路程/*-------------------------- 测速/测距/测时模块-------------------------------*/voidINTInit(void); //所有中断初始化voidSpeedINT(void); //测速中断voidComputeTime(void);voidComputeSpeedANDDistance(void); //计算速度和距离/*-------------------------------- 控速模块-----------------------------------*/voidCtrSpeedINT(void); //控速中断voidTime0INT(void);voidTime1INT(void); //控速单位时间中断voidClock0_Init(void); //时钟中断初始化voidClock1_Init(void); //时钟中断初始化voidCtrSpeed(void);/****************************************************************************** **\** 全局变量区**\****************************************************************************** **/float SpeedCount=0; //测速计数脉冲float Speed=0.0;float Distance=0.0;char Time1INTCount=0; //T1中断时间计时float PassTime=0.00; //小车行走的时间short IsT0INT=1;bit IsT1INT; //判断T1是否已经响应中断short IsT0INT2=1;char Thx[5]={0xf4,0xf4,0xc5,0xf4,0xff}; //3ms,3ms,15ms,3ms char Tlx[5]={0x48,0x48,0x68,0x48,0xff};char Thx0=0xd8;char Tlx0=0xf0;char Thx1=0xb1; //20mschar Tlx1=0xe0;short Round=0;short Back=0;short Back0=0;bit Backid;bit Stop=0;char Area0=0;char Area1=0; //区域变量char LowSpeedArea1StartTime;char LowSpeedArea1EndTime;char HighSpeedAreaEndTime;char LowSpeedArea2EndTime;char LowSpeedArea1PassTime=0; //第一个低速区通过时间char HighSpeedAreaPassTime=0; //高速区通过时间char LowSpeedArea2PassTime=0; //第二个低速区通过时间char ReadyToGo=4; //倒计时char flag;bit Roundid=0;char Nocurve=0;char ChangeFlag;char Mode;bit Running;bit SelectedAll; //模式和速度是否选择完毕标志bit IsSelectingMode; //模式选择标志bit IsSelectingSpeed; //速度选择标志bit ModeSelected; //已经被选择的模式标志char SelectedMode=10; //模式选择是否完毕标志bit Next; //Next键标志bit SpeedSelected; //已经被选中的速度方案标志char SelectedSpeed; //速度选择是否完毕标志bit ChoosingDisplay; //人工选择菜单开始标志bit SelectedShow; //显示选择标志bit SelectedReturn; //返回选择标志bit Selected; //确定/返回键选择标志bit ReturnSelection; //返回键启用标志bit AVGSpeedShow; //平均速度显示标志bit TotalDistanceShow; //总路程显示标志bit ReturnMain; //返回主菜单标志bit AutoDisplay; //自动显示标志bit GoToChoosingDisplay; //人工选择标志bit AutoMode=0;char PassLineID=0;char PassLine=0;float PrepareDistance;float FirstDistance;float SecondDistance;float ThirdDistance;int FirstHigh;int SecondHigh;int ThirdHigh;float Rate=1.25; //5ms时的速度float Count=4; //时间的倍数/****************************************************************************** **\** 全局函数实现区 **\****************************************************************************** **//*-------------------------------- 主函数------------------------------------*/ voidmain(){P01=0;P02=0;P03=0;P04=0;P31=1; //单片机复位,背光开Delay(40); //延时等待LCD启动LCDInit(); //初始化LCDDisplayString(0x0,0," Starting... ");DisplayString(0x0,1,"DesignedBy202");Delay(300);WriteCmd(LCD_CLS);EA=1; //开总中断EX0=1; //开INT0中断IT0=1; //INTO边沿触发EX1=1; //开INT1中断IT1=1; //INT1边沿触发SelectedAll=False; //开始模式和速度选择/*------------------------------ 模式选择---------------------------------*/ DisplayString(0x0,0,"ChooseTheMode");DisplayString(0x0,1,"youwant. ");Delay(50);WriteCmd(LCD_CLS);IsSelectingMode=True;while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0," LineMode ");DisplayString(0x0,1,"Next Yes");Delay(300); //延时消除抖动while(1) //不断检测中断,直到按确定键或是NEXT键{if(Next==True) //如果按Next键则直接跳出break;if(ModeSelected==True) //如果按确定键则设置模式为Line并跳出{SelectedMode=Line;break;} //如果什么键都没有按下,那么一直显示等待}if(ModeSelected==True) //按下了确定键,退出模式选择{IsSelectingMode=False;break;}if(Next==True) //按下了Next键,显示下一个菜单项{Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0," CurveMode ");DisplayString(0x0,1,"Next Yes");Delay(300); //延时消除抖动while(1) //不断检测中断,直到按确定键或是Next键{if(Next==True) //如果再一次按下Next键,则跳出break;if(ModeSelected==True) //如果按下确定键,则设置模式为Curve,并跳出{SelectedMode=Curve;break;}}}if(ModeSelected==True) //按下了确定键,退出模式选择{IsSelectingMode=False;break;}if(Next==True) //再一次按下了Next键,则循环模式选择{Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0," AutoMode ");DisplayString(0x0,1,"Next Yes");Delay(300); //延时消除抖动while(1){if(Next==True)break;if(ModeSelected==True){AutoMode=1;break;}}}if(ModeSelected==True){IsSelectingMode=False;break;}if(Next==True){Next=False;continue;}}Delay(50);WriteCmd(LCD_CLS);/*------------------------------ 速度选择---------------------------------*/ if(SelectedMode==Line&&AutoMode==0){DisplayString(0x0,0," NowChoosea ");DisplayString(0x0,1," kindofSpeed");Delay(50);WriteCmd(LCD_CLS);IsSelectingSpeed=True;while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0,"NormalSpeed ");DisplayString(0x0,1,"Next Yes");Delay(300); //延时消除抖动while(1){if(Next==True) //如果按Next键则直接跳出break;if(SpeedSelected==True) //如果按确定键则设置速度为Normal并跳出{Thx[0]=0xec;Tlx[0]=0x78; //5msThx[1]=0xf0;Tlx[1]=0x60; //4msThx[2]=0x8a;Tlx[2]=0xd0; //30msThx[3]=0xf4;Tlx[3]=0x48; //3msSelectedSpeed=Normal;break;} //如果什么键都没有按下,那么一直显示等待}if(SpeedSelected==True) //按下了确定键,退出速度选择{IsSelectingSpeed=False;break;}if(Next==True){Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0," Low Speed ");DisplayString(0x0,1,"Next Yes");Delay(300); //延时消除抖动while(1)if(Next==True) //如果再一次按下Next键,则跳出break;if(SpeedSelected==True) //如果按下确定键,则设置速度为Low,并跳出{SelectedSpeed=Low; //这里没有速度设置,因为默认速度就是Lowbreak;}}}if(SpeedSelected==True) //按下了确定键,退出速度选择{IsSelectingSpeed=False;break;}if(Next==True){Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0," High Speed ");DisplayString(0x0,1,"Next Yes");Delay(300); //延时消除抖动while(1){if(Next==True) //如果再一次按下Next键,则跳出break;if(SpeedSelected==True) //如果按下确定键,则设置速度为High,并跳出{Thx[0]=0xe0;Tlx[0]=0xc0;//8msThx[1]=0xe0;Tlx[1]=0xc0; //8msThx[2]=0x63;Tlx[2]=0xc0; //40msThx[3]=0xec;Tlx[3]=0x78; //5msSelectedSpeed=High;break;}}}if(SpeedSelected==True) //按下了确定键,退出速度选择{IsSelectingSpeed=False;break;if(Next==True) //再一次按下了Next键,则循环速度选择{Next=False;continue;}}}SelectedAll=True; //标志模式选择和速度选择完毕Running=True;Delay(50);WriteCmd(LCD_CLS);/*------------------------- 显示所选择的模式和速度方案-------------------------*/if(SelectedMode==Line){DisplayString(0x0,0,"ChoosenModeis");DisplayString(0x0,1," Line ");Delay(50);WriteCmd(LCD_CLS);}if(SelectedMode==Curve){DisplayString(0x0,0,"ChoosenModeis");DisplayString(0x0,1," Curve ");Delay(50);WriteCmd(LCD_CLS);}if(AutoMode==1){DisplayString(0x0,0,"ChoosenModeis");DisplayString(0x0,1," AutoMode ");Delay(50);WriteCmd(LCD_CLS);}if(SelectedMode==Line){if(SelectedSpeed==Normal){DisplayString(0x0,0,"ChoosenSpeedis");DisplayString(0x0,1," Normal ");Delay(50);WriteCmd(LCD_CLS);if(SelectedSpeed==Low){DisplayString(0x0,0,"ChoosenSpeedis"); DisplayString(0x0,1," Low ");Delay(50);WriteCmd(LCD_CLS);}if(SelectedSpeed==High){DisplayString(0x0,0,"ChoosenSpeedis"); DisplayString(0x0,1," High ");Delay(50);WriteCmd(LCD_CLS);}}INTInit(); //初始化所有中断DisplayString(0x0,0,"LeftTimesToGo"); while(ReadyToGo--){DisplaySingleChar(0x7,1,ReadyToGo+0x30); DisplaySingleChar(0x09,1,'s');Delay(300);}WriteCmd(LCD_CLS);DisplayString(0x05,0,"Go!!!");Delay(100);WriteCmd(LCD_CLS);DisplayString(0x0,0," Living... "); DisplayString(0x0,1,"Designedby202");if(SelectedMode==Line&&AutoMode==0)flag=Area0;elseflag=1;while(flag<5){if(AutoMode==1) //自动模式{switch(PassLineID){case0 :{if(IsT0INT==1){P01=P02=P04=0;P03=1;}else{P01=P02=P03=P04=0;}}break;case1 :{P01=P02=P03=0;P04=1;}break;case2 :{P01=P02=P04=0;P03=1;}break;default:break;}}else{if(SelectedMode==Line) //直线模式{flag=Area0;if(IsT0INT==1){P03=1;P04=0;P01=P02=0;}else{P03=0;P04=0;P01=P02=0;}}else{ //S型模式if((Nocurve<2)&&Round!=0&&(Back0>0)&&Back!=0) {if(Backid==1){P01=1;P02=0;P03=0;P04=1;}else{P01=0;P02=1;P03=0;P04=1;}Back=1;}else{if(Round==0){if(IsT0INT2==1){P01=0;P02=0;P03=1;P04=0;}else{P01=0;P02=0;P03=0;P04=0;}}else{if(P33==0){if(IsT0INT2==1){P01=0;P02=0;P03=1;P04=0;}else{P01=0;P02=0;P03=0;P04=0;}}else{EX1=1;if(Round%2){if(IsT0INT2==1){P01=1;P02=0;P03=1;P04=0;Backid=1;}else{P01=1;P02=0;P03=0;P04=0;}}else{if(IsT0INT2==1){P01=0;P02=1;P03=1;P04=0;Backid=0;}else{P01=0;P02=1;P03=0;P04=0;}}}}}}}if(IsT1INT==1){IsT1INT=0;ComputeTime();ComputeSpeedANDDistance();}}//补中断路程,加上最后一次中断缺失的路程ComputeSpeedANDDistance();P04=1;P03=0;P01=P02=0;Delay(90);P03=0;P04=0; //行程结束,小车停止P31=1; //行程结束,背光开ET0=0x0; //关T0中断ET1=0x0; //关T1中断EX1=0x01; //开INT1中断Running=False;AutoDisplay=True; //默认情况下直线模式会自动显示各个区域经过的时间WriteCmd(LCD_CLS);if(SelectedMode==Line) //直线模式才显示{while(1){if(GoToChoosingDisplay==True)break;Delay(200);WriteCmd(LCD_CLS);Delay(200);DisplayString(0,0,"LowSpeedArea1");DisplayString(0,1,"Costed");DisplaySingleChar(0x0C,1,'s');LowSpeedArea1PassTime=LowSpeedArea1EndTime-LowSpeedArea1StartTime; DisplaySingleChar(0x0A,1,LowSpeedArea1PassTime%10+0x30);if(LowSpeedArea1PassTime>9) //通过第一个低速区的时间超过sDisplaySingleChar(0x0B,1,LowSpeedArea1PassTime/10+0x30);if(GoToChoosingDisplay==True)break;Delay(200);WriteCmd(LCD_CLS);Delay(200);DisplayString(0,0,"HighSpeedArea");DisplayString(0,1,"Costed");DisplaySingleChar(0x0C,1,'s');HighSpeedAreaPassTime=HighSpeedAreaEndTime-LowSpeedArea1EndTime; DisplaySingleChar(0x0A,1,HighSpeedAreaPassTime%10+0x30);if(HighSpeedAreaPassTime>9) //通过高速区的时间超过s DisplaySingleChar(0x0B,1,HighSpeedAreaPassTime/10+0x30);if(GoToChoosingDisplay==True)break;Delay(200);WriteCmd(LCD_CLS);Delay(200);DisplayString(0,0,"LowSpeedArea2");DisplayString(0,1,"Costed");DisplaySingleChar(0x0C,1,'s');LowSpeedArea2PassTime=LowSpeedArea2EndTime-HighSpeedAreaEndTime; DisplaySingleChar(0x0A,1,LowSpeedArea2PassTime%10+0x30);if(LowSpeedArea2PassTime>9) //通过第二个低速区的时间超过sDisplaySingleChar(0x0B,1,LowSpeedArea2PassTime/10+0x30);}AutoDisplay=False;/*---------------- 菜单选择你想要看的内容--总时间、总路程以及平均速度--------------*/ChoosingDisplay=True;WriteCmd(LCD_CLS);/*首先显示主菜单,然后显示第一个选项*/DisplayString(0x0,0,"NowChoosewhat");DisplayString(0x0,1,"youwanttosee");Delay(100);while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0," CostedTime ");DisplayString(0x0,1,"Next Show");Delay(250); //延时消除抖动/*------------------------------------第一次按键--------------------------------------*//*不断检测确定键和Next键*/while(1){if(Next==True)break;if(SelectedShow==True)break;}/*按下了确定键,显示第一个选项的内容*/if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;WriteCmd(LCD_CLS);DisplayString(0,0,"CostedTimeis");DisplayTime();DisplayString(0x0A,1,"s");ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能AVGSpeedShow=False;Delay(250); //延时消除抖动}/**按下了Next键,则显示第二个选项*/if(Next==True) //按下Next键,显示AVGSpeed菜单项Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0," AVGSpeed ");DisplayString(0x0,1,"Next Show");ReturnMain=False;ReturnSelection=False; //按下了Next键,那么这个时候关闭返回键的功能AVGSpeedShow=True; //表明AVGSpeed选项已经显示过了Delay(250); //延时消除抖动}/*------------------------------------第二次按键--------------------------------------*//*显示第一个选项的内容后又不断检测返回键(确定键)和Next键*/while(1){if(Next==True)break;if(Selected==True)break;}if(Next==True){Next=False;ReturnMain=False;ReturnSelection=False; //按下了Next键,那么这个时候关闭返回键的功能if(AVGSpeedShow==False) //还没有显示AVGSpeed选项,显示它{ //即第一次选择了确定键WriteCmd(LCD_CLS);DisplayString(0x0,0," AVGSpeed ");DisplayString(0x0,1,"Next Show");TotalDistanceShow=False; //显示了AVGSpeed,则表明TotalDistance还没有显示Delay(250); //延时消除抖动}if(AVGSpeedShow==True) //已经显示过AVGSpeed选项了,则显示下一个选项{ //即第一次选择了Next键WriteCmd(LCD_CLS);DisplayString(0x0,0,"TotalDistance");DisplayString(0x0,1,"Next Show");TotalDistanceShow=True; //表明显示了TotalDistance选项Delay(250); //延时消除抖动}}if(Selected==True) //按下了确定键或返回键{SelectedShow=False;SelectedReturn=False;Selected=False;if(ReturnSelection==True) //第一次选择了确定键,故这次按下的是返回键ReturnMain=True;if(ReturnSelection==False){WriteCmd(LCD_CLS);DisplayString(0,0,"TheAVGSpeedis");DisplayAVGSpeed();DisplayString(0x0A,1,"m/s");ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能Delay(250); //延时消除抖动}TotalDistanceShow=False;}if(ReturnMain==True) //按下了返回键,返回主菜单{ReturnMain=False;continue;}/*------------------------------------第三次按键--------------------------------------*//*如果没有返回主菜单,则继续检测Next键和确定键*/while(1){if(Next==True)break;if(SelectedShow==True)break;}/*按下Next键,显示下一个选项*/if(Next==True){Next=False;ReturnMain=False;ReturnSelection=False; //按下了Next键,那么这个时候关闭返回键的功能if(TotalDistanceShow==True)ReturnMain=True;if(TotalDistanceShow==False) //还没有显示TotalDistance选项,显示它{WriteCmd(LCD_CLS);DisplayString(0x0,0,"TotalDistance");DisplayString(0x0,1,"Next Show");TotalDistanceShow=True;Delay(250); //延时消除抖动}}if(Selected==True) //按下了确定键或返回键{SelectedShow=False;SelectedReturn=False;Selected=False;if(ReturnSelection==True) //按下的是返回键ReturnMain=True;if(ReturnSelection==False){if(TotalDistanceShow==False) //表明AVGSpeed选项的内容还没有显示{WriteCmd(LCD_CLS);DisplayString(0,0,"TheAVGSpeedis");DisplayAVGSpeed();DisplayString(0x0A,1,"m/s");ReturnSelection=True;Delay(250); //延时消除抖动}if(TotalDistanceShow==True){WriteCmd(LCD_CLS);DisplayString(0,0,"TotalDistance");DisplayDistance();DisplayString(0x0A,1,"m");ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能Delay(250); //延时消除抖动}}}if(ReturnMain==True) //按下了返回键,返回主菜单{ReturnMain=False;continue;}/*------------------------------------第四次按键--------------------------------------*/while(1){if(Next==True)break;if(SelectedShow==True)break;}if(Next==True) //所有菜单项已经显示完毕,返回主菜单{Next=False;ReturnMain=False;ReturnSelection=False;if(TotalDistanceShow==False){WriteCmd(LCD_CLS);DisplayString(0x0,0,"TotalDistance");DisplayString(0x0,1,"Next Show");TotalDistanceShow=True;Delay(250); //延时消除抖动}}if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;if(ReturnSelection==True) //按下的是返回键ReturnMain=True;if(ReturnSelection==False){if(TotalDistanceShow==True){WriteCmd(LCD_CLS);DisplayString(0,0,"TotalDistance");DisplayDistance();DisplayString(0x0A,1,"m");ReturnSelection=True;//按下了确定键,那么这个时候开启返回键的功能Delay(250); //延时消除抖动}}}if(ReturnMain==True) //按下了返回键,返回主菜单{ReturnMain=False;continue;}/*------------------------------------第五次按键--------------------------------------*/while(1){if(Next==True)break;if(SelectedShow==True)break;}if(Next==True) //所有菜单项已经显示完毕,返回主菜单{Next=False;ReturnMain=False;ReturnSelection=False;if(TotalDistanceShow==True) //最后一个选项已经显示完毕,返回主菜单{ReturnMain=True;}}if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;if(ReturnSelection==True) //按下的是返回键ReturnMain=True;if(ReturnSelection==False){if(TotalDistanceShow==True){WriteCmd(LCD_CLS);DisplayString(0,0,"TotalDistance");DisplayDistance();DisplayString(0x0A,1,"m");ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能Delay(250); //延时消除抖动}}}/*------------------------------------第六次按键--------------------------------------*/while(1){if(Next==True)break;if(SelectedShow==True)break;}if(Next==True){Next=False;ReturnMain=False;ReturnSelection=False;}if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;}continue;}while(1);}/****************************************************************************** **********\** LCD驱动模块 **\****************************************************************************** **********//*--------------------------------- LCD初始化函数--------------------------------------*/voidLCDInit(void){//三次显示模式设置LCD_Data=0;LCD_E=Disable;Delay(5);WriteCmd(LCD_Init);Delay(5);WriteCmd(LCD_Init);Delay(5);WriteCmd(LCD_Init);WriteCmd(LCD_Init); //初始化WriteCmd(LCD_CloseCtr); //关显示WriteCmd(LCD_CLS); //清屏幕WriteCmd(LCD_EnterSet); //光标移动设置WriteCmd(LCD_DispCtr); //显示开以及光标设置}/*--------------------------------- LCD模式设置函数--------------------------------------*\SetWriteCmd() 设置LCD为写命令模式SetReadCmd() 设置LCD为读命令模式SetWriteData() 设置LCD为写数据模式\*----------------------------------------------------------------------------------------*/voidSetWriteCmd(void){LCD_RW=Write;LCD_RS=Cmd;}voidSetReadCmd(void){LCD_RW=Read;LCD_RS=Cmd;}voidSetWriteData(void){LCD_RW=Write;LCD_RS=Data;}/*--------------------------------- LCD功能执行函数--------------------------------------*\WriteCmd() 写命令WriteData() 写数据ExecuteCmd() 执行命令SetXY() 显示定位DisplaySingleChar() 显示单个字符DisplayString() 显示一串字符IsBusy() 忙标志检测\*----------------------------------------------------------------------------------------*/voidWriteCmd(charcmd){while(IsBusy());LCD_Data=cmd;SetWriteCmd();ExecuteCmd();}voidWriteData(charddata){while(IsBusy());LCD_Data=ddata;SetWriteData();ExecuteCmd();}voidExecuteCmd(void){LCD_E=Enable;LCD_E=Disable;}voidSetXY(charx,chary){if(y)x|=0x40;x|=0x80;Delay(5);WriteCmd(x);}voidDisplaySingleChar(charx,chary,charcchar){SetXY(x,y);WriteData(cchar);}voidDisplayString(charx,chary,char*str){while(*str){Delay(5);DisplaySingleChar(x++,y,*str);str++;}}bitIsBusy(void){LCD_Data=0xFF;SetReadCmd();ExecuteCmd();return(bit)(P1&0x80);}/*------------------------------------- 延时函数-------------------------------------*/voidDelay(unsignedinttime){unsignedinttimeCounter=0;for(timeCounter=time;timeCounter>0;timeCounter--)DelayUs(255);}voidDelayUs(unsignedinttime){unsignedinttimeCounter=0;for(timeCounter=0;timeCounter<time;timeCounter++)_nop_();}/****************************************************************************** *************\** LCD显示模块**\****************************************************************************** *************/voidComputeTime(void){if(Area0<5)PassTime+=0.5;}voidComputeSpeedANDDistance(void){Speed=SpeedCount/4*CircleLength; //计算瞬时速度Distance+=Speed; //计算距离SpeedCount=0;}/*------------------------------------- 显示时间----------------------------------------*/voidDisplayTime(void){charPassTime1=0x30;charPassTime2=0x30;charPassTime3=0x30;charPassTime4=0x30;if((int)PassTime*100<100) //时间未够1s{PassTime1+=0;PassTime2+=(int)(PassTime*100)/10;PassTime3+=(int)(PassTime*100)%10;}elseif((int)(PassTime*100)>100 &&(int)(PassTime*100)<1000)//够1s而未够10s {PassTime1+=(int)(PassTime*100)/100;PassTime2+=(int)(PassTime*100)/10%10;PassTime3+=(int)(PassTime*100)%10;}else{PassTime1+=(int)(PassTime*100)/1000;PassTime2+=(int)(PassTime*100)/100%10;PassTime3+=(int)(PassTime*100)/10%10;PassTime4+=(int)(PassTime*100)%10;}if((int)(PassTime*100)<1000){DisplaySingleChar(0x05,1,PassTime1);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,PassTime2);DisplaySingleChar(0x08,1,PassTime3);}else{DisplaySingleChar(0x04,1,PassTime1);DisplaySingleChar(0x05,1,PassTime2);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,PassTime3);DisplaySingleChar(0x08,1,PassTime4);}}/*------------------------------------ 显示平均速度----------------------------------------*/voidDisplayAVGSpeed(void){intSpeed1=0x30; //初始化为0的ASCII码intSpeed2=0x30;intSpeed3=0x30;if((int)(Distance/PassTime*100)<100){Speed1+=0;Speed2+=(int)(Distance/PassTime*100)/10;Speed3+=(int)(Distance/PassTime*100)%10;}else{Speed1+=(int)(Distance/PassTime*100)/100;Speed2+=(int)(Distance/PassTime*100)/10%10;Speed3+=(int)(Distance/PassTime*100)%10;}DisplaySingleChar(0x05,1,Speed1);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,Speed2);DisplaySingleChar(0x08,1,Speed3);}/*------------------------------------- 显示路程----------------------------------------*/voidDisplayDistance(void){intDistance1=0x30;intDistance2=0x30;intDistance3=0x30;intDistance4=0x30;if((int)(Distance*100)<100){Distance1+=0;Distance2+=(int)(Distance*100)/10;Distance3+=(int)(Distance*100)%10;}elseif((int)(Distance*100)>100 &&(int)(Distance*100)<1000){Distance1+=(int)(Distance*100)/100;Distance2+=(int)(Distance*100)/10%10;Distance3+=(int)(Distance*100)%10;}else{Distance1+=(int)(Distance*100)/1000;Distance2+=(int)(Distance*100)/100%10;Distance3+=(int)(Distance*100)/10%10;Distance4+=(int)(Distance*100)%10;}。

智能小车的PWM键盘控制电机程序

智能小车的PWM键盘控制电机程序

智能小车的PWM键盘控制电机程序这个是从一个制作成功的智能小车里面提取出来的 全部的制作资料下载:51hei/bbs/dpj-19526-1.html 下面是程序预览:#includesbit P00=P0; //循迹口sbit P01=P0 ;sbit P02=P0 ; sbit P04=P0 ; //电机1左轮sbit P05=P0 ; sbit P06=P0 ; //电机2sbit P07=P0 ;unsigned int i=0,j=0;void main(){ while(1) { P04=1;P05=1;P06=1; P07=1; TMOD=0X01; EA=1; ET0=1;if(P00==0&&P01==1&&P02==0) // 小车直走定时0.002ms{TH0=0XFF; //定时0.01msTL0=0xFe;TR0=1;}if(P00==0&&P01==0&&P02==1) //小车右转定时0.005ms { TH0=0XFF; TL0=0Xfb; TR0=1; } if(P00==1&&P01==0&&P02==0) //小车左转定时0.005ms { TH0=0XFF; TL0=0XFb; TR0=1; } if(P00==1&&P01==1&&P02==1) //全部检测到黑线时车停{ TH0=0XFF; TL0=0Xfb; TR0=1; }}} xiong() interrupt 1{ if(P00==0&&P01==1&&P02==0) //小车直线快走定时0.002ms { TH0=0XFF; TL0=0xFe; P04=0;//电机1左轮P05=1;P06=1; //电机2 右转P07=0; } if(P00==0&&P01==0&&P02==1) //小车右转定时0.005ms { TH0=0XFF; TL0=0Xfb; P04=1;//电机1 左轮P05=1; P06=1; //电机2P07=0;i=1; } if(P00==0&&P01==0&&P02==0&&i==1) // 特别{TH0=0XFF; TL0=0Xfb; P04=1; P05=1; P06=1; P07=0; j=0; } if(P00==1&&P01==0&&P02==0) //小车左转定时0.005ms { TH0=0XFF; TL0=0XFb; P04=0;//电机1 P05=1; P06=1; //电机2 P07=1; j=1; } if(P00==0&&P01==0&&P02==0&&j==1) // 特别{ TH0=0XFF;。

基于单片机的调速寻迹小车

基于单片机的调速寻迹小车
电机驱动模块:将PWM信号转 换为适当的电压以驱动电机
光电传感器或红外传感器: 用于检测寻迹路径,并将检 测到的信号传递给51单片机
小车底盘和电机:用于实际 运动和执行PWM调速
基于51单片机的PWM调速寻迹小车
二、PWM调速原 理
PWM调速的原理是基 于调节电压的平均值 。通过改变脉冲宽度 ,我们可以改变电压 的平均值,从而控制 电机的转速。例如, 较宽的脉冲会产生较 高的平均电压,导致 电机以更高的速度旋 转
-
THE END
感谢您的观看
THANK 迹小车
三、软件实现
为了实现PWM调速和寻迹功能,我们需要编写相应的软件代码。以下是一个简化的伪代码 示例
这个示例代码使用了简单的占空比调节来实现PWM调速。在实际应用中,我们可能需要使 用更复杂的算法来优化速度和转向控制。此外,根据实际硬件配置和电机类型,可能还需 要调整PWM模块和电机驱动模块的参数以达到最佳性能
模拟信号的电压值
基于51单片机的PWM调速寻迹小车
一、硬件配置
首先,我们需要为51单片机连接适当的硬件以实现PWM控制和寻迹功能。以下是一个基本 的硬件配置列表
51单片机:作为主控制器,负责处理PWM信号和控制逻辑 PWM驱动模块:用于生成可调脉宽的PWM信号,以控制小车的速度
基于51单片机的PWM调速寻迹小车
xxxxxxxxx
基于51单片机的 PWM调速寻迹小车
xxxxxx:xxx
xxxxxxxxx
-
目录
CONTENTS
1
一、硬件配置
2
二、PWM调速原理
3
三、软件实现
2
基于51单片机的PWM调速寻迹小车
1
在本文中,我们将探讨 如何使用51单片机(MCU) 来控制PWM调速以实现寻

51单片机智能小车PWM调速前进程序源代码、电路原理图和器件表

51单片机智能小车PWM调速前进程序源代码、电路原理图和器件表

51单片机智能小车PWM调速前进程序源代码、电路原理图、电路器件表从控制电路角度划分,智能小车电路板分为核心板和驱动板。

核心板上的处理器的芯片型号是:STC15W4K56S4,这是一款51单片机。

驱动板上有电源电路、电机驱动电路以及一些功能模块接口。

智能小车前进只要控制智能小车四个轮子向前转动就可以了。

智能小车四个轮子由四个直流减速电机驱动。

直流减速电机驱动芯片采用L293D,一片电机驱动芯片L293D可以驱动两个直流减速电机,智能小车用到4个直流减速电机,需要用到两片L293D电机驱动芯片。

但有时候我们需要控制智能小车的速度,不希望智能小车全速前进。

比如在“智能小车循迹实验”中,如果智能小车速度过快,来不及反应做出方向的调整,智能小车会很容易跑离轨迹,这样就需要调整控制智能小车的速度了。

那么怎么样实现智能小车前进速度的调节呢?调节智能小车的速度,实际上是调节电机的运转速度,PWM调速是目前电机的主流调速方式。

智能小车采用脉宽调制(PWM)的办法来控制电机的转速,从而控制智能小车的速度。

在此种情况下,电池电源并非连续地向直流电机供电,而是在一个特定的频率下为直流电机提供电能。

不同占空比的方波信号,调节对直流电机的通断电,能起到对直流电机调速作用。

这是因为电机实际上是一个大电感,它有阻碍输入电流和电压突变的能力,因此脉冲输入信号被平均分配到作用时间上。

这样,改变L293D使能端EN1和EN2上输入方波的占空比就能改变加在电机两端的电压大小,从而改变了直流电机转速。

智能小车PWM调速前进程序如下:首先,定义了2个变量,这2个变量用于设置智能小车的速度。

unsigned char pwmval_left_init=6; //调节此值可以调节小车的速度。

unsigned char pwmval_right_init=6; //调节此值可以调节小车的速度。

通过以下函数初始化定时器0,每1毫秒中断一次。

void Timer0_Init(void) //定时器0初始化{TMOD=0x01;TH0=0xf8;TL0=0xcd;TR0=1;ET0=1;EA=1;}下面我们看定时器0的中断处理函数。

智能寻迹小车调试程序

智能寻迹小车调试程序
hyou1 = 1;
hyou2 = 0;
}
void TurnRight()//右转
{Leabharlann qzuo1 = 1;qzuo2 = 0;
hzuo1 = 1;
hzuo2 = 0;
qyou1 = 0;
qyou2 = 0;
hyou1 = 0;
hyou2 = 0;
}
void Xiaoying()
{
qzuo1=qzuo2=qyou1=qyou2=hzuo1=hzuo2=hyou1=hyou2=0 ;
if(LED1==1&&LED2==1&&LED3==0&&LED4==0&&LED5==1)//直行超出范围后速度变化不明显
{ RUN(); delay(30) ;Xiaoying() ;}
if(LED1==1&&LED2==0&&LED3==0&&LED4==1&&LED5==1)//直行
{ RUN(); delay(30) ;Xiaoying() ;}
void delay(int i)
{
while(i--);
}
void RUN()//向前
{
qzuo1 = 1;
qzuo2 = 0;
hzuo1 = 1;
hzuo2 = 0;
qyou1 = 1;
qyou2 = 0;
hyou1 = 1;
hyou2 = 0;
}
void STOP()//停车
{
qzuo1 = 0;
voiddelayintvoidrun向前voidstop停车voidturnleft左转voidturnright右转voidxiaoyingvoidmainvoidifled11led21led30led41led51直行delay值越小速度越小范围在10120为最佳控制范围run

循迹小车完整程序

循迹小车完整程序

程序# include <reg51.h>//********驱动芯片L298管脚位声明*****sbit IN1= P1^0;sbit PWM1= P1^1;sbit IN2= P1^2;sbit IN3= P1^3;sbit PWM2= P1^4;sbit IN4= P1^5;//********传感器TCRT5000管脚位声明****sbit XL= P1^6; //左侧第一个传感器sbit XR= P1^7; //右侧第一个传感器sbit YL= P2^0; //左侧第二个传感器sbit YR= P2^1; //右侧第二个传感器//********用于定时计数的两个全局变量位声明****** int count1=0;int count2=0;//********左边电机前进*******void forward_turn1(){IN1=0;IN2=0;}//*********左边电机后退******void reverse_tuen1(){IN1=1;IN2=0;}//*********右边电机前进*******void forward_turn2(){IN3=0;IN4=1;}//**********右边电机后退********void reverse_turn2(){IN3=1;IN4=0;}//***********左边电机速度控制函数******void speed1(int ct,int sd){if(ct<=sd)PWM1=1;elsePWM1=0;}//************右边电机速度控制函数******viod speed2(int ct,int sd){if (ct<=sd)PWM2=1;elsePWM2=0;//*************小车直线前进函数*********void advance (int ct1,int sd1,int ct2,int sd2); {forward_turn1();forward_turn2();speed1(ct1,sd1);speed2(ct2,sd2);}//**********小车左转********void left_turn1(int ct1,int sd1,int ct2,int sd2); {forward_turn1();forward_turn2();speed1(ct1,sd1);speed2(ct2,sd2);}//************小车右转*********viod riht_ turn1(int ct1,int sd1,int ct2,int sd2); {forward_turn1();forward_turn2();speed1(ct1,sd1);speed2(ct2,sd2);}//**************主函数**********main(){TMOD=ox11;TH0=(65536-1000)/256;TL0=(65536-1000)%256;EA=1;ET0=1;TR0=1;TH1=(65536-1000)/256;TL1=(65536-1000)%256;EA=1;ET1=1;TR1=1;while(1){if(XL==0&&XR==0&&YL==0&&YR==0) //传感器未检测到直线,小车直行{advance(count1,500,count2,500);}if(XL==1&&XR==0&&YL==0&&YR==0) //左边内侧传感器检测到黑线,小左转 {Left_turn1(count1,200,count2,500);}if(XL==0&&XR==0&&YL==1&&YR==0) //左边外侧传感器检测到黑线,大左转{Left_turn1(count1,200,count2,700);}if(XL==0&&XR==1&&YL==0&&YR==0) //右边内侧传感器检测到黑线,小右转{right_turn1(count1,500,count2,200);}if(XL==0&&XR==0&&YL==0&&YR=1) //右边外侧传感器检测到黑线,大右转{right_turn1(count1,700,count2,200);}if(XL==1&&XR==0&&YL==1&&YR=0) //左侧两个传感器均检测到黑线,中左转{Left_turn1(count1,200,count2,600);}if(XL==0&&XR==1&&YL==0&&YR=1) //右侧两个传感器均检测到黑线,中右转{right_turn1(count1,600,count2,200);}}}//******中断服务程序*******viod time0() interrupt1;{TH0=(65536-1000)/256;TL0=(65536-1000)%256;count1++;if (count1>=1000)count1=0}viod time1() interrupt1;{TH0=(65536-1000)/256;TL0=(65536-1000)%256;count2++;if (count2>=1000)count2=0}。

智能小车设计PWM与循迹

智能小车设计PWM与循迹

智能小车设计PWM与循迹一、教学内容本节课的教学内容选自《智能小车设计与实践》教材的第四章,主要涉及PWM(脉冲宽度调制)技术与循迹算法在智能小车中的应用。

具体内容包括PWM技术的原理及其在智能小车速度控制中的应用,循迹算法的原理及其在智能小车行驶中的实现。

二、教学目标1. 让学生了解并掌握PWM技术的原理及其在智能小车速度控制中的应用。

2. 让学生了解并掌握循迹算法的原理及其在智能小车行驶中的实现。

3. 培养学生动手实践的能力,提高他们解决实际问题的能力。

三、教学难点与重点重点:PWM技术的原理及其在智能小车速度控制中的应用,循迹算法的原理及其在智能小车行驶中的实现。

难点:PWM技术的原理及其在智能小车速度控制中的应用,循迹算法的原理及其在智能小车行驶中的实现。

四、教具与学具准备教具:智能小车、编程器、实验板。

学具:教材《智能小车设计与实践》、笔记本电脑、实验器材。

五、教学过程1. 实践情景引入:让学生观察智能小车在直线行驶和转弯时的表现,引发学生对PWM技术和循迹算法的兴趣。

2. 知识讲解:讲解PWM技术的原理及其在智能小车速度控制中的应用,循迹算法的原理及其在智能小车行驶中的实现。

3. 例题讲解:通过示例代码,讲解如何使用编程器调整智能小车的PWM信号,实现速度控制;如何使用循迹算法,使智能小车按照预设的路径行驶。

4. 随堂练习:让学生分组进行实践,使用编程器调整智能小车的PWM信号,实现速度控制;使用循迹算法,使智能小车按照预设的路径行驶。

六、板书设计板书内容主要包括PWM技术的原理及其在智能小车速度控制中的应用,循迹算法的原理及其在智能小车行驶中的实现。

七、作业设计1. 请简述PWM技术的原理及其在智能小车速度控制中的应用。

2. 请简述循迹算法的原理及其在智能小车行驶中的实现。

3. 请编写一段代码,实现智能小车按照预设的路径行驶。

八、课后反思及拓展延伸课后反思:本节课学生掌握了PWM技术的原理及其在智能小车速度控制中的应用,循迹算法的原理及其在智能小车行驶中的实现。

智能循迹小车程序

智能循迹小车程序

L#include<reg52.h>#define uchar unsigned char#define uint unsigned int//D0-D7:f,b,a,e,d,h,c,g 共阴依次编码//74LS04反相器驱动数码管uchar code table[10] = {0x5F,0x42,0x9E,0xD6,0xC3,0xD5,0xDD,0x46,0xDF,0xD7};uchar i = 0; //用于0-3数码管轮流显示uint j = 0; //计时的次数uint time=0; //计时uint pwm=16; //占空比uint speed; //调制PWM波的当前的值sbit R=P3^2; //右边传感器P3^2sbit L=P3^3; //左边传感器P3^3//电机驱动口定义sbit E NB=P1^0; //前轮电机停止控制使能sbit E NA=P1^1; //后轮控制调速控制端口sbit I N1=P1^2; //前轮sbit I N2=P1^3; //前轮sbit I N3=P1^4; //后轮sbit I N4=P1^5; //后轮void Init(){TMOD = 0x12; //定时器0用方式2,定时器1用方式1TH0=(256-200)/256; //pwmTL0=(256-200)/256;TH1 = 0x0F8; //定时2msTL1 = 0x30;EA = 1;ET0 = 1;ET1 = 1;TR0 = 1;TR1 = 1;}void tim0(void) interrupt 1 //产生PWM{speed ++;if(speed <= pwm) //pwm 就相当于占100的比例{ENA = 1;}else if(speed < 100){ENA = 0;}elsespeed = 0;}void time1() interrupt 3 //定时2ms{TH1 = 0x0F8;TL1 = 0x30;i =(i+1) % 4; //0-3循环j++;if(i == 0) //显示最低位数码管{P0 = 0x00; //段选清零防止乱码P0 = table[time%10]; //送段码信号}if(i == 1){P0 = 0x00;P0 = table[time/ 10% 10];}if(i == 2){P0 = 0x00;P0 = table[time/ 100% 10];}if(i == 3){P0 = 0x00;P0 = table[time/ 1000% 10];}P2 = ( 0x10 << i ); //送位选信号if(j == 500){time ++; //500次为1秒j = 0;}}void forward() //前进{IN2=1;IN1=0;}void back() //后退{IN2=0;IN1=1;}void left() //左转{ENB=1; //打开使能IN3=1;IN4=0;}void right() //右转{ENB=1; //打开使能IN3=0;IN4=1;}void stop() //停止{IN2=0;IN1=0;IN3=0;IN4=0;}void main(){Init(); //定时器初始化while(1){if(R==0 && L==1) //右传感器检测到黑线{right(); //右转forward();while(R==0 && L==1);}if(R==1 && L==0) //左传感器检测到黑线{left();forward();while(R==1 && L==0);}if(R==0 && L==0) //都检测到黑线则停止{stop();j = 0; //定时器仍在工作,计数时间清空}else //都没有检测到黑线{ENB = 0; //关闭转向控制forward();}}}。

带PWM调速的小车循迹程序

带PWM调速的小车循迹程序

//ICC-A VR application builder : 2010-9-21 10:22:14// Target : M16// Crystal: 8.0000Mhz#include <iom16v.h>#include <macros.h>#define uchar unsigned char#define uint unsigned intuint discrepancy=0;//function declarationvoid port_init(void);void motor(uchar index, uchar speed); //input PWM wave(PWM波输入)void sensor_state(void); //get the running condition (运行情况)void revise_to_line(void ); /0=run forward,1=left,2=right,3=sever left,4=sever rightvoid delayms(uint MS) ;//call this routine to initialize all peripherals【调用这个程序初始化所有的外围设备】void init_devices0(void){//stop errant interrupts until set upCLI(); //disable all interrupts【禁用所有中断】timer0_init();MCUCR = 0x00;GICR = 0x00;TIMSK = 0x02; //timer interrupt sources【定时器中断源】SEI(); //re-enable interrupts【重设中断】//all peripherals are now initialized【现在所有外设的初始化】}//initialize T/C1【初始化T / C1】void timer1_init(void){TCCR1B = 0x00;//停止定时器TIMSK |= 0x00;//中断允许TCNT1H = 0x00;TCNT1L = 0x00;//初始值OCR1AH = 0x00;OCR1AL = 0xF0;//匹配A值OCR1BH = 0x00;OCR1BL = 0xF0;//匹配B值ICR1H = 0xFF;ICR1L = 0xFF;//输入捕捉匹配值TCCR1A = 0xA1;TCCR1B = 0x01;//启动定时器}//call this routine to initialize all peripherals【调用这个程序初始化所有的外围设备】void init_devices1(void){CLI(); //禁止所有中断timer1_init( );MCUCR = 0x00;MCUCSR = 0x80;//禁止JTAGGICR = 0x00;SEI();//开全局中断}//PWM 调速,通过改变占空比,周期性地开闭使能端,调节电机的有效电压。

可以用PWM实现小车变速

可以用PWM实现小车变速

可以用PWM实现小车变速,但有一点要提醒一下,就是频率不要太高,我调试的时候,频率高时电动机会发出刺耳的声音,具体程序如下:#include < reg51.h >#include < intrins.h >sbit K1 =P2^0 ; //按K1,PWM值增加键sbit K2 =P2^1 ; //按K2,PWM值减少键sbit K3 =P2^2 ; //按K2,正反转unsigned char PWM="0x80",f=0x05; //赋初值bit k="0";/**************************************************延时程序/*************************************************/void delayms(unsigned char ms){unsigned char i ;while(ms--){for(i = 0 ; i < 240 ; i++) ;}}/***************************************************主程序****************************************************/void main(void){P1=0x00;TMOD="0x11" ; //计时器1,0的计时方式就均为为 1TH0=0x00 ; //周期TL0=0x00 ; //频率调节TH1=PWM ; //脉宽调节TL1=PWM ;EA="1";ET0=1;ET1=1;TR0=1 ;while(1){if(K3==0) k=~k; //实现正反转 while(K3==0);if(k==0) f="0x05";if(k==1) f="0x0a";while(K1==0&&PWM!=0xff) //加减速度{PWM++ ;delayms(10);}while(K2==0&&PWM!=0x00){PWM-- ;delayms(10);}}}/**************************************************定时器T0频率调节***************************************************/ void timer0() interrupt 1{TR1=0 ;TH0=0x00 ;TL0=0x00 ;TH1=PWM ;TL1=PWM;TR1=1 ;P1=0x00 ;}/***************************************************定时器T1,脉宽调节***************************************************/ void timer1() interrupt 3{TR1=0 ;P1=f ;}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//T0产生双路PWM信号,L298N为直流电机调速,接L298N时相应的管脚上最好接上10K的上拉电阻。

/* 晶振采用12M,产生的PWM的频率约为100Hz */#include<reg51.h>#include<math.h>#define uchar unsigned char#define uint unsigned intsbit en1=P3^4; /* L298的Enable A */sbit en2=P3^5; /* L298的Enable B */sbit s1=P1^0; /* L298的Input 1 */sbit s2=P1^1; /* L298的Input 2 */sbit s3=P1^3; /* L298的Input 3 */sbit s4=P1^2; /* L298的Input 4 */sbit R=P2^0;sbit C=P2^1;sbit L=P2^2;sbit key=P1^4;uchar t=0; /* 中断计数器*/uchar m1=0; /* 电机1速度值*/uchar m2=0; /* 电机2速度值*/uchar tmp1,tmp2; /* 电机当前速度值*//* 电机控制函数index-电机号(1,2); speed-电机速度(0-100) */void motor(uchar index, char speed){if(speed<=100){if(index==1) /* 电机1的处理*/{m1=abs(speed); /* 取速度的绝对值*/s1=1;s2=0;}if(index==2) /* 电机2的处理*/{m2=abs(speed); /* 电机2的速度控制*/s3=1;s4=0;}}}void Back(void)s1=0;s2=1;s3=1;s4=0;}void GO(void){s1=1;s2=0;s3=1;s4=0;}void TL(void){s1=1;s2=0;s3=0;s4=1;}void TR(void){s1=0;s2=1;s3=1;s4=0;}void STOP(void){s1=1;s2=1;s3=1;s4=1;}/*void delay(uint j) /* 简易延时函数*/ {for(j;j>0;j--);} */void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void main(){uchar i=0,j=0;TMOD=0x02; /* 设定T0的工作模式为2 ,8位自动重置定时器,每过几个机器周期,计数器加一*/TH0=0x9B; /* 装入定时器的初值,计数100次溢出*/TL0=0x9B; /*装入时间常数*/EA=1; /* 开中断*/ET0=1; /* 定时器0允许中断*/TR0=1; /* 启动定时器0 */while(1){if(key==1){/* 电机实际控制演示*/if(i<=100) // 正转加速{motor(1,i);motor(2,i);delay(5000);i++;}else{GO();}}else{EA=0;while(1){if((L|C|R)==0)STOP();if(L&R)GO();if(L==0)while(C){TL();}}if(R==0){while(C){TR();}}}}}}void timer0() interrupt 1 /* T0中断服务程序*/{if(t==0) /* 1个PWM周期完成后才会接受新数值*/{ tmp1=m1;tmp2=m2;}if(t<tmp1) en1=1; else en1=0; /* 产生电机1的PWM信号*/ if(t<tmp2) en2=1; else en2=0; /* 产生电机2的PWM信号*/ t++;if(t>=100) t=0; /* 1个PWM信号由100次中断产生*/}#include<intrins.h>#include<AT89X52.h>/********************************************************************************\** 宏定义区**\********************************************************************************/------------------------------------*/ /*------------------------------- LCD模块#defineLCD_RW P2_6 //读写控制端数据命令选择端#defineLCD_RS P2_7 // 执行使能端#defineLCD_E P2_5 // 口#defineLCD_Data P1 //P1 低电平写入#defineWrite 0x00 // 高电平读出#defineRead 0x01 // 高电平选择数据#defineData 0x01 // 低电平选择命令#defineCmd 0x00 // 跃变到低电平时执行命令#defineEnable 0x00 //#defineDisable 0x01#defineTrue 0x01#defineFalse 0x00初始化模式#defineLCD_Init 0x38 // 开显示及光标设置#defineLCD_DispCtr 0x0C //#defineLCD_CloseCtr 0x08 //关显示#defineLCD_CLS 0x01 //清屏幕#defineLCD_EnterSet 0x06 //显示光标#defineBusy P1_7 //忙信号/*--------------------------测速/测距/测时模块-------------------------------*/#defineCircleLength 0.132 //小车转一轮的长度为.132m/*--------------------------------控速模块-----------------------------------*/#defineP03 P0_3 //后电机#defineP04 P0_4 //后电机#defineP01 P0_1 //前电机#defineP02 P0_2 //前电机#defineP31 P0_5 //控制液晶背光#defineP33 P3_3/*------------------------------菜单选择模块---------------------------------*/#defineLine 0x00 //0代表直线模式#defineCurve 0x01 //1代表S型模式#defineNormal 0x00 //0 代表正常速度#defineLow 0x01 //1 代表低速#defineHigh 0x02 //2 代表高速/*********************************************************************************\**全局函数声明区**\*********************************************************************************/-------------------------------------*/ /*------------------------------- LCD模块voidLCDInit(void); //LCD初始化voidSetWriteCmd(void); //设置写命令模式设置读命令模式voidSetReadCmd(void); // 设置写数据模式voidSetWriteData(void); // 写命令voidWriteCmd(charcmd); // 写数据voidWriteData(charddata); // 执行命令voidExecuteCmd(void); // 定位显示地址voidSetXY(charx,chary); // 显示单个字符voidDisplaySingleChar(charx,chary,charcchar); // 显示一段字符串voidDisplayString(charx,chary,char*str); // 延时主程序voidDelay(unsignedinttime); // 延时子程序voidDelayUs(unsignedinttime); // 判断忙标志函数bit IsBusy(void); // voidDisplayTime(void); //显示时间voidDisplayA VGSpeed(void); //显示平均速度voidDisplayDistance(void); //显示路程/*--------------------------测速/测距/测时模块-------------------------------*/voidINTInit(void); //所有中断初始化voidSpeedINT(void); //测速中断voidComputeTime(void);voidComputeSpeedANDDistance(void); //计算速度和距离/*--------------------------------控速模块-----------------------------------*/voidCtrSpeedINT(void); //控速中断voidTime0INT(void);voidTime1INT(void); //控速单位时间中断voidClock0_Init(void); //时钟中断初始化voidClock1_Init(void); //时钟中断初始化voidCtrSpeed(void);/********************************************************************************\** 全局变量区**\********************************************************************************/float SpeedCount=0; //测速计数脉冲float Speed=0.0;float Distance=0.0;char Time1INTCount=0; //T1中断时间计时float PassTime=0.00; //小车行走的时间short IsT0INT=1;bit IsT1INT; //判断T1是否已经响应中断short IsT0INT2=1;char Thx[5]={0xf4,0xf4,0xc5,0xf4,0xff}; //3ms,3ms,15ms,3mschar Tlx[5]={0x48,0x48,0x68,0x48,0xff};char Thx0=0xd8;char Tlx0=0xf0;char Thx1=0xb1; //20mschar Tlx1=0xe0;short Round=0;short Back=0;short Back0=0;bit Backid;bit Stop=0;char Area0=0;char Area1=0; //区域变量char LowSpeedArea1StartTime;char LowSpeedArea1EndTime;char HighSpeedAreaEndTime;char LowSpeedArea2EndTime;char LowSpeedArea1PassTime=0; //第一个低速区通过时间char HighSpeedAreaPassTime=0; //高速区通过时间char LowSpeedArea2PassTime=0; //第二个低速区通过时间char ReadyToGo=4; //倒计时char flag;bit Roundid=0;char Nocurve=0;char ChangeFlag;char Mode;bit Running;bit SelectedAll; //模式和速度是否选择完毕标志bit IsSelectingMode; //模式选择标志bit IsSelectingSpeed; //速度选择标志bit ModeSelected; //已经被选择的模式标志char SelectedMode=10; //模式选择是否完毕标志bit Next; //Next键标志bit SpeedSelected; //已经被选中的速度方案标志char SelectedSpeed; //速度选择是否完毕标志bit ChoosingDisplay; //人工选择菜单开始标志bit SelectedShow; //显示选择标志bit SelectedReturn; //返回选择标志bit Selected; //确定/返回键选择标志bit ReturnSelection; //返回键启用标志bit A VGSpeedShow; //平均速度显示标志总路程显示标志bit TotalDistanceShow; //bit ReturnMain; //返回主菜单标志bit AutoDisplay; //自动显示标志bit GoToChoosingDisplay; //人工选择标志bit AutoMode=0;char PassLineID=0;char PassLine=0;float PrepareDistance;float FirstDistance;float SecondDistance;float ThirdDistance;int FirstHigh;int SecondHigh;int ThirdHigh;float Rate=1.25; //5ms时的速度float Count=4; //时间的倍数/****************************************************************************** **\** 全局函数实现区**\****************************************************************************** **//*--------------------------------主函数------------------------------------*/voidmain(){P01=0;P02=0;P03=0;P04=0;P31=1; //单片机复位,背光开Delay(40); //延时等待LCD启动LCDInit(); //初始化LCDDisplayString(0x0,0, Starting... );DisplayString(0x0,1,DesignedBy202);Delay(300);WriteCmd(LCD_CLS);EA=1; //开总中断EX0=1; //开INT0中断IT0=1; //INTO边沿触发EX1=1; //开INT1中断IT1=1; //INT1边沿触发SelectedAll=False; //开始模式和速度选择/*------------------------------模式选择---------------------------------*/DisplayString(0x0,0,ChooseTheMode);DisplayString(0x0,1,youwant. );Delay(50);WriteCmd(LCD_CLS);IsSelectingMode=True;while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0, LineMode );DisplayString(0x0,1,Next Yes);Delay(300); //延时消除抖动while(1) //不断检测中断,直到按确定键或是NEXT键{if(Next==True) //如果按Next键则直接跳出break;if(ModeSelected==True) //如果按确定键则设置模式为Line并跳出{SelectedMode=Line;break;} //如果什么键都没有按下,那么一直显示等待}if(ModeSelected==True) //按下了确定键,退出模式选择{IsSelectingMode=False;break;}if(Next==True) //按下了Next键,显示下一个菜单项{Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0, CurveMode );DisplayString(0x0,1,Next Yes);Delay(300); //延时消除抖动while(1) //不断检测中断,直到按确定键或是Next键{if(Next==True) //如果再一次按下Next键,则跳出break;if(ModeSelected==True) //如果按下确定键,则设置模式为Curve,并跳出{SelectedMode=Curve;break;}}}if(ModeSelected==True) //按下了确定键,退出模式选择{IsSelectingMode=False;break;}if(Next==True) //再一次按下了Next键,则循环模式选择{Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0, AutoMode );DisplayString(0x0,1,Next Yes);Delay(300); //延时消除抖动while(1){if(Next==True)break;if(ModeSelected==True){AutoMode=1;break;}}}if(ModeSelected==True){IsSelectingMode=False;break;}if(Next==True){Next=False;continue;}}Delay(50);WriteCmd(LCD_CLS);/*------------------------------速度选择---------------------------------*/ if(SelectedMode==Line&&AutoMode==0){DisplayString(0x0,0, NowChoosea );DisplayString(0x0,1, kindofSpeed);Delay(50);WriteCmd(LCD_CLS);IsSelectingSpeed=True;while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0,NormalSpeed );DisplayString(0x0,1,Next Yes);Delay(300); //延时消除抖动while(1){if(Next==True) //如果按Next键则直接跳出break;if(SpeedSelected==True) //如果按确定键则设置速度为Normal并跳出{Thx[0]=0xec;Tlx[0]=0x78; //5msThx[1]=0xf0;Tlx[1]=0x60; //4msThx[2]=0x8a;Tlx[2]=0xd0; //30msThx[3]=0xf4;Tlx[3]=0x48; //3msSelectedSpeed=Normal;break;} //如果什么键都没有按下,那么一直显示等待}if(SpeedSelected==True) //按下了确定键,退出速度选择{IsSelectingSpeed=False;break;}if(Next==True){Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0, Low Speed );DisplayString(0x0,1,Next Yes);Delay(300); //延时消除抖动while(1){if(Next==True) //如果再一次按下Next键,则跳出break;if(SpeedSelected==True) //如果按下确定键,则设置速度为Low,并跳出{SelectedSpeed=Low; //这里没有速度设置,因为默认速度就是Lowbreak;}}}if(SpeedSelected==True) //按下了确定键,退出速度选择{IsSelectingSpeed=False;break;}if(Next==True){Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0, High Speed );DisplayString(0x0,1,Next Yes);Delay(300); //延时消除抖动while(1){if(Next==True) //如果再一次按下Next键,则跳出break;if(SpeedSelected==True) //如果按下确定键,则设置速度为High,并跳出{Thx[0]=0xe0;Tlx[0]=0xc0;//8msThx[1]=0xe0;Tlx[1]=0xc0; //8msThx[2]=0x63;Tlx[2]=0xc0; //40msThx[3]=0xec;Tlx[3]=0x78; //5msSelectedSpeed=High;break;}}}if(SpeedSelected==True) //按下了确定键,退出速度选择{IsSelectingSpeed=False;break;}if(Next==True) //再一次按下了Next键,则循环速度选择{Next=False;continue;}}}SelectedAll=True; //标志模式选择和速度选择完毕Running=True;Delay(50);WriteCmd(LCD_CLS);/*-------------------------显示所选择的模式和速度方案-------------------------*/ if(SelectedMode==Line){DisplayString(0x0,0,ChoosenModeis);DisplayString(0x0,1, Line );Delay(50);WriteCmd(LCD_CLS);}if(SelectedMode==Curve){DisplayString(0x0,0,ChoosenModeis); DisplayString(0x0,1, Curve );Delay(50);WriteCmd(LCD_CLS);}if(AutoMode==1){DisplayString(0x0,0,ChoosenModeis); DisplayString(0x0,1, AutoMode );Delay(50);WriteCmd(LCD_CLS);}if(SelectedMode==Line){if(SelectedSpeed==Normal){DisplayString(0x0,0,ChoosenSpeedis); DisplayString(0x0,1, Normal );Delay(50);WriteCmd(LCD_CLS);}if(SelectedSpeed==Low){DisplayString(0x0,0,ChoosenSpeedis); DisplayString(0x0,1, Low );Delay(50);WriteCmd(LCD_CLS);}if(SelectedSpeed==High){DisplayString(0x0,0,ChoosenSpeedis); DisplayString(0x0,1, High );Delay(50);WriteCmd(LCD_CLS);}}INTInit(); //初始化所有中断DisplayString(0x0,0,LeftTimesToGo);while(ReadyToGo--){DisplaySingleChar(0x7,1,ReadyToGo+0x30); DisplaySingleChar(0x09,1,'s');}WriteCmd(LCD_CLS);DisplayString(0x05,0,Go!!!);Delay(100);WriteCmd(LCD_CLS);DisplayString(0x0,0, Living... ); DisplayString(0x0,1,Designedby202);if(SelectedMode==Line&&AutoMode==0) flag=Area0;elseflag=1;while(flag<5){if(AutoMode==1) //自动模式{switch(PassLineID){case0 :{if(IsT0INT==1){P01=P02=P04=0;P03=1;}else{P01=P02=P03=P04=0;}}break;case1 :{P01=P02=P03=0;P04=1;}break;case2 :{P01=P02=P04=0;P03=1;}break;default:break;}}else{if(SelectedMode==Line) //直线模式{flag=Area0;if(IsT0INT==1){P03=1;P04=0;P01=P02=0;}else{P03=0;P04=0;P01=P02=0;}}elseif((Nocurve<2)&&Round!=0&&(Back0>0)&&Back!=0) {if(Backid==1){P01=1;P02=0;P03=0;P04=1;}else{P01=0;P02=1;P03=0;P04=1;}Back=1;}else{if(Round==0){if(IsT0INT2==1){P01=0;P02=0;P03=1;P04=0;}else{P01=0;P02=0;P03=0;P04=0;}}else{if(P33==0){if(IsT0INT2==1){P01=0;P02=0;P03=1;P04=0;}else{P01=0;P02=0;P03=0;P04=0;}}else{EX1=1;if(Round%2){if(IsT0INT2==1){P01=1;P02=0;P03=1;P04=0;Backid=1;}else{P01=1;P02=0;P03=0;P04=0;}}else{if(IsT0INT2==1){P01=0;P02=1;P03=1;P04=0;Backid=0;}else{P01=0;P02=1;P03=0;P04=0;}}}}}}}if(IsT1INT==1){IsT1INT=0;ComputeTime();ComputeSpeedANDDistance();}}//补中断路程,加上最后一次中断缺失的路程ComputeSpeedANDDistance();P04=1;P03=0;P01=P02=0;Delay(90);P03=0;P04=0; //行程结束,小车停止P31=1; //行程结束,背光开ET0=0x0; //关T0中断ET1=0x0; //关T1中断EX1=0x01; //开INT1中断Running=False;AutoDisplay=True; //默认情况下直线模式会自动显示各个区域经过的时间WriteCmd(LCD_CLS);if(SelectedMode==Line) //直线模式才显示{while(1){if(GoToChoosingDisplay==True)break;Delay(200);WriteCmd(LCD_CLS);Delay(200);DisplayString(0,0,LowSpeedArea1);DisplayString(0,1,Costed);DisplaySingleChar(0x0C,1,'s');LowSpeedArea1PassTime=LowSpeedArea1EndTime-LowSpeedArea1StartTime; DisplaySingleChar(0x0A,1,LowSpeedArea1PassTime_x0010_+0x30);if(LowSpeedArea1PassTime>9) //通过第一个低速区的时间超过sDisplaySingleChar(0x0B,1,LowSpeedArea1PassTime/10+0x30);if(GoToChoosingDisplay==True)break;Delay(200);WriteCmd(LCD_CLS);Delay(200);DisplayString(0,0,HighSpeedArea);DisplayString(0,1,Costed);DisplaySingleChar(0x0C,1,'s');HighSpeedAreaPassTime=HighSpeedAreaEndTime-LowSpeedArea1EndTime; DisplaySingleChar(0x0A,1,HighSpeedAreaPassTime_x0010_+0x30);if(HighSpeedAreaPassTime>9) //通过高速区的时间超过sDisplaySingleChar(0x0B,1,HighSpeedAreaPassTime/10+0x30);if(GoToChoosingDisplay==True)break;Delay(200);WriteCmd(LCD_CLS);Delay(200);DisplayString(0,0,LowSpeedArea2);DisplayString(0,1,Costed);DisplaySingleChar(0x0C,1,'s');LowSpeedArea2PassTime=LowSpeedArea2EndTime-HighSpeedAreaEndTime; DisplaySingleChar(0x0A,1,LowSpeedArea2PassTime_x0010_+0x30);if(LowSpeedArea2PassTime>9) //通过第二个低速区的时间超过sDisplaySingleChar(0x0B,1,LowSpeedArea2PassTime/10+0x30);}}AutoDisplay=False;/*----------------菜单选择你想要看的内容--总时间、总路程以及平均速度--------------*/ ChoosingDisplay=True;WriteCmd(LCD_CLS);*/首先显示主菜单,然后显示第一个选项/*DisplayString(0x0,0,NowChoosewhat);DisplayString(0x0,1,youwanttosee);Delay(100);while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0, CostedTime );DisplayString(0x0,1,Next Show);Delay(250); //延时消除抖动/*------------------------------------第一次按键--------------------------------------*//*不断检测确定键和Next键*/while(1){if(Next==True)break;if(SelectedShow==True)break;}/*按下了确定键,显示第一个选项的内容*/if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;WriteCmd(LCD_CLS);DisplayString(0,0,CostedTimeis);DisplayTime();DisplayString(0x0A,1,s);ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能A VGSpeedShow=False;Delay(250); //延时消除抖动}/**按下了Next键,则显示第二个选项*/if(Next==True) //按下Next键,显示A VGSpeed菜单项{Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0, A VGSpeed );DisplayString(0x0,1,Next Show);ReturnMain=False;ReturnSelection=False; //按下了Next键,那么这个时候关闭返回键的功能选项已经显示过VGSpeedA表明VGSpeedShow=True; //A.了Delay(250); //延时消除抖动}/*------------------------------------第二次按键--------------------------------------*/ /*显示第一个选项的内容后又不断检测返回键(确定键)和Next键*/ while(1){if(Next==True)break;if(Selected==True)break;}if(Next==True){Next=False;ReturnMain=False;ReturnSelection=False; //按下了Next键,那么这个时候关闭返回键的功能if(A VGSpeedShow==False) //还没有显示A VGSpeed选项,显示它{ //即第一次选择了确定键WriteCmd(LCD_CLS);DisplayString(0x0,0, A VGSpeed );DisplayString(0x0,1,Next Show);TotalDistanceShow=False; //显示了A VGSpeed,则表明TotalDistance还没有显示Delay(250); //延时消除抖动}if(A VGSpeedShow==True) //已经显示过A VGSpeed选项了,则显示下一个选项{ //即第一次选择了Next键WriteCmd(LCD_CLS);DisplayString(0x0,0,TotalDistance);DisplayString(0x0,1,Next Show);TotalDistanceShow=True; //表明显示了TotalDistance选项Delay(250); //延时消除抖动}}if(Selected==True) //按下了确定键或返回键{SelectedShow=False;SelectedReturn=False;Selected=False;第一次选择了确定键,故这次按下if(ReturnSelection==True) //的是返回键ReturnMain=True;if(ReturnSelection==False){WriteCmd(LCD_CLS);DisplayString(0,0,TheA VGSpeedis);DisplayA VGSpeed();DisplayString(0x0A,1,m/s);ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能Delay(250); //延时消除抖动}TotalDistanceShow=False;}if(ReturnMain==True) //按下了返回键,返回主菜单{ReturnMain=False;continue;}/*------------------------------------第三次按键--------------------------------------*/ /*如果没有返回主菜单,则继续检测Next键和确定键*/while(1){if(Next==True)break;if(SelectedShow==True)break;}/*按下Next键,显示下一个选项*/if(Next==True){Next=False;ReturnMain=False;ReturnSelection=False; //按下了Next键,那么这个时候关闭返回键的功能if(TotalDistanceShow==True)ReturnMain=True;if(TotalDistanceShow==False) //还没有显示TotalDistance选项,显示它{WriteCmd(LCD_CLS);DisplayString(0x0,0,TotalDistance);DisplayString(0x0,1,Next Show);TotalDistanceShow=True;延时消除抖动Delay(250); //}}if(Selected==True) //按下了确定键或返回键{SelectedShow=False;SelectedReturn=False;Selected=False;if(ReturnSelection==True) //按下的是返回键ReturnMain=True;if(ReturnSelection==False){if(TotalDistanceShow==False) //表明A VGSpeed选项的内容还没有显示{WriteCmd(LCD_CLS);DisplayString(0,0,TheA VGSpeedis);DisplayA VGSpeed();DisplayString(0x0A,1,m/s);ReturnSelection=True;Delay(250); //延时消除抖动}if(TotalDistanceShow==True){WriteCmd(LCD_CLS);DisplayString(0,0,TotalDistance);DisplayDistance();DisplayString(0x0A,1,m);ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能Delay(250); //延时消除抖动}}}if(ReturnMain==True) //按下了返回键,返回主菜单{ReturnMain=False;continue;}/*------------------------------------第四次按键--------------------------------------*/ while(1){if(Next==True)break;if(SelectedShow==True)break;}if(Next==True) //所有菜单项已经显示完毕,返回主菜单{Next=False;ReturnMain=False;ReturnSelection=False;if(TotalDistanceShow==False){WriteCmd(LCD_CLS);DisplayString(0x0,0,TotalDistance);DisplayString(0x0,1,Next Show);TotalDistanceShow=True;Delay(250); //延时消除抖动}}if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;if(ReturnSelection==True) //按下的是返回键ReturnMain=True;if(ReturnSelection==False){if(TotalDistanceShow==True){WriteCmd(LCD_CLS);DisplayString(0,0,TotalDistance);DisplayDistance();DisplayString(0x0A,1,m);ReturnSelection=True;//按下了确定键,那么这个时候开启返回键的功能Delay(250); //延时消除抖动}}}if(ReturnMain==True) //按下了返回键,返回主菜单{ReturnMain=False;continue;}--------------------------------------*/第五次按键/*------------------------------------while(1){if(Next==True)break;if(SelectedShow==True)break;}if(Next==True) //所有菜单项已经显示完毕,返回主菜单{Next=False;ReturnMain=False;ReturnSelection=False;if(TotalDistanceShow==True) //最后一个选项已经显示完毕,返回主菜单{ReturnMain=True;}}if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;if(ReturnSelection==True) //按下的是返回键ReturnMain=True;if(ReturnSelection==False){if(TotalDistanceShow==True){WriteCmd(LCD_CLS);DisplayString(0,0,TotalDistance);DisplayDistance();DisplayString(0x0A,1,m);ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能Delay(250); //延时消除抖动}}}/*------------------------------------第六次按键--------------------------------------*/ while(1){if(Next==True)break;if(SelectedShow==True)break;}if(Next==True){Next=False;ReturnMain=False;ReturnSelection=False;}if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;}continue;}while(1);}/****************************************************************************** **********\** LCD驱动模块**\****************************************************************************** **********//*--------------------------------- LCD初始化函数--------------------------------------*/voidLCDInit(void){//三次显示模式设置LCD_Data=0;LCD_E=Disable;Delay(5);WriteCmd(LCD_Init);Delay(5);WriteCmd(LCD_Init);Delay(5);WriteCmd(LCD_Init);WriteCmd(LCD_Init); //初始化WriteCmd(LCD_CloseCtr); //关显示WriteCmd(LCD_CLS); //清屏幕WriteCmd(LCD_EnterSet); //光标移动设置WriteCmd(LCD_DispCtr); //显示开以及光标设置}--------------------------------------*\模式设置函数/*--------------------------------- LCD.SetWriteCmd() 设置LCD为写命令模式SetReadCmd() 设置LCD为读命令模式SetWriteData() 设置LCD为写数据模式\*----------------------------------------------------------------------------------------*/ voidSetWriteCmd(void){LCD_RW=Write;LCD_RS=Cmd;}voidSetReadCmd(void){LCD_RW=Read;LCD_RS=Cmd;}voidSetWriteData(void){LCD_RW=Write;LCD_RS=Data;}/*--------------------------------- LCD功能执行函数--------------------------------------*\ WriteCmd() 写命令WriteData() 写数据ExecuteCmd() 执行命令SetXY() 显示定位DisplaySingleChar() 显示单个字符DisplayString() 显示一串字符IsBusy() 忙标志检测\*----------------------------------------------------------------------------------------*/ voidWriteCmd(charcmd){while(IsBusy());LCD_Data=cmd;SetWriteCmd();ExecuteCmd();}voidWriteData(charddata){while(IsBusy());LCD_Data=ddata;SetWriteData();ExecuteCmd();}voidExecuteCmd(void){LCD_E=Enable;LCD_E=Disable;}voidSetXY(charx,chary){if(y)x|=0x40;x|=0x80;Delay(5);WriteCmd(x);}voidDisplaySingleChar(charx,chary,charcchar)SetXY(x,y);WriteData(cchar);}voidDisplayString(charx,chary,char*str){while(*str){Delay(5);DisplaySingleChar(x++,y,*str);str++;}}bitIsBusy(void){LCD_Data=0xFF;SetReadCmd();ExecuteCmd();return(bit)(P1&0x80);}/*-------------------------------------延时函数-------------------------------------*/voidDelay(unsignedinttime){unsignedinttimeCounter=0;for(timeCounter=time;timeCounter>0;timeCounter--)DelayUs(255);}voidDelayUs(unsignedinttime){unsignedinttimeCounter=0;for(timeCounter=0;timeCounter<time;timeCounter++)_nop_();}/****************************************************************************** *************\块示模** LCD显**\****************************************************************************** *************/voidComputeTime(void){if(Area0<5)PassTime+=0.5;}voidComputeSpeedANDDistance(void)Speed=SpeedCount/4*CircleLength; //计算瞬时速度Distance+=Speed; //计算距离SpeedCount=0;}/*-------------------------------------显示时间----------------------------------------*/ voidDisplayTime(void){charPassTime1=0x30;charPassTime2=0x30;charPassTime3=0x30;charPassTime4=0x30;if((int)PassTime*100<100) //时间未够1s{PassTime1+=0;PassTime2+=(int)(PassTime*100)/10;PassTime3+=(int)(PassTime*100)_x0010_;}elseif((int)(PassTime*100)>100 &&(int)(PassTime*100)<1000)//够1s而未够10s {PassTime1+=(int)(PassTime*100)/100;PassTime2+=(int)(PassTime*100)/10_x0010_;PassTime3+=(int)(PassTime*100)_x0010_;}else{PassTime1+=(int)(PassTime*100)/1000;PassTime2+=(int)(PassTime*100)/100_x0010_;PassTime3+=(int)(PassTime*100)/10_x0010_;PassTime4+=(int)(PassTime*100)_x0010_;}if((int)(PassTime*100)<1000){DisplaySingleChar(0x05,1,PassTime1);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,PassTime2);DisplaySingleChar(0x08,1,PassTime3);}else{DisplaySingleChar(0x04,1,PassTime1);DisplaySingleChar(0x05,1,PassTime2);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,PassTime3);DisplaySingleChar(0x08,1,PassTime4);}}/*------------------------------------显示平均速度----------------------------------------*/ voidDisplayA VGSpeed(void){intSpeed1=0x30; //初始化为0的ASCII码intSpeed2=0x30;intSpeed3=0x30;if((int)(Distance/PassTime*100)<100){Speed1+=0;Speed2+=(int)(Distance/PassTime*100)/10;Speed3+=(int)(Distance/PassTime*100)_x0010_;}else{Speed1+=(int)(Distance/PassTime*100)/100;Speed2+=(int)(Distance/PassTime*100)/10_x0010_;Speed3+=(int)(Distance/PassTime*100)_x0010_;}DisplaySingleChar(0x05,1,Speed1);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,Speed2);DisplaySingleChar(0x08,1,Speed3);}/*-------------------------------------显示路程----------------------------------------*/ voidDisplayDistance(void){intDistance1=0x30;intDistance2=0x30;intDistance3=0x30;intDistance4=0x30;if((int)(Distance*100)<100){Distance1+=0;Distance2+=(int)(Distance*100)/10;Distance3+=(int)(Distance*100)_x0010_;}elseif((int)(Distance*100)>100 &&(int)(Distance*100)<1000){Distance1+=(int)(Distance*100)/100;Distance2+=(int)(Distance*100)/10_x0010_;Distance3+=(int)(Distance*100)_x0010_;}else{Distance1+=(int)(Distance*100)/1000;Distance2+=(int)(Distance*100)/100_x0010_;Distance3+=(int)(Distance*100)/10_x0010_;Distance4+=(int)(Distance*100)_x0010_;}if((int)(Distance*100)<1000){DisplaySingleChar(0x05,1,Distance1);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,Distance2);DisplaySingleChar(0x08,1,Distance3);}else{DisplaySingleChar(0x04,1,Distance1);DisplaySingleChar(0x05,1,Distance2);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,Distance3);DisplaySingleChar(0x08,1,Distance4);}}/*-------------------------------------中断初始化-------------------------------------*/voidINTInit(void){EA=1; //开总中断IT0=1; //INTO边沿触发PX0=1; //INTO优先级为高级中断INT1开EX1=1; //IT1=1; //INT1边沿触发PX1=1; //INT1优先级为高级Clock0_Init(); //初始化时钟中断1 TMOD=0x11; //T0/T1定时方式T0中断ET0=0x01; //开中断ET1=0x01; //开T1} voidClock0_Init(void){T0 启动TR0=0x01; // 定时初值TH0=Thx0; //TL0=Tlx0;}voidClock1_Init(void){T1启动TR1=0x01; // 中断一次定时初值-50msTH1=0x3C; //TL1=0x0B0;}/****************************************************************************** *************\。

相关文档
最新文档