智能循迹小车:从模块到代码全解析
智能循迹小车一个循迹小车主要有以下几个模块组成1电机驱动模块电机驱动模块是L298N只要将相应接口使用杜邦线连接在单片机上再由程序控制相应接口的电平高低就可以控制俩个电机的转动实现小车前进、后退、左转、右转等动作。2PWM调速模块3红外循迹模块剩下的就是在主函数中对这几个模块进行相互配合让小车能够在红外寻迹模块的反馈下通过PWM模块的调速使电机驱动。以下是一个完整的代码流程在引用时请读者考虑到自己所接电机的运行与停止实时更改代码中的1001等。1)电机PWM.c #include REGX52.H sbit ENA1P1^4; sbit ENB1P1^5; sbit ENA2P1^7; sbit ENB2P1^6; unsigned char compare_ENA1,compare_ENB1;//PWM比较 unsigned char compare_ENA2,compare_ENB2; unsigned char count_ENA1,count_ENB1; //PWM计数 unsigned char count_ENA2,count_ENB2; #define uchar unsigned char void Timer0_PWM_Init(void) { TMOD 0x01; TL0 0xA4; TH0 0xFF; TF0 0; TR0 1; ET01; EA1; } void PWM_Compare1( unsigned char Date1,Date2) { compare_ENA1Date1; compare_ENB1Date2; } void PWM_Compare2( unsigned char Date1,Date2) { compare_ENA2Date1; compare_ENB2Date2; } void Timer0_PWM_Run(void) interrupt 1 { TL0 0xA4; TH0 0xFF; count_ENA1; count_ENA1%100; if(count_ENA1compare_ENA1) { ENA11; } else if(count_ENA1compare_ENA1) { ENA10; } count_ENB1; count_ENB1%100; if(count_ENB1compare_ENB1) { ENB11; } else if(count_ENB1compare_ENB1) { ENB10; } count_ENA2; count_ENA2%100; if(count_ENA2compare_ENA2) { ENA21; } else if(count_ENA2compare_ENA2) { ENA20; } count_ENB2; count_ENB2%100; if(count_ENB2compare_ENB2) { ENB21; } else if(count_ENB2compare_ENB2) { ENB20; } } 2)PWM.h #ifndef __PWM_H__ #define __PWM_H__ void Timer0_PWM_Init(void); void PWM_Compare1( unsigned char Date1,Date2); void PWM_Compare2( unsigned char Date1,Date2); void Timer0_PWM_Run(void); #endif 3)主函数main.c #include REGX52.H #include trace.h #include pwm.h //#include tx.h sbit act P3^7; sbit beepP3^6; void main() { Timer0_PWM_Init(); beep1; while(1) { Trace(); } } 4)循迹trace.c #include reg52.h #include pwm.h //传感器引脚 sbit IR_1P1^0; sbit IR_2P1^1; sbit IR_3P1^2; sbit IR_4P1^3; //电机引脚 sbit IN11P3^2; sbit IN12P3^3; sbit IN13P3^4; sbit IN14P3^5; sbit IN21P2^0; sbit IN22P2^1; sbit IN23P2^2; sbit IN24P2^3; sbit beepP3^6; sbit act P0^2; void delay(unsigned int xms) { unsigned char i, j; while(xms) { i 2; j 239; do { while (--j); } while (--i); xms--; } } void L298N_Init1(unsigned char a,b,c,d) { IN11a; IN12b; IN13c; IN14d; } void L298N_Init2(unsigned char a,b,c,d) { IN21a; IN22b; IN23c; IN24d; } void Trace() { beep1; if(IR_11IR_21IR_31IR_41) //未检测到黑线直走 { PWM_Compare1( 20,20); PWM_Compare2( 20,20); L298N_Init1(0,1,1,0); L298N_Init2(1,0,0,1); beep1; } if(IR_11IR_20IR_31IR_41) //右检测到黑线向右转弯或调整 { PWM_Compare1( 50,10); PWM_Compare2( 50,10); L298N_Init1(0,1,0,1); L298N_Init2(1,0,1,0); delay(10); beep1; } if(IR_10IR_21IR_31IR_41) //右检测到黑线向右转弯或调整 { PWM_Compare1( 50,30); PWM_Compare2( 50,30); L298N_Init1(0,1,0,0); L298N_Init2(1,0,0,0); delay(10); beep1; } if(IR_11IR_21IR_31IR_40) //左检测到黑线左转或调整 { PWM_Compare1( 10,30); PWM_Compare2( 10,30); L298N_Init1(1,0,1,0); L298N_Init2(0,1,0,1); delay(10); beep1; } if(IR_11IR_21IR_30IR_41) //左检测到黑线左转或调整 { PWM_Compare1( 50,30); PWM_Compare2( 50,30); L298N_Init1(1,0,1,0); L298N_Init2(0,1,0,1); delay(10); beep1; } if(IR_10IR_20IR_31IR_41) //警报 { beep0; delay(100); beep1; PWM_Compare1( 20,20); PWM_Compare2( 20,20); L298N_Init1(0,1,1,0); L298N_Init2(1,0,0,1); } if(IR_11IR_20IR_30IR_41) //中间检测到黑线停止 { PWM_Compare1( 20,20); PWM_Compare2( 20,20); L298N_Init1(0,0,0,0); L298N_Init2(0,0,0,0); delay (20); beep1; } if(IR_10IR_20IR_30IR_40) //检测到黑线停止 { PWM_Compare1( 20,20); PWM_Compare2( 20,20); L298N_Init1(0,0,0,0); L298N_Init2(0,0,0,0); delay (20); beep1; }} 5)trace.h #ifndef __TRACE_H__ #define __TRACE_H__ void L298N_Init1(unsigned char a,b,c,d); void L298N_Init2(unsigned char a,b,c,d); void Trace(); #endif 6)定时器t.c #include REGX52.H #define uint unsigned int #define uchar unsigned char void Send_Data(uchar Key_val); void Usart_Init(void) { TMOD0X20; TH10xF3; TL10xF3; TR11; SM00; SM11; EA1; ES1; } void Send_Data(uchar sign) { SBUFsign; while(!TI); TI0; }