avr或51单片机pwm控制小车左右电机并调速.doc
avr或51单片机pwm控制小车左右电机并调速,红外对管检测的程序 / Crystal: 8.0000Mhz #include <iom16v.h> #include <macros.h> #define uchar unsigned char #define uint unsigned int uint discrepancy=0; /function declaration void port_init(void); void motor(uchar index, uchar speed);/input PWM wave 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 right void delayms(uint MS) ; /call this routine to initialize all peripherals调用这个例程初始化所有外设void init_devices0(void) /stop errant interrupts until set up CLI(); /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 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;/禁止JTAG GICR = 0x00; SEI();/开全局中断 /PWM 调速,通过改变占空比,周期性地开闭使能端,调节电机的有效电压。/use PD4,PD5 to output PWM,speed(0255) void motor(uchar index, uchar speed) if(index=1) OCR1AH = 0x00; OCR1AL =speed; if(index=2) OCR1BH = 0x00; OCR1BL =speed; /delay time by ms void delayms(uint MS) uint i,j; for( i=0;i<MS;i+) for(j=0;j<1141;j+); /1141是在8MHz晶振下 /port initial void port_init( ) DDRA = 0x00;/input running state DDRB = 0xFF;/control two motors DDRC = 0x00; DDRD = 0x30;/PWM wave PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x30; /*传感器函数*/ /获取小车的行驶状态。0(直线),1(左偏),2(右偏),3(严重左偏), 4(严重右偏) /从左到右传感器(光电对管)对应的输入端口:PA0,PA1,PA2,PA3,PA4 /正常行驶时引导线夹在PA1,PA3之间 /根据端口PA0,PA1,PA3,PA4的值判断行驶状态。(中间传感器PA2并未使用) void sensor_state(void)/传感器状态 uchar state,state1,state2 ;/暂存PINA0PINA4相应位的值 state1=0b00000010&PINA;state2=0b00000001&PINA; if(state1=0b00000010) if(state2=0b00000001) discrepancy=4; return; else discrepancy=2;return; state1=0b00001000&PINA;state2=0b00010000&PINA; if(state1=0b00001000) if(state2=0b00010000) discrepancy=3; return; else discrepancy=1; return; /补充严重左偏或严重右偏的情况 state=0b00000001&PINA; if(state=0b00000001) discrepancy=4;return; state=0b00010000&PINA; if(state=0b00010000) discrepancy=3;return ; discrepancy=0; /*循迹函数*/ /ENA-PD4,ENB-PD5,PORTB03-IN13 ,L298电机驱动电路 /PB0,PB1控制右电机,PB1,PB2控制左电机 void revise_to_line( )/0=run forward,1=left,2=right,3=sever left,4=sever right if (discrepancy=0) /PORTB=0b11111001; PORTB|=(1<<PB3)|(1<<PB0); PORTB&=(1<<PB1)|(1<<PB2); delayms(10); return; if (discrepancy=1) /PORTB=0b11111000; PORTB|=(1<<PB3); PORTB&=(1<<PB0)|(1<<PB1)|(1<<PB2); while(0b00001000&PINA)=0b00001000);/get the value of PINA3 return; if (discrepancy=2) / PORTB=0b11110001; PORTB|=(1<<PB0); PORTB&=(1<<PB1)|(1<<PB2)|(1<<PB3); while(0b00000010&PINA)=0b00000010) ;/get the value of PINA1 return; if (discrepancy=3) / PORTB=0b11111000; PORTB|=(1<<PB3); PORTB&=(1<<PB0)|(1<<PB1)|(1<<PB2); while(0b00001000&PINA)=0b00001000);/get the value of PINA3 return; if (discrepancy=4) PORTB|=(1<<PB0); PORTB&=(1<<PB1)|(1<<PB2)|(1<<PB3); while(0b00000010&PINA)=0b00000010) ;/get the value of PINA1 return; /main function:action structure / / void main(void) port_init(); init_devices1( ); /set speed value motor(1,200); motor(2,200); while(1) sensor_state( );/传感器状态 revise_to_line( );