各位大咖:煩請幫忙分析一下該程序,十分感謝!
1.當單片機收到紅外信號(temp=0x5e)時,即讓電機啟動標志位kai=1;定時器1中斷只運行到行號51.d,不知道為什么?
1. #include <reg52.h>
2. #define uchar unsigned char
3. #define uint unsigned int
4. /*------------------------------------------------
a) 紅外全局變量聲明
5. ------------------------------------------------*/
6. sbit IR=P3^2; //紅外接口標志
7. unsigned char irtime;//紅外用全局變量
8. bit irpro_ok,irok,zheng,fan;
9. uchar IRcord[4];
10. uchar irdata[33];
11. //加入紅外
12. sbit out=P2^0; //PWM輸出用于正傳
13. sbit out1=P2^2; //PWM輸出用于反轉
14. sbit test1=P2^1;
15.
16. uint m,flag_1,kai;
17. /*------------------------------------------------
1. 紅外函數聲明
18. ------------------------------------------------*/
19. void EX0init(void)
20. {
21. IT0 = 1; //指定外部中斷0下降沿觸發,INT0(P3.2)
22. EX0 = 1; //使能外部中斷
23. EA = 1; //開總中斷
24. }
25. /*------------------------------------------------
i. 鍵值處理
26. ------------------------------------------------*/
27. void Ir_work(uchar temp)//紅外鍵值散轉程序
28. {
i. if (temp== 0x5E)
1. kai=1-kai;
ii. if (temp==0x45 &&m<=199)
1. m++;
iii. if (temp==0x46 &&m>=1)
1. m--;
iv. if(temp==0x0c)
1. {zheng=1; //正傳標志置1
2. fan=0; } // 反轉標志置0
v. if (temp==0x18)
1. {zheng=0; //正傳標志置0
2. fan=1; } // 反轉標志置1
b) }
29. /*------------------------------------------------
a) 紅外碼值處理
30. ------------------------------------------------*/
31. void Ircordpro(void)//紅外碼值處理函數
32. {
a) unsigned char i, j, k;
b) unsigned char cord,value;
c) k=1;
d) for(i=0;i<4;i++) //處理4個字節
i. {
ii. for(j=1;j<=8;j++) //處理1個字節8位
1. {
2. cord=irdata[k];
3. if(cord>7)//大于某值為1,這個和晶振有絕對關系,這里使用12M計算,此值可以有一定誤差
a) value|=0x80;
4. if(j<8)
5. {
a) value>>=1;
6. }
7. k++;
8. }
iii. IRcord[ i]=value;
iv. value=0;
v. }
vi. irpro_ok=1;//處理完畢標志位置1
33. }
34. void initT0()//初始化函數
35. {
a) TMOD |=0x01; //定時器方式1
b) TH0=0xdc;
c) TL0=0x00; //定時器裝入初值
d) EA=1; //開總中斷
e) ET0=1; //定時器0開中斷
f) TR0=1;
36. }
37. void initT1()
38. {
a) TMOD |=0x01;
b) TH1=0xff;
c) TL1=0x66;//定時100us
d) EA=1;
e) ET1=1; //定時器1開中斷
f) TR1=1;
39. }
40. void main()
41. {
a) flag_1=0;
b) m=100; //占空比為100
c) zheng=1; //初始化電機正轉動
d) fan=0;
e) EX0init(); //初始化外部中斷
f) initT0(); //初始化 T0
g) initT1(); //初始化 T1
i. while(1)
1. {
2. if(irok) //如果接收好了進行紅外處理
a) {
b) Ircordpro();
c) irok=0;
d) }
3. if(irpro_ok) //如果處理好后進行工作處理,如按對應的按鍵后顯示對應的數字等
a) {
b) Ir_work(IRcord[2]);
c) }
4. }
42. }
43. void EX0_ISR (void) interrupt 0//外部中斷0服務函數
44. {
a) static unsigned char i; //接收紅外信號處理
b) static bit startflag; //是否開始處理標志位
45. if(startflag)
a) {
b) if(irtime<63&&irtime>=33)//引導碼 TC9012的頭碼,9ms+4.5ms
1. i=0;
2. irdata=irtime;//存儲每個電平的持續時間,用于以后判斷是0還是1
3. irtime=0;
4. i++;
a) if(i==33)
b) {
i. irok=1;
ii. i=0;
c) }
5. }
ii. else
iii. {
iv. irtime=0;
v. startflag=1;
vi. }
46. }
47. void int2()interrupt 1
48. {
a) irtime++; //用于計數2個下降沿之間的時間
49. }
50. void int3()interrupt 3 //產生PWM
51. {
a) TH1=0xff;
b) TL1=0x66;//定時100us
c) flag_1++;
d) if(flag_1>199)
i. flag_1=1;
e)
f) if(kai==1) //如果kai==1電機啟動
i. {
ii. if(zheng==1) //電機正轉
1. {
2. if(flag_1<m) //小于占空比m輸出PWM=0輸出電壓為1
i. {
ii. out=0;
iii. out1=1;
iv. }
b) else
i. {
ii. out=1;
iii. out1=1;
iv. }
c) }
iii. if(fan==1) //電機反轉
1. {
2. if(flag_1<m) //小于占空比m輸出PWM=0輸出電壓為1
a) {
b) out=1;
c) out1=0;
d) }
3. else //大于m輸出PWM=1輸出電壓為0
a) {
b) out=1;
c) out1=1;
d) }
4. }
5. }
6. if(kai==0) //kai=0電機停止轉動
a) {
b) out=1;
c) out1=1;
d) }
52. }
|