- 启动键为U2P32
- 停止键为U2P33*/
- #include <at89x52.h>
- #define uchar unsigned char
- #define uint unsigned int
- void motor_r_z(void);//右边电动机正转
- void motor_l_z(void);//左边电动机正转
- void motor_r_f(void);//右边电动机反转
- void motor_l_f(void);//左边电动机反转
- void go(uchar,uchar);//小车前进
- void stop(void);//小车停止
- sbit IN1=P2^5;//L298N的IN1接到P2.5
- sbit IN2=P2^4;//L298N的IN2接到P2.4
- sbit IN3=P2^1;//L298N的IN3接到P2.1
- sbit IN4=P2^2;//L298N的IN4接到P2.2
- sbit ENA=P2^0;//L298N的ENA接到P2.0
- sbit ENB=P2^3;//L298N的ENB接到P2.2
- sbit left_k=P0^5;//小车左转信号输入端为P0.5,P0.5为1时说明已经检测到黑线
- sbit right_k=P0^4;//小车右转信号输入端为P0.4,P0.4为1时说明已经检测到黑线
- sbit start_k=P3^2;//启动按键为U2P32
- sbit stop_k=P3^3;//停止按键为U2P33
- sbit sound=P2^7;//蜂鸣器接到了P2.7上,P2.7为低电平的时候,蜂鸣器响。
- uchar data t_0;//每产生一次T0定时器中断的时候t_0加1
- uchar data motor_r;//motor_r用于存放右边电机转速和转向的数据
- uchar data motor_l;//motor_l用于存放左边电机转速和转向的数据
- uchar data Speed_Parameters;
- //********************************延时程序
- void delay_1ms(uint n)
- {
- uint i,j;
- for(j=n;j>0;j--)
- for(i=20;i>0;i--);
- }
- //****************************初始化函数
- void ini(void)
- {
- TMOD=0x01; //T0工作在方式1
- TH0=0xff; //装入T0初值
- TL0=0xf6;
- TR0=1;//开T0中断
- ET0=1;//T0允许中断
- EA=1;
- t_0=0;
- P2=0x00;
- sound=0;
- delay_1ms(100);//蜂鸣器响100ms
- sound=1;
- }
- //********************************蜂鸣器响
- void Sound(void)
- {
- sound=0;
- delay_1ms(60);
- sound=1;
- }
- //******************************启动处理函数
- void start(void)
- {
- uchar a;
- aa:while(start_k);//防抖程序
- for(a=0;a<50;a++)
- {
- delay_1ms(1);
- while(start_k)
- goto aa;
- }
- Sound();//调用蜂鸣器发音程序
- go(0x40,0x40);//直行
- }
- //*******************************直行函数
- void go(uchar left_motor,uchar right_motor)
- {
- Speed_Parameters=right_motor;//给速度参数赋值
- motor_r_z();//调用右边电机正转函数
- Speed_Parameters=left_motor;
- motor_l_z();//调用左边电机正转函数
- }
- //*******************************右边电动机正转
- void motor_r_z(void)
- {
- motor_r=0x64+Speed_Parameters;
- ENA=1;
- }
- //********************************左边电机正转
- void motor_l_z(void)
- {
- motor_l=0x64-Speed_Parameters;
- ENB=1;
- }
- //*********************************停止函数
- void stop(void)
- {
- ENB=0;
- ENA=0;
- }
- //********************************T0中断服务程序(PWM产生)
- void time0(void) interrupt 1 using 2
- {
- TR0=0;//停止T0计数
- TH0=0xff;//当晶振频率是12M时,每隔0.01ms中断一次,200次中断为PWM信号输出的周期,
- TL0=0xf6;//PWM信号的频率=1000/(200*0.01ms)=500HZ
- ++t_0;//产生一次中断t_0加1
- ACC=t_0;//将t_0的值赋值给ACC
- CY=0;//清零CY
- ACC-=motor_r;//用ACC减去右边电动机的参数(此参数决定了右边电机的转向和速度)
- if(CY==1)//判断CY是否置1,如果为1,说明ACC-motor_r已经为负数,置位了CY
- {
- IN1=1;//IN1由原来的0变成了1
- IN2=0;//IN2由原来的1变成了0
- goto PWM_2;
- }
- IN1=0;//如果CY不等于1,IN1=0,IN2=1
- IN2=1;
- PWM_2:
- ACC=t_0;//重新将t_0的值赋值给ACC
- CY=0;//清零CY
- ACC-=motor_l;//用ACC减去左边电动机的参数(此参数决定了左边电机的转向和速度)
- if(CY==1)//判断CY是否置1,如果为1,说明ACC-motor_l已经为负数,置位了CY
- {
- IN3=1;//IN3由原来的0变成了1
- IN4=0;//IN4由原来的1变成了0
- goto HIGHT;
- }
- IN3=0;//如果CY不等于1,IN3=0,IN4=1
- IN4=1;
- HIGHT:
- //ACC=t_0; //重新将t_0的值赋值给ACC
- if(t_0!=0xc8)//判断t_0的值是否不等于200
- goto EXIT;//如果不等于200,程序指针指向EXIT执行程序
- ACC=0;//如果t_0的值等于200,清零ACC和t_0
- t_0=ACC;
- EXIT:
- TR0=1;//打开TO计数
- }
- //********************************启动或关闭小车
- void all_on(void)
- {
- if((left_k==1)&&(right_k==1))
- {
- stop();
- start();//跳到启动处理函数,执行程序
- while((left_k==1)&&(right_k==1));
- }
- }
- //**********************************主函数
- void main(void)
- {
- uchar a;
- ini();//调用初始化函数
- start();//调用启动处理函数
- ////判断左传感器状态////
- while(1)
- {
- aa:
- all_on();
- while(!left_k)//判断左边传感器的值是否为0
- goto bb;//如果是0,程序指针指向标号bb,执行程序
- P1_0=0;//如果是1,点亮P1.0上连接的发光二极管
- // Sound();
- while(left_k)//如果left_k的值一直为1,不断的循环执行 go(0x00,0x64);小车左转 直到left_k的值为0为止。
- {
- go(0x00,0x45);//0x00,0x64分别代表左右电动机的转速,两个值的取值为0x00到0x64之间,0x00最慢。0x64最快
- all_on();
- } //0x00,0x64这两个值不一样代表两个电机向前转的速度不同,小车将拐弯
- go(0x40,0x40);//执行到这句说明left_k已经为1,说明左传感器已经离开了黑线。小车直线前进
- //0x40,0x40这连个值同表示小车执行这个函数时将向前走,用户可以自任意修改这些数值,达到小车走黑线
- //最稳定的效果,建议不要取得太大(十六进制0x64是最大,其实也就是十进制数的100),也就是速度等级
- //为0到100个等级。
- P1_0=1;//关闭LED指示灯
- ////判断右传感器状态////
- bb:
- all_on();
- while(!right_k)//判断右传感器的值是否为0
- goto cc;//如果是0,程序指针指向标号cc,执行程序
- P1_1=0;//如果是1,点亮P1.1上连接的发光二极管
- // Sound();
- while(right_k)//如果right_k的值一直为1,不断的循环执行go(0x64,0x0),小车右转,直到right_k的值为0为止
- {
- go(0x45,0x00);
- all_on();
- }
- go(0x40,0x40);//执行到这句说明right_k已经为1,说明左传感器已经离开了黑线。小车直线前进
- P1_1=1;//关闭LED指示灯
- ///判断是否按下停止按钮//////
- cc:
-
- while(stop_k)//判断停止键是否按下,按下的时候stop_k为1
- goto aa;////如果是1,程序指针指向标号aa,执行程序
- for(a=0;a<20;a++)//如果是0,进入防抖程序
- {
- delay_1ms(1);
- while(stop_k)//判断20次stop_k是否为1
- goto cc;//如果是1,程序指针指向标号cc,执行程序
- }
- stop();//20次判断之后stop_k都是0,立马停止两个电动机
- start();//跳到启动处理函数,执行程序。
- }
- }
复制代码
|