各位大咖:烦请帮忙分析一下该程序,十分感谢!
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. }
|