| 程序有bug,仿真看一下哪里有问题就知道了 |
滥情 发表于 2020-5-14 17:16 unsigned char getkey(void) { unsigned char result=0; if(key == 0) { delay_nms(10); if(key == 0) { result++; while(!key); } } if(result > 4) { result = 1; } return result; } unsigned char DelayWaitKey(unsigned int Delayms) { unsigned char tmpkey; z=0; TR1=1; while (z<(Delayms/50)) { tempkey=getkey(); if (tempkey!=0) { TR1=0; z=0; return tempkey; } } TR1=0; z=0; return 0; } unsigned char wudao(void) { unsigned char tmpResult; tingzhi(); tmpResult=DelayWaitKey(1000); if (tmpResult>0) return tmpResult; qianjin(); tmpResult=DelayWaitKey(3000); if (tmpResult>0) return tmpResult; tingzhi(); tmpResult=DelayWaitKey(150); if (tmpResult>0) return tmpResult; youzhuan(); tmpResult=DelayWaitKey(150); if (tmpResult>0) return tmpResult; tingzhi(); tmpResult=DelayWaitKey(150); if (tmpResult>0) return tmpResult; qianjin(); tmpResult=DelayWaitKey(300); if (tmpResult>0) return tmpResult; tingzhi(); tmpResult=DelayWaitKey(150); if (tmpResult>0) return tmpResult; youzhuan(); tmpResult=DelayWaitKey(150); if (tmpResult>0) return tmpResult; tingzhi(); tmpResult=DelayWaitKey(150); if (tmpResult>0) return tmpResult; qianjin(); tmpResult=DelayWaitKey(3000); if (tmpResult>0) return tmpResult; tingzhi(); tmpResult=DelayWaitKey(150); if (tmpResult>0) return tmpResult; youzhuan(); tmpResult=DelayWaitKey(150); if (tmpResult>0) return tmpResult; tingzhi(); tmpResult=DelayWaitKey(150); if (tmpResult>0) return tmpResult; qianjin(); tmpResult=DelayWaitKey(3000); if (tmpResult>0) return tmpResult; tingzhi(); return 0; } //------------------------------------------------------------------------------------------------------- void main() //主程序入口 { // bit RunFlag=0; //定义小车运行标志位 bit IsMusicFlag=0; // LedFlash=3000; //对闪灯数据进行初始化 EX1=1; //同意开启外部中断1 IT1=1; //设定外部中断1为低边缘触发类型 EA=1; //总中断开启 // ET1=1; tingzhi(); //初始化小车运行状态 Timer1Init();//定时器1初始化 while(1) //程序主循环 { if (!IsMusicFlag) { temp=getkey(); } switch(temp) { case 1: IsMusicFlag=0; tingzhi(); //forward(); Stop_Music(); break; case 2: IsMusicFlag=0; Robot_Avoidance(); EX1 = 0; break; case 3: IsMusicFlag=0; EX1 = 1; break; case 4: IsMusicFlag=1; temp=Star_Music(); break; }//switch }//while(1) }//main 理解下。。 |
| 中断那里出了优先级问题,别把wudao函数写入中断,程序执行不到吧 |
carpcarey 发表于 2020-5-14 09:56 我用定时器写了舞蹈但是还是为什么还是caes4切换不到case没有做用,楼下是我的代码能帮我看看吗,还有就是为什么我用注释的wudao()而不是现在这个wudao()的时候,放音乐的时候小车不转。是if语句用的不对吗 |
|
#include <REGX52.H> //包含51单片机相关的头文件 #include <intrins.h> sbit LeftIR=P3^5; //定义前方左侧红外探头端口 sbit RightIR=P3^4; //定义前方右侧红外探头端口 sbit IN1=P1^2; //定义左侧电机驱动A端 sbit IN2=P1^3; //定义左侧电机驱动B端 sbit IN3=P1^4; //定义右侧电机驱动A端 sbit IN4=P1^5; sbit EN1=P1^6; sbit EN2=P1^0; sbit Beep=P2^3; //定义蜂鸣器端口 sbit IRIN=P3^3; //定义红外接收端口 sbit p00=P0^0; //LED sbit p01=P0^1; //LED sbit p02=P0^2; //LED sbit p03=P0^3; //LED sbit p04=P0^4; //LED sbit p05=P0^5; //LED sbit p06=P0^6; //LED sbit p07=P0^7; //LED sbit sda=P1^1; sbit key=P3^2; #define Left_moto_pwm P1_6 //PWM信号端 #define Right_moto_pwm P1_7 //PWM信号端 #define Left_moto_go {P1_2=1,P1_3=0;} //左电机向前走 #define Left_moto_back {P1_2=0,P1_3=1;} //左边电机向后转 #define Left_moto_Stop {P1_2=0,P1_3=0;} //左边电机停转 #define Right_moto_go {P1_4=1,P1_5=0;} //右边电机向前走 #define Right_moto_back {P1_4=0,P1_5=1;} //右边电机向后走 #define Right_moto_Stop {P1_4=0,P1_5=0;} //右边电机停转 unsigned char pwm_val_left =0;//变量定义 unsigned char push_val_left =0;// 左电机占空比N/20 unsigned char pwm_val_right =0; unsigned char push_val_right=0;// 右电机占空比N/20 unsigned char code RecvData[]={0x19,0x18,0x52,0x5A,0x08,0x1C,0x16,0x45,0x46,0x47,0x0D,0x0E,0x00,0x0F}; unsigned char temp = 1; unsigned char IRCOM[7];//接收数据缓冲区 unsigned int z; bit Right_moto_stop=1; bit Left_moto_stop =1; unsigned int time3=0; /*********************************************************************/ void tingzhi(void) { P1_2 = 0; P1_3 = 0; P1_4 = 0; P1_5 = 0; } void qianjin(void) { push_val_left=3; //速度调节变量 0-20。。。0最小,20最大 push_val_right=3; Left_moto_go ; //左电机往前走 Right_moto_go ; //右电机往前走 } void houtui() { push_val_left=12; //速度调节变量 0-20。。。0最小,20最大 push_val_right=12; Left_moto_back ; //左电机往前走 Right_moto_back ; //右电机往前走 } void zuozhuan() { push_val_left=6; push_val_right=12; Right_moto_go ; //右电机往前走 Left_moto_back ; //左电机后走 } void youzhuan() { push_val_left=12; push_val_right=6; Left_moto_go ; //左电机往前走 Right_moto_back ; //右电机往后走 } /************************************************************************/ /* PWM调制电机转速 */ /************************************************************************/ /* 左电机调速 */ /*调节push_val_left的值改变电机转速,占空比 */ void pwm_out_left_moto(void) { if(Left_moto_stop) { if(pwm_val_left<=push_val_left) { Left_moto_pwm=1; } else { Left_moto_pwm=0; } if(pwm_val_left>=20) pwm_val_left=0; } else { Left_moto_pwm=0; } } /******************************************************************/ /* 右电机调速 */ void pwm_out_right_moto(void) { if(Right_moto_stop) { if(pwm_val_right<=push_val_right) { Right_moto_pwm=1; } else { Right_moto_pwm=0; } if(pwm_val_right>=20) pwm_val_right=0; } else { Right_moto_pwm=0; } } /***************************************************/ ///*TIMER0中断服务子函数产生PWM信号*/ void timer0()interrupt 1 using 2 { TH0=0xFc; TL0=0X18; time3++; pwm_val_left++; pwm_val_right++; pwm_out_left_moto(); pwm_out_right_moto(); } void Timer1Init() //50毫秒@11.0592MHz { // AUXR &= 0xBF; //定时器时钟12T模式 TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x10; //设置定时器模式 TL1 = 0x00; //设置定时初值 TH1 = 0x4C; //设置定时初值 TF1 = 0; //清除TF1标志 EA=1; ET1=1; TR1 = 1; //定时器1开始计时 } void Timer1() interrupt 3//晶振频率是11.0592M { TH1=0X00; //给定时器赋初值,定时50ms TL1=0x4C; z++; } void Delay1ms(unsigned int i) { unsigned char j,k; do{ j = 10; do{ k = 50; do{ _nop_(); }while(--k); }while(--j); }while(--i); } 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,同时进行补偿 } void delayms(unsigned char x) //0.14mS延时程序 { unsigned char i; //定义临时变量 while(x--) //延时时间循环 { for (i = 0; i<13; i++) {} //14mS延时 } } void delay5(unsigned int i) //延时程序 {while(i--);} void Delay1us ( int T ) { while(T!=0) { _nop_(); T--; } } void led_delay(void) { unsigned char i,j; for(i=0;i<220;i++) for(j=0;j<220;j++); } /* void wudao(void) { Timer1Init(); while(1) { if(z>=3){ z=0; tingzhi(); } if(z>=60){ z=0; qianjin(); } if(z>=3){ z=0; tingzhi(); } if(z>=3){ z=0; youzhuan(); } if(z>=3){ z=0; tingzhi(); } if(z>=60){ z=0; qianjin(); } if(z>=3){ z=0; tingzhi(); } if(z>=3){ z=0; youzhuan(); } if(z>=3){ z=0; tingzhi(); } if(z>=60){ z=0; qianjin(); } if(z>=3){ z=0; tingzhi(); } if(z>=3){ z=0; youzhuan(); } if(z>=3){ z=0; tingzhi(); } if(z>=3){ z=0; qianjin(); } tingzhi(); } } */ void wudao(void) { Timer1Init();//定时器1初始化 while(1) { tingzhi(); TR1=1; while(z!=3); TR1=0; z=0; qianjin(); TR1=1; while(z!=60); TR1=0; z=0; tingzhi(); TR1=1; while(z!=3); TR1=0; z=0; youzhuan(); TR1=1; while(z!=3); TR1=0; z=0; tingzhi(); TR1=1; while(z!=3); TR1=0; z=0; qianjin(); TR1=1; while(z!=6); TR1=0; z=0; tingzhi(); TR1=1; while(z!=3); TR1=0; z=0; youzhuan(); TR1=1; while(z!=3); TR1=0; z=0; tingzhi(); TR1=1; while(z!=3); TR1=0; z=0; qianjin(); TR1=1; while(z!=60); TR1=0; z=0; tingzhi(); TR1=1; while(z!=3); TR1=0; z=0; youzhuan(); TR1=1; while(z!=3); TR1=0; z=0; tingzhi(); TR1=1; while(z!=3); TR1=0; z=0; qianjin(); TR1=1; while(z!=60); TR1=0; z=0; tingzhi(); } } void forward(void)//两边 { P0=0x7e; led_delay(); P0=0xbd; led_delay(); P0=0xdb; led_delay(); P0=0xe7; led_delay(); P0=0xe7; led_delay(); P0=0xdb; led_delay(); P0=0xbd; led_delay(); P0=0x7e; led_delay(); } void Alter(void)//交替 { P0=0xaa; led_delay(); P0=0x55; led_delay(); } void backward(void) { P0=0x7f; led_delay(); P0=0xbf; led_delay(); P0=0xdf; led_delay(); P0=0xef; led_delay(); P0=0xf7; led_delay(); P0=0xfb; led_delay(); P0=0xfd; led_delay(); P0=0xfe; led_delay(); } void blink(void) { P0=0xff; led_delay(); P0=0x00; led_delay(); } void deng1() //流水灯 {p00=0; p01=0; delay5(5000); p02=0; p03=0; delay5(5000); p04=0; p05=0; delay5(5000); p06=0; p07=0; delay5(5000); p07=1; p06=1; delay5(5000); p05=1; p04=1; delay5(5000); p03=1; p02=1; delay5(5000); p01=1; p00=1; delay5(5000);} void deng2() //流水灯 {p00=0; p01=1; delay5(5000); p02=0; p03=1; delay5(5000); p04=0; p05=1; delay5(5000); p06=0; p07=1; delay5(5000); p07=0; p06=1; delay5(5000); p05=0; p04=1; delay5(5000); p03=0; p02=1; delay5(5000); p01=0; p00=1; delay5(5000);} void deng3() //流水灯 {p00=0; p01=0; delay5(5000); p02=0; p03=0; delay5(5000); p04=0; p05=0; delay5(5000); p06=0; p07=0; delay5(5000); p07=1; p06=1; delay5(5000); p05=1; p04=1; delay5(5000); p03=1; p02=1; delay5(5000); p01=1; p00=1; delay5(5000);} void deng4() //流水灯 {p00=1; p01=1; p02=1; p03=1; p04=1; p05=1; p06=1; p07=1; } void Robot_Avoidance() //机器人避障子程序 { if(LeftIR==1&&RightIR ==1) //LeftIRBZ RightIRBZ { deng1(); qianjin(); delay_nms (10); // SB1=1; } else { if(LeftIR==1&&RightIR ==0) //右边检测到红外信号 { deng4(); youzhuan(); //右转 delay_nms (300); //停止300MS 防止电机反相电压冲击 导致系统复位 deng1(); } if(RightIR ==1&&LeftIR==0) //左边检测到红外信号 { deng4(); zuozhuan(); //左转 delay_nms (300); //停止300MS 防止电机反相电压冲击 导致系统复位 deng1(); } if(RightIR==0&&LeftIR==0) //两边传感器同时检测到红外 { // SB1=0; deng4(); tingzhi(); //停止 delay_nms (300); //停止300MS 防止电机反相电压冲击 导致系统复位 houtui(); //调用电机后退函数 delay_nms (300); //后退50毫秒 youzhuan(); //调用电机右转函数 delay_nms (400); deng1(); } } qianjin(); } void ControlCar_yaokong(unsigned char ConType) //定义电机控制子程序 (红外遥控单独设置一个 switch case 语句 ) { tingzhi(); switch(ConType) //判断用户设定电机形式 { case 1: //前进 //判断用户是否选择形式1 { tingzhi(); //进入前进之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 Delay1ms(150); // LeftLed = 0 ; qianjin(); break; } case 2: //后退 //判断用户是否选择形式2 { tingzhi(); //进入后退之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 Delay1ms(150); // LeftLed = 1 ; houtui(); //M2电机反转 break; } case 3: //右转 //判断用户是否选择形式3 { tingzhi(); //进入左转之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 Delay1ms(150); youzhuan(); //M2电机正转 break; } case 4: //左转 //判断用户是否选择形式4 { tingzhi(); //进入右转之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 Delay1ms(150); zuozhuan(); //M1电机正转 //M2电机反转 break; } case 5: //停止 //判断用户是否选择形式8 { tingzhi(); break; //退出当前选择 } case 6: //左转 //判断用户是否选择形式4 { //进入右转之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 Robot_Avoidance(); break; } case 7: //停止 //判断用户是否选择形式8 { deng2(); break; //退出当前选择 } case 8: //停止 //判断用户是否选择形式8 { deng4(); break; //退出当前选择 } } } //----------红外遥控------------------------------------------------------------- void IR_IN() interrupt 2 using 0 //定义INT2外部中断函数 { unsigned char j,k,N=0; //定义临时接收变量 EX1 = 0; //关闭外部中断,防止再有信号到达 delayms(15); //延时时间,进行红外消抖 if (IRIN==1) //判断红外信号是否消失 { EX1 =1; //外部中断开 return; //返回 } while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。 { delayms(1); //延时等待 } for (j=0;j<4;j++) //采集红外遥控器数据 { for (k=0;k<8;k++) //分次采集8位数据 { while (IRIN) //等 IR 变为低电平,跳过4.5ms的前导高电平信号。 { delayms(1); //延时等待 } while (!IRIN) //等 IR 变为高电平 { delayms(1); //延时等待 } while (IRIN) //计算IR高电平时长 { delayms(1); //延时等待 N++; //计数器加加 if (N>=30) //判断计数器累加值 { EX1=1; //打开外部中断功能 return; //返回 } } IRCOM[j]=IRCOM[j] >> 1; //进行数据位移操作并自动补零 if (N>=8) //判断数据长度 { IRCOM[j] = IRCOM[j] | 0x80; //数据最高位补1 } N=0; //清零位数计录器 } } if (IRCOM[2]!=~IRCOM[3]) //判断地址码是否相同 { EX1=1; //打开外部中断 return; //返回 } for(j=0;j<10;j++) //循环进行键码解析 { if(IRCOM[2]==RecvData[j]) //进行键位对应 { // ControlCar(j); ControlCar_yaokong(j); //数码管显示相应数码 } } EX1 = 1; //外部中断开 } void SendData ( unsigned char addr ) { unsigned char i; // EA = 0;/*发送时关掉中断,防止中断影响时序 */ sda = 1;/*开始拉搞 */ Delay1us ( 1000 ); sda = 0;/*开始引导码*/ Delay1us ( 3000 );/*此处延时最少要大于2ms,此参数延时为310ms */ for ( i = 0; i < 8; i++ ) /*总共8位数据 */ { sda = 1; if ( addr & 0x01 ) /*3:1表示数据位1,每个位用两个脉冲表示 */ { Delay1us ( 500 ); sda = 0; Delay1us ( 210 ); } else /*1:3表示数据位0 ,每个位用两个脉冲表示 */ { Delay1us ( 210 ); sda = 0; Delay1us ( 500 ); } addr >>= 1; } sda = 1; // EA = 1; } void Stop_Music() { SendData(0x0a); SendData(0x13); } void Star_Music() { SendData(0x0a); SendData(0x03); SendData(0x0b); wudao(); } //------------------------------------------------------------------------------------------------------- void main() //主程序入口 { // bit RunFlag=0; //定义小车运行标志位 // LedFlash=3000; //对闪灯数据进行初始化 EX1=1; //同意开启外部中断1 IT1=1; //设定外部中断1为低边缘触发类型 EA=1; //总中断开启 // ET1=1; tingzhi(); //初始化小车运行状态 while(1) //程序主循环 { if(key == 0) { delay_nms(10); if(key == 0) { temp++; while(!key); } } if(temp > 4) { temp = 1; } switch(temp) { case 1:tingzhi(); //forward(); Stop_Music(); break; case 2: Robot_Avoidance();EX1 = 0;break; case 3: EX1 = 1;break; case 4: Star_Music(); break; } } } |
| 中断那里出了问题,优先级 |
滥情 发表于 2020-5-10 22:58 我说的很明白,不要把wudao函数写入中断啊。 |
EDGClearlove7 发表于 2020-5-11 10:11 那要切换的话该怎么做呢?用定时器写延时吗?写的话是要把wudao()里面的全部写进去吗?不太会写 |
| case语句中执行玩wudao()才break |
carpcarey 发表于 2020-5-9 10:06 是要把wudao()这部分全写入中断里吗?不太会写啊 |
滥情 发表于 2020-5-8 17:16 Delay10000ms();用定时器做。wudao里的Delay10000ms()改为:启动定时器,看是不是到定时时间了,如果没到,看是不是有按键被按下了?没有的话继续看是不是到定时时间了。。如果有按键被按下了,那是不是停止?是停止键,那就停止播放,退出wudao函数。 |
| 非常有趣! 我希望我有空的时候可以尝试一下。 |
carpcarey 发表于 2020-5-6 17:20 这个我是是根据歌曲时间确定的,但是我想要让它随时能够切换该怎么办呢 |
| 你的wudao()函数耗时很长啊,至少30秒时间,也就是说,进入wudao()后,至少30秒才能返回主函数。当然这30秒就不会接受你按键处理了啊。 |
| 怎么,没人呢 |