#include<at89x51.h>//此为红外线寻线小车程序 单片机为stc89c51rc 发射频率为38.5mKz 电机驱动芯片为L298 / void delay_nus(unsigned int i) //延时:i>=12 ,i的最小延时单12 us { i=i/10; while(--i); } void delay_nms(unsigned int n) //延时n ms { n=n+1; while(--n) delay_nus(900); //延时 1ms,同时进行补偿 } /****************************************************** /************管脚定义********************/ extern int abs(int val); //声明abs函数 sbit ENA = P3^6; //左轮驱动使能 sbit IN1 = P3^2; //左轮黑线 sbit IN2 = P3^3; //左轮红线 sbit IN3 = P3^4; //右轮红线 sbit IN4 = P3^5; //右轮黑线 sbit ENB = P3^7; //右轮驱动使能 sbit L_scan=P0^2; //传感器扫描管脚 sbit R_scan=P0^3; sbit L_led=P0^0; //LED控制管脚 sbit R_led=P0^1; //=============PWM================ #define PWM_COUST 100 //PWM细分等份 unsigned int MOTO_speed1; //左边电机转速 unsigned int MOTO_speed2; //右边电机转速 unsigned int PWM_abs1; //左边电机取绝对值后占空比 unsigned int PWM_abs2; //左边电机取绝对值后占空比 //uchar PWM_var1=20; //左边电机直走速度 (不同的电机,此参数不同) //uchar PWM_var2=20; //右边电机直走速度 unsigned int PWMAnd = 0; //PWM自增变量 /****************************************************************** 名称:motor(char speed1,char speed2); 功能:同时调节电机的转速 参数:speed1:电机1的PWM值;speed2:电机2的PWM值 speed>0.正转;speed<0.反转(-100~100) 调用:extern int abs(int val); 取绝对值 返回: ******************************************************************/ void motor(unsigned int speed1,unsigned int speed2) { MOTO_speed1=speed1; MOTO_speed2=speed2; //==============左边电机============= if(speed1==0) { IN1 =0;IN2 =0; } if (speed1>0) { IN1 =0;IN2 =1;//正转 } else if (speed1<0) { IN1 =1;IN2 =0;//反转 } //==============右边电机============= if (speed2==0) { IN3 =0;IN4 =0;//不转 } if (speed2>0) { IN3 =1;IN4 =0;//正转 } else if (speed2<0) { IN3 =0;IN4 =1;//反转 } } /****************************************************************** 名称:motor_PWM(); 功能:PWM占空比输出 参数:无 调用:无 返回:无 ******************************************************************/ void motor_PWM () { PWM_abs1=abs(MOTO_speed1); PWM_abs2=abs(MOTO_speed2); if (PWM_abs1>PWMAnd) ENA=1; //左边电机占空比输出 else ENA=0; if (PWM_abs2>PWMAnd) ENB=1; //右边电机占空比输出 else ENB=0; if (PWMAnd>=PWM_COUST) PWMAnd=0; //PWM计数清零 else PWMAnd+=1; } /****************************************************************** 名称:void TIME_Init (); 功能:定时器初始化 指令: 调用:无 返回:无 ******************************************************************/ void TIME_Init () { //=========定时器T0初始化 PWM================== EA=1; // TCON = 0x10; TMOD = 0x01; TH0 = 0xff; TL0 = 0x9B; // TL0 = 0x47; ET0 = 1; //定时器1中断开 TR0 = 1; //PWM定时器开,PWM周期为10ms } /****************************************************************** 名称:void PWM_Time0 () interrupt 0 功能:T2中断,PWM控制 参数: 调用:motor_PWM();//PWM占空比输出 返回: ******************************************************************/ void PWM_Time0 () interrupt 1 { TR0 = 0; //TF2 = 0; ET0 = 0; //定时器0中断禁止 TH0 = 0xff; TL0 = 0x9B; motor_PWM();//PWM占空比输出 ET0 = 1; //定时中断0开启 TR0 = 1; } //扫描传感器状态 unsigned char scan(void) { unsigned char i,result,temp1,temp2; for(i=38;i>0;i--) //LED发送38次脉冲 { L_led=0; delay_nus(12); L_led=1; delay_nus(12); } temp1=L_scan; //记录传感器状态 for(i=38;i>0;i--) //另一侧发脉冲 { R_led=0; delay_nus(12); R_led=1; delay_nus(12); } temp2=R_scan; //记录传感器状态 if(temp2==1&&temp1==1) //两侧都扫描到黑边 result=1; if(temp1==0&&temp2==1) //左侧扫描到白线 result=0; if(temp1==1&&temp2==0) //右侧扫描到白线 result=2; if(temp1==0&&temp2==0) //两侧都扫描到白线 result=3; return result; } unsigned char result;
void main() { while(1) { result=scan(); if(result==1) //直走 { unsigned int i=0; unsigned int y=0; TIME_Init () ; motor(100,100);//电机的转速 } else if(result==0)//左转,左轮停止 { unsigned int i=0; unsigned int y=0; TIME_Init () ; motor(0,100);//电机的转速 while(1); } else if(result==2)//右转,右轮停止 { unsigned int i=0; unsigned int y=0; TIME_Init () ; motor(100,0);//电机的转速 } else if(result==3)//两边都没有返回的状态(比如小车悬空)~自己定吧,这里停车 { unsigned int i=0; unsigned int y=0; TIME_Init () ; motor(0,0);//电机的转速 } delay_nms(200);//延时200ms } } 求高手指点程序中错误
[此贴子已经被作者于2011-10-20 20:25:46编辑过]
|