
#include #define l 1 //左电机 #define r 2 //右电机 #define rl 3 //左右电机 //#define S_B 70 //基准占空比设置 #define f 'f' //代表电机正转 #define forward 'f' #define b 'b' //代表电机反转 #define backward 'b' #define LCD_DATA_PORT P0 //接液晶数据口 #define LCD_EN P0_3 //接液晶使能端 #define LCD_RS P0_2 //RS=1写数据,RS=0写命令 //sbit clk=P1^0; sbit LED=P1^7; sbit W0=P1^3; //右电机PWM输出 sbit W1=P1^4; //左电机PWM输出 sbit DIR_0=P1^2; //右电机,PWM0的正反转控制位,1代表正,0代表反 sbit DIR_1=P1^5; //左电机,PWM1的正反转控制位,1代表正,0代表反 sbit start_=P3^2; //启动按键位 sbit stop_=P3^3; //停止按键位 sbit L=P2^5; //左传感器 sbit Z=P2^6; //中路传感器 sbit R=P2^7; //右传感器 sbit BZ=P2^4; //避障 unsigned char flag; unsigned int S=0;hour=0,min=0,sec=0,count=0; //定义时间路程变量 unsigned char data_code[]="happy every day"; unsigned char a[]="Time-"; unsigned char Data1[]={0,0,0,0,0,0,0,0,0,0,0}; unsigned char Data2[]={0,0,0,0,0}; //unsigned char tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 }; //unsigned char Data[4]={0,0,0,0}; //unsigned char select[4]={0x7f,0xbf,0xdf,0xef}; /*void delay(unsigned int n) {unsigned char i; while(n--) {for(i=0;i<125;i++) {;} } } */ /*======================================================================= 【函数原形】:void pwm0_1() 【功能说明】:PCA时钟源 控制寄存器 计数初值 设置 【编写日期】:2011年1月20日 ========================================================================*/ void pwm0_1() { CCON=0x00; //CR=0,PCA计数器停止计数 CH=0; CL=0; CMOD=0x00;//系统时钟,SYSclk/12,不用中断 } /*======================================================================= 【函数原形】:void PWM0(unsigned char Fosc_1) 【参数说明】:Fosc_0 Fosc_0为占空比设置形参 【编写日期】:2011年1月20日 ========================================================================*/ void PWM0(unsigned int Fosc_0) //Fosc_0为占空比设置形参 { CCAP0H=CCAP0L=((Fosc_0)*25)/10; CCAPM0=0X42; //8位PWM输出,无中断 PCA_PWM0=0x00; } /*======================================================================= 【函数原形】:void PWM1(unsigned char Fosc_1) 【参数说明】:Fosc_1 Fosc_1为占空比设置形参 【编写日期】:2011年1月20日 ========================================================================*/ void PWM1(unsigned int Fosc_1) { CCAP1H=CCAP1L=((Fosc_1)*25)/10; CCAPM1=0X42; PCA_PWM1=0x00; //8位PWM输出,无中断 } /*======================================================================= 【函数原形】:void delay_ms(unsigned int T) 【参数说明】:T 延时时间设定 【函数功能】:ms级延时函数 【编写日期】:2011年1月20日 ========================================================================*/ void delay_ms(unsigned int T) { unsigned int CON; unsigned int i; for(i=0;i } /*======================================================================= 【函数原形】:void motor(unsigned char m,unsigned char z,unsigned int n,) 【参数说明】:m 电机,z 方向,n 占空比 【编写日期】:2011年1月20日 ========================================================================*/ void motor(unsigned char m,unsigned char z,unsigned int n) {switch (m) { case r: if(z==forward||z==f) {CR=1; PWM0(n); DIR_0=0; } else if(z==backward||z==b) {CR=1; PWM0(n); DIR_0=1; } break; case l: if(z==forward||z==f) {CR=1; PWM1(n); DIR_1=0; } else if(z==backward||z==b) {CR=1; PWM1(n); DIR_1=1; } break; default: break; } } /*==================================================== 【函数原形】: void stop (unsigned char m) 【参数说明】: m:选择电机 【功能说明】: 停止电机转动 【修改时间】: ====================================================*/ /* void stop (unsigned char m) { switch(m) { case r : /*CR=0;*/ //PWM0(0);break; // case l : /*CR=0;*/ //PWM1(0);break; /* case rl : CR=0;PWM0(0);DIR_0=0;PWM1(0);DIR_1=0;break; default : break; } } */ /*==================================================== 【函数原形】: void S_T() 【功能说明】: 程序初始化 【参数说明】: 【编写时间】: 2011年3月6日 【修改时间】: ====================================================*/ void S_T() { P1M1=0x00; P1M0=0x18; P2M1=0xff; P2M0=0x00; P4SW=0x50; //P4.4和P4.6口设置,都为I/O输出口 pwm0_1(); //PWM的初始化设置 start_=1; while(start_==1) //等待按键 {;} } /*==================================================== 【函数原形】: void b_z() 【功能说明】: 避障程序 ====================================================*/ void b_z() { if(BZ==0&&flag==0) { motor(l,f,40); motor(r,f,80); TR0=1; } else if(BZ==1&&flag==0) { motor(l,f,20); motor(r,f,20); TR0=1; } } /*==================================================== 【函数原形】: void xunji_line() 【功能说明】: 轨迹程序 ====================================================*/ void xunji_line() { if((L==0)&&(Z==1)&&(R==0)) { motor(l,f,10); motor(r,f,10); TR0=1; } else if((L==1)&&(Z==1)&&(R==0)) { motor(l,f,80); motor(r,f,50); TR0=1; } else if((L==1)&&(Z==0)&&(R==0)) { motor(l,f,80); motor(r,f,45); TR0=1; flag=1; } else if((L==0)&&(Z==1)&&(R==1)) { motor(l,f,50); motor(r,f,80); TR0=1; } else if((L==0)&&(Z==0)&&(R==1)) { motor(l,f,45); motor(r,f,80); TR0=1; } else if(L==1&&Z==1&&R==1) { motor(l,f,100); motor(r,f,100); TR0=0; } else if((L==0)&&(Z==0)&&(R==0)) { flag=0; } } /**********************函数声明***************************/ void LCD_write_char (unsigned char Data,unsigned char command);//写命令或写数据函数 /*******************延时函数*************************/ //系统时钟:12MHZ void delay_nus(unsigned int n) //N us延时函数 { unsigned int i=0; for (i=0;i } void delay_nms(unsigned int n) //N ms延时函数 { unsigned char i=0; while(n--) { for (i=0;i<125;i++); } } /********************液晶初始化函数************************/ void LCD_init(void) { delay_nms(5); LCD_write_char(0x28,0); //4位显示 LCD_write_char(0x0c,0); //显示开 LCD_write_char(0x06,0); LCD_write_char(0x01,0); //清屏 } /********************液晶使能函数************************/ void LCD_en_write(void) { LCD_EN=0; delay_nus(3500); LCD_EN=1; delay_nus(3500); LCD_EN=0; } /*********************写命令或写数据函数*******************/ void LCD_write_data(unsigned char Data_command) { unsigned char temp; temp=Data_command; LCD_DATA_PORT&=0X0f;//LCD_DATA_PORT=LCD_DATA_PORT&0X0f LCD_DATA_PORT|=temp&0xf0; //写高四位 LCD_en_write(); temp=temp<<4; LCD_DATA_PORT&=0x0f; LCD_DATA_PORT|=temp&0xf0; //写低四位 LCD_en_write(); } /*********************写命令和写数据函数*******************/ //参数:command=1,写数据,command=0写命令 void LCD_write_char(unsigned char Data_or_command,unsigned char command) { if(command==0) {LCD_RS=0; //RS=0,选择指令寄存器 LCD_write_data(Data_or_command); } else { LCD_RS=1; //RS=1,选择数据寄存器 LCD_write_data(Data_or_command); } } /**********************设置显示地址函数********************/ void LCD_set_xy( unsigned char x, unsigned char y ) { unsigned char address; if (y == 0) address = 0x80 + x; else address = 0xc0 + x; LCD_write_char( address, 0 ); } /*********************写字符串函数************************/ //参数:X为显示在第几列,Y为显示在第几行,s为待显示字符串 void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) { LCD_set_xy( X, Y ); //写地址 while (*s) // 写显示字符 { LCD_write_char(*s,1); s ++; } } /************将十进数转换为ASCII表中对应的值(时间显示程序)***********/ void BCDtostring(unsigned char i,unsigned char j,unsigned char k,unsigned char count,unsigned char *p) { p[0]=i/10+0x30; p[1]=i%10+0x30; p[2]=':'; p[3]=j/10+0x30; p[4]=j%10+0x30; p[5]=':'; p[6]=k/10+0x30; p[7]=k%10+0x30; p[8]=':'; p[9]=count/10+0x30; p[10]=count%10+0x30; } /************路程显示转换程序***********/ void Data2_process(unsigned int s,unsigned char *p1) {unsigned int i; p1[0]=s/10000+0x30; i=s%10000; p1[1]=i/1000+0x30; i=i%1000; p1[2]=i/100+0x30; i=i%100; p1[3]=i/10+0x30; p1[4]=i%10+0x30; } /*******************定时器0初始化函数*********************/ void TIMER0_init() { TMOD=0x51; TH0=0x3c;//50ms定时初始值 TL0=0xb0; TH1=0x00; TL1=0x00; TR1=1; //TR0=1; EA=1; ET0=1; } /********************定时器0中断函数************************/ void TIMER0_OVER(void) interrupt 1 {// unsigned int count; // 中断次数计数值 count++; if(count==20) {count=0; sec++;//秒加1 if(sec==60) {sec=0; min++;//分加1 if(min==60) {min=0; hour++;// 时加1 if(hour==24) {hour=0;} //时清0 } } } } /*******************液晶显示函数*********************/ void LCD_Display() { delay_nms(1); BCDtostring(hour,min,sec,count,Data1); //将时、分、秒,毫秒转换为ASCII码 LCD_write_string(5,0,Data1); //显示时、分、秒 LCD_write_string(0,0,a); LCD_write_string(0,1,"LuChengS="); //路程字符显示 Data2_process(S,Data2);//将路程转换为ASCII码 LCD_write_string(9,1,Data2); //显示路程 LCD_write_string(14,1,"cm"); delay_nms(50); } /*----------------------- 主函数 -----------------------*/ void main() { TIMER0_init(); LCD_RS=1; LCD_EN=1; LCD_init(); P1=0xff; S_T(); //BRT=0XF1; //AUXR |=0X01; //WAKE_CLKO=0X04; while(1) { b_z(); xunji_line(); S=10*(TH1*256+TL1);//路程计算公式 LCD_Display(); } }
