|
發布時間: 2020-5-5 14:12
正文摘要:我在做用JQ8400放音樂讓小車跳舞,現在為什么按鍵切換到case4后,就停不下來了,可以從case1切換到case4,但是case4到case1就不行,能幫我看看嗎void wudao(void) { tingzh ... |
| 程序有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秒就不會接受你按鍵處理了啊。 |
| 怎么,沒人呢 |