
// Target : M16
// Crystal: 8.0000Mhz
#include #include #define uchar unsigned char #define uint unsigned int //global variable declaration uint discrepancy=0;//,store the cerrent running condition uint count_cross=0 ;//global variable,store the number of black0cross(include the starting ling) passed by uint flag=0;//global variable ,if the running condition cann't be recognized ,set flag=1 //function declaration void port_init(void); void timer1_init(void); void init_devices(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 uint tiaoma_shibie(void); void delayms(uint MS) ; //*****************延时函数ms级***************************// void delayms(uint MS) { uint i,j; for( i=0;i } void port_init(void) { DDRA = 0x00; DDRB = 0x0F; DDRC = 0x00; DDRD = 0x30; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x3c; } //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_devices(void) { CLI(); //禁止所有中断 MCUCR = 0x00; MCUCSR = 0x80;//禁止JTAG GICR = 0x00; SEI();//开全局中断 port_init( ); timer1_init( ); } /*****************传感器函数********************/ //获取小车的行驶状态。0(直线),1(左偏),2(右偏),3(严重左偏),4(严重右偏) //从左到右传感器(光电对管)对应的输入端口:PA0,PA1,PA2,PA3,PA4 //根据端口PA0,PA1,PA3,PA4的值判断行驶状态。(中间传感器PA2并未使用) void sensor_state(void) { uchar state,state1,state2 ;//暂存PINA0~PINA4相应位的值 //flag=1; //default value: cann't be recognized if(count_cross=0)//when all are not on the black line, if in the starting area, run forward,if not set flag=1 { //state=0b00011011&PINA; //在启动区,直线前进 //if(state==0b00000000) discrepancy=0;flag=0; return; } state=0b00011111&PINA; if(state==0b00011111) {discrepancy=0;flag=0;count_cross++;return;} state1=0b00001011&PINA;state2=0b00011010&PINA; if((state1==0b00000111)|(state2==0b00011100)|state==0b00001110) {discrepancy=0;flag=0;return; }// running through the black cross or starting line //state=0b00000100&PINA; //if(state==0b00000100) {discrepancy=0;return;} //排除特例后,再进行各种情况的分析 sta te1=0b00000010&PINA;state2=0b00000001&PINA; if(state1==0b00000010) { if(state2==0b00000001) {discrepancy=4;flag=0; return;} else {discrepancy=2;flag=0;return; } } state1=0b00001000&PINA;state2=0b00010000&PINA; if(state1==0b00001000) { if(state2==0b00010000) {discrepancy=3;flag=0; return;} else {discrepancy=1;flag=0; return;} } //补充严重左偏或严重右偏的情况 state=0b00000001&PINA; if(state==0b00000001) {discrepancy=4;flag=0;return; } state=0b00010000&PINA; if(state==0b00010000) {discrepancy=3;flag=0;return ;} //if cann't be recongnized, keep discrepancy unchanged //note:it sometimes runs wrongly when passing by the balck-cross discrepancy=0; return; } /************************循迹函数******************/ //ENA---PD4,ENB---PD5,PORTB0~3----IN1~3 ,L298电机驱动电路 void revise_to_line( )//0=run forward,1=left,2=right,3=sever left,4=sever right { //正常行驶速度 //motor(1,255); //motor(2,255); //if((count_cross==2)|(count_cross==3)) //上坡,下坡减速 //{ //motor(1,200); //motor(2,200); //} if (discrepancy==0) { PORTB=0b11111001; //while((0b00001110&PINA)==0b00000100);//get the value of PINA2,可用延时控制delay(10). delayms(10); return; } if (discrepancy==1) { PORTB=0b11111000; while((0b00001000&PINA)==0b00001000);//get the value of PINA3 //check revise effection // sensor_state(); //if(flag) //{ //PORTB=0b11110001;//反向回调,可能出现退行。 // while((0b00000100&PINA)!=0b00000100);// assume if PINA2=1,then the conditon must can be recognized //} return; } if (discrepancy==2) { PORTB=0b11110001; while((0b00000010&PINA)==0b00000010) ;//get the value of PINA1 //check revise effection //sensor_state(); //if(flag) //{ //PORTB=0b11111000; //while((0b00000100&PINA)!=0b00000100);// assume if PINA2=1,then the conditon must can be recognized // } return; } if (discrepancy==3) { PORTB=0b11111000; while((0b00001000&PINA)==0b00001000);//get the value of PINA3 //check revise effection // sensor_state(); // if(flag) // { // PORTB=0b11110001;//反向回调,可能出现退行。 // while((0b00000100&PINA)!=0b00000100);// assume if PINA2=1,then the conditon must can be recognized // } return; } if (discrepancy==4) { PORTB=0b11110001; while((0b00000010&PINA)==0b00000010) ;//get the value of PINA1 //check revise effection // sensor_state(); // if(flag) // { // PORTB=0b11111000; // while((0b00000100&PINA)!=0b00000100);// suppose if PINA2=1,then the conditon must can be recognized // } } } //note:the value of count_cross must be accurate(未考虑反复通过跷跷板的情况) //PWM 调速,通过改变占空比,周期性地开闭使能端,调节电机的有效电压。 void motor(uchar index, uchar speed) { if(index==1) {OCR1AH = 0x00; OCR1AL =speed; } if(index==2) {OCR1BH = 0x00; OCR1BL =speed; } } /*********************识别条形码函数***************/ //输入口PA5,传感器为光电对管 //uint area 指示机关区的位置 uint tiaoma_shibie(void) { uchar state; uint t[5]={0};// t[i] store the time used when running through tiao xing ma uint temp=0;//记录延时次数 uint t_ave,t_max,t_min,i=5; uint flag1=1,flag2=1; uint area;//ji lu ji guan shi wei zhi 0(D),1(C),2(B),3(A),4(wei shi bie qing kuang) while(i>0) { flag1=0; //shi fou shi bie dao tiao xing ma state=0b00100000&PINA;// use PORTA5 as input port while(state==0b00100000) {delayms(10);temp++;flag1=1;state=0b00100000&PINA;}//assume 10ms is far less than the total time sued if(flag1)//shi bie dao tiaoxingma { t[--i]=temp; } } //tiaoxingma chu li t_max=t_min=t[0]; for( i=1;i<5;i++) { if(t[i]>t_max) t_max=t[i]; else if(t[i] t_ave=(t_max+t_min)/2; //data type is int not float to reduce CPU resource used //jie yi tiao xing ma for( i=0;i<5;i++) { if(t[i]>t_ave) t[i]=1; else if(t[i] } if(flag2) { uint value; value=t[0]+2*t[1]+4*t[2]+8*t[3]+16*t[4]; switch(value) { case 0b10011 :area=3;break; case 0b10101 :area=2;break; case 0b10111 :area=1;break; case 0b11001 :area=0;break; case 0b11011 :area=2;break; case 0b11101 :area=1;break; default: area=4; //wei shi bie qing kuang } } else area=4 ; //tiao ma wei shi bie return area; } /**********************/ //all the functions above have been tested successfully.2010-9-21 // void main(void) { //uint A; //PORTB=0x09; init_devices(); //motor(1,255); //motor(2,255); // while(1){sensor_state( );revise_to_line( );} //uint A; //A=tiaoma_shibie( ); motor(1,255); motor(2,255); while(1) if((PINA&0x40)==0x00)break; //motor(1,100); //motor(1,100); while(1){sensor_state( );revise_to_line( );} //have been downloded }
