用51单片机红外遥控舵机,用到外部中断0、定时器0、定时器1;定时器0用来红外解码,定时器1用来产生舵机的PWM,两个部分都会了,但是最后一步的使用红外遥控舵机在同一个程序里没反应,我想是定时器之间是不是有什么问题,有懂得吗?代码如下:
- #include <reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar code table[]={ //段选数组定义
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- uchar code aable[]={ //位选数组定义
- 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
- uchar irtimer;
- uchar irdata[33]; //接收红外发送的数据
- uchar bitnum;
- uchar ircode[4];
- uchar disp[8];
- uchar duoji_timer;
- uchar state = 0;
- sbit PWM1 = P2^0;
- sbit K1=P2^7;
- sbit K2=P2^6;
- sbit K3=P2^5;
- bit IRstart_Flag; //红外发送标志位
- bit IR_rec_ok_Flag; //接收红外发送的数据完毕标志位
- bit IR_code_ok_Flag; //数据解码完成标志位
- void delay(uint t)
- {
- uchar i,j;
- for(i=t;i>0;i--)
- for(j=110;j>0;j--);
- }
- void INT0_Init() //外部中断0初始化
- {
- IT0 = 1; //下降沿触发外部中断0
- EX0 = 1; //打开外部中断0
- EA = 1; //打开总中断
- }
- void Timer0_Init() //定时器0初始化
- {
- TMOD |= 0x02;
- TH0 = 0x00;
- TL0 = 0x00;
- ET0 = 1;
- EA = 1;
- TR0 = 1;
- }
- void Timer1_Init()
- {
- TMOD = 0x10;
- TH1 = 0xff;
- TL1 = 0x1a; //0.25ms
- ET1 = 0;
- TR1 = 1;
- }
- void irdata_pros() //红外数据判断处理函数,逻辑“0” OR 逻辑“1”
- {
- uchar i,j,n;
- uchar value;
- n = 1;
- for(j=0;j<4;j++)
- {
- for(i=0;i<8;i++)
- {
- value = value >>1;
- if(irdata[n] > 6) //判断是逻辑“0” OR 逻辑“1”,根据两者间的中间值6来判断
- {
- value |= 0x80;
- }
- n++;
- }
- ircode[j] = value;
- }
- IR_code_ok_Flag = 1;
- }
- void ir_work()
- {
- disp[0] = ircode[0]/16; //用户码
- disp[1] = ircode[0]%16;
- disp[2] = ircode[1]/16; //用户反码
- disp[3] = ircode[1]%16;
- disp[4] = ircode[2]/16; //数据码
- disp[5] = ircode[2]%16;
- disp[6] = ircode[3]/16; //数据反码
- disp[7] = ircode[3]%16;
- }
- void display()
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- P1=table[disp]; //段选
- P0=aable; //位选
- delay(10);
- }
- }
- void turn()
- {
- if(K1==0)
- {
- delay(20);
- state = -1;
- }
- if(K2==0)
- {
- delay(20);
- state = 0;
- }
- if(K3==0)
- {
- delay(20);
- state = 1;
- }
-
- switch(state)
- {
- case -1 :
- {
- if(duoji_timer <= 1)
- {
- PWM1 = 1;
- }
- else
- {
- PWM1 = 0;
- }
- break;
- }
- case 0 :
- {
- if(duoji_timer <= 5)
- {
- PWM1 = 1;
- }
- else
- {
- PWM1 = 0;
- }
- break;
- }
- case 1 :
- {
- if(duoji_timer <= 9)
- {
- PWM1 = 1;
- }
- else
- {
- PWM1 = 0;
- }
- break;
- }
- }
- }
- void main()
- {
- if(K1)
- {
- INT0_Init();
- Timer0_Init();
- while(1)
- {
-
- if(IR_rec_ok_Flag == 1)
- {
- irdata_pros();
- IR_rec_ok_Flag = 0;
- }
- if(IR_code_ok_Flag == 1)
- {
- ir_work();
- IR_code_ok_Flag = 0;
- }
- display();
- break;
- }
- }
- else
- {
- Timer1_Init();
- while(1)
- {
- turn();
- break;
- }
- }
- }
- void INT0_ISP() interrupt 0 //外部中断0服务函数
- {
- if(IRstart_Flag) //红外遥控开始发送
- {
- if(irtimer > 30) // 9ms/277.8us = 32 开头的引导码
- {
- bitnum = 0;
- }
- irdata[bitnum] = irtimer;//接收红外发送的数据
- irtimer = 0;
- bitnum++;
- if(bitnum==33) //接收红外发送的数据完毕
- {
- bitnum = 0;
- IR_rec_ok_Flag = 1;
- IRstart_Flag = 0;
- }
-
- }
- else
- {
- IRstart_Flag = 1;
- irtimer = 0;
- }
- }
- void Timer0_ISP()interrupt 1
- {
- irtimer++; //每隔(256*12/11.0592)加一 277.8us
- }
- void Timer1_ISP() interrupt 3 //定时器1服务函数
- {
- TH1 = 0xff;
- TL1 = 0x1A; //0.25ms
- duoji_timer++;
- if(duoji_timer == 80) //20ms
- {
- duoji_timer = 0;
- }
- }
懂得人很多,但是冲你这个代码排版也不会有人仔细看的,建议用发代码的功能。
-------------------------------------
#include
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={ //段选数组定义
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar code aable[]={ //位选数组定义
0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uchar irtimer;
uchar irdata[33]; //接收红外发送的数据
uchar bitnum;
uchar ircode[4];
uchar disp[8];
uchar duoji_timer;
uchar state = 0;
sbit PWM1 = P2^0;
sbit K1=P2^7;
sbit K2=P2^6;
sbit K3=P2^5;
bit IRstart_Flag; //红外发送标志位
bit IR_rec_ok_Flag; //接收红外发送的数据完毕标志位
bit IR_code_ok_Flag; //数据解码完成标志位
bit turn_flag;
void delay(uint t)
{
uchar i,j;
for(i=t;i>0;i--)
for(j=110;j>0;j--);
}
void INT0_Init() //外部中断0初始化
{
IT0 = 1; //下降沿触发外部中断0
EX0 = 1; //打开外部中断0
EA = 1; //打开总中断
}
void Timer0_Init() //定时器0初始化
{
TMOD |= 0x02;
TH0 = 0x00;
TL0 = 0x00;
ET0 = 1;
TR0 = 1;
}
void Timer1_Init() //定时器1初始化
{
TMOD = 0x10;
TH1 = 0xff;
TL1 = 0x1a; //0.25ms
EA = 1;
ET1 = 1;
TR1 = 1;
}
void irdata_pros() //红外数据判断处理函数,逻辑“0” OR 逻辑“1”
{
uchar i,j,n;
uchar value;
n = 1;
for(j=0;j<4;j++)
{
for(i=0;i<8;i++)
{
value = value >>1;
if(irdata[n] > 6) //判断是逻辑“0” OR 逻辑“1”,根据两者间的中间值6来判断
{
value |= 0x80;
}
n++;
}
ircode[j] = value;
}
IR_code_ok_Flag = 1;
}
void main()
{
while(1)
{
INT0_Init();
Timer0_Init();
if(IR_rec_ok_Flag == 1)
{
irdata_pros();
IR_rec_ok_Flag = 0;
}
if(IR_code_ok_Flag == 1)
{
EA = 0;
IR_code_ok_Flag = 0;
}
Timer1_Init();
if (K3==0)
{
delay(2);
state = -1;
}
if (K2==0 )
{
delay(2);
state = 0 ;
}
if (K1==0 )
{
delay(2);
state = 1 ;
}
}
}
void INT0_ISP() interrupt 0 //外部中断0服务函数
{
if(IRstart_Flag) //红外遥控开始发送
{
if(irtimer > 30) // 9ms/277.8us = 32 开头的引导码
{
bitnum = 0;
}
irdata[bitnum] = irtimer;//接收红外发送的数据
irtimer = 0;
bitnum++;
if(bitnum==33) //接收红外发送的数据完毕
{
EA = 0;
bitnum = 0;
IR_rec_ok_Flag = 1;
}
}
else
{
IRstart_Flag = 1;
irtimer = 0;
}
}
void Timer0_ISP()interrupt 1 //定时器0服务函数
{
irtimer++; //每隔(256*12/11.0592)加一 277.8us
}
void Timer1_ISP() interrupt 3 //定时器1服务函数
{
TR1 = 0;
TH1 = 0xff;
TL1 = 0x1A; //0.25ms
TR1 =1;
duoji_timer++;
switch(state)
{
case -1 :
{
if(duoji_timer <= 1)
{
PWM1 = 1;
}
else
{
PWM1 = 0;
}
break;
}
case 0 :
{
if(duoji_timer <= 5)
{
PWM1 = 1;
}
else
{
PWM1 = 0;
}
break;
}
case 1 :
{
if(duoji_timer <= 9)
{
PWM1 = 1;
}
else
{
PWM1 = 0;
}
break;
}
}
if(duoji_timer == 80) //20ms
{
duoji_timer = 0;
}
}
看代码是个很头疼的事儿,你这么求恐怕很难,别人也不会拿出几个小时时间给你解决这个问题。
另外不能确定是硬件还是软件的问题,所以看了半天可能白费时间。
建议你调试起来跑一下,把问题范围缩小,才好。
现在就是两个单独放在不同程序里的话都可以,但是放在同一个程序就不可以
定时器0用来红外解码,定时器1用来产生舵机的PWM,是不是亮功能都分别实现了。但是组合起来,就不正常。具体什么情况呢。是红外解码异常,还是pwm异常。如何异常,是收不到数据,还是数据错误,和正确数据之间有什么关系。pwm是不能产生,还是波形不对。根据具体结果往下分析。初始化,以及后面两部分的运行语句,会不会相互之间有影响。比如说,初始化,每一个配置都看分析,这个配置会不会对一个功能有影响。初始化分析完,再看运行时的情况。
#include
#include
sbit IR = P3^2;
sbit BEEP = P3^6;
sbit PWM_OUT = P0^0;
bit inf_flag = 1; //ºìÍâ½ÓÊյĿªÆô¹Ø±Õ¿ØÖÆ룬ÔÚºìÍâ½âÂë¹ý³ÌÖÐÒª¹Ø±ÕºìÍâ½ÓÊÕ
bit ecode_ok; //½âÂë³É¹¦±ê־λ
unsigned char ircode[4];
unsigned int LowTime,HighTime; //ºìÍâ½ÓÊÕ¹ý³ÌÖб£´æ¸ß¡¢µÍµçƽµÄ¿í¶È
unsigned char se_PWM =15; //³õʼ»¯¶æ»úµÄPWM£¨¸ßµçƽʱ¼ä£©
unsigned char key_stime_counter; //¼Ç¼×ܵÄÖжϴÎÊý£¬³¬¹ý200(20ms)´Î¾Í»Ø0
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++);
}
void delay(unsigned char n)
{
unsigned char i;
for(i=0;i
delay1ms();
}
void beep()
{
unsigned char i;
for(i=0;i<100;i++)
{
delay1ms();
BEEP = !BEEP; //beepÈ¡·´
}
BEEP = 1 ;//¹Ø±Õ·äÃùÆ÷
delay(250); //ÑÓʱ
}
void DeCode()
{
unsigned char i,j;
unsigned char temp; //´¢´æ½âÂë³öµÄÊý¾Ý
for(i=0;i<4;i++) //Á¬Ðø¶ÁÈ¡4¸öÓû§ÂëÓëÊý¾ÝÂë
{
for(j=0;j<8;j--) //ÿ¸öÂëÓÐ8λÊý¾Ý
{
temp = temp>>1; //¸÷Êý¾ÝλÓÒÒÆһ룬ÒòΪÏȶÁ³öµÄÊǸßλÊý¾Ý
TH0 = 0;
TL0 = 0; //¶¨Ê±Æ÷0ÇåÁã
TR0 = 1; //´ò¿ª¶¨Ê±Æ÷0
while(IR == 0)
{
;
} //Èç¹ûÊǵ͵çƽ¾ÍµÈ´ý£¬¸øÒýµ¼ÂëµÍµçƽ¼Æʱ
TR0 = 0;//¹Ø±Õ¶¨Ê±Æ÷0
LowTime = TH0*256 + TL0; //±£´æµÍµçƽʱ¼ä
TH0 = 0;
TL0 = 0; //¶¨Ê±Æ÷0ÇåÁã
TR0 = 1; //´ò¿ª¶¨Ê±Æ÷0
while(IR == 1)
{
;
} //Èç¹ûÊǸߵçƽ¾ÍµÈ´ý
TR0 = 0;
HighTime = TH0*256 + TL0; //±£´æ¸ßµçƽʱ¼ä
if((LowTime < 370)||(LowTime >640))
{
ecode_ok = 0; //Èç¹ûµÍµçƽ³¤¶È²»ÔÚºÏÀí·¶Î§£¬ÔòÈÏΪ³ö´í£¬Í£Ö¹½âÂë
}
if((HighTime > 420) && (HighTime < 620))
//Èç¹û¸ßµçƽʱ¼äÔÚ560us×óÓÒ£¬560us / 1.085us = 516 ´Î
{
temp = temp&0x7f; //(520 - 100 =420 , 520 + 100 = 620),Ϊ0
}
if((HighTime >1300) && (HighTime < 1800))
//Èç¹û¸ßµçƽʱ¼äÔÚ1680us×óÓÒ£¬¼ÆÊý 1680 / 1.085 = 1548´Î
{
temp |= 0x80; //(1550-250 = 1300 £¬ 1500+250 = 1800)£¬Îª1
}
ircode[i] = temp;
}
if(ircode[2] = ~ircode[3]) //ÑéÖ¤Êý¾ÝÊÇ·ñÏàµÈ
{
//Èç¹û½âÂëÕýÈ·¾Í½øÈë¶Ô¶æ»úµÄ²Ù×÷
if(ircode[2] == 0x44) //×óת
{
se_PWM -= 5;
if(se_PWM <= 10)
se_PWM = 10;
}
else if(ircode[2] == 0x43)//ÓÒת
{
se_PWM+=5;
if(se_PWM >=15)
se_PWM = 15;
}
ecode_ok = 1; //½âÂëÕýÈ·£¬·µ»Ø1
}
}
}
void inf()//ºìÍâ½ÓÊÕ
{
if(inf_flag & IR == 0)
{
inf_flag = 0; //¹Ø±ÕºìÍâ¼ì²â
TH0 = 0;
TL0 = 0; //¶¨Ê±Æ÷0ÇåÁã
TR0 = 1; //´ò¿ª¶¨Ê±Æ÷0
while(IR == 0)
{
;
} //Èç¹ûÊǵ͵çƽ¾ÍµÈ´ý£¬¸øÒýµ¼ÂëµÍµçƽ¼Æʱ
TR0 = 0;//¹Ø±Õ¶¨Ê±Æ÷0
LowTime = TH0*256 + TL0; //±£´æµÍµçƽʱ¼ä
TH0 = 0;
TL0 = 0; //¶¨Ê±Æ÷0ÇåÁã
TR0 = 1; //´ò¿ª¶¨Ê±Æ÷0
while(IR == 1)
{
;
} //Èç¹ûÊǸߵçƽ¾ÍµÈ´ý
TR0 = 0;
HighTime = TH0*256 + TL0; //±£´æ¸ßµçƽʱ¼ä
if((LowTime > 7800) && (LowTime < 8800) && (HighTime > 3600) && (HighTime > 4700))
//Èç¹ûÊÇÒýµ¼Â룬¾Í¿ªÊ¼½âÂ룬·ñÔò·ÅÆú£¬Òýµ¼ÂëµÄµÍµçƽ¼Æʱ
//µÍµçƽ´ÎÊý = 9000us /(12/11.0592) = 8294 ,ÅжÏÇø¼ä£º8300-500 = 7800£¬ 8300+500 = 8800
{
DeCode();
if(ecode_ok == 1) //Ö´ÐÐÒ£¿Ø½âÂ빦ÄÜ
{
beep();//·äÃùÆ÷ÏìÒ»Éù£¬Ìáʾ½âÂë³É¹¦
}
}
inf_flag = 1; //¿ªÆôºìÍâ¼ì²â
}
}
void main()
{
EA = 1; //´ò¿ª×ÜÖжÏ
EX0 = 1; //´ò¿ªÍⲿÖжÏ0
//ET0 = 1; //¶¨Ê±Æ÷0ÖжÏÔÊÐí
IT0 = 1; //ÍⲿÖжÏ0ϽµÑØ´¥·¢
TMOD = 0x11;//ʹÓö¨Ê±Æ÷0·½Ê½1
TR0 = 0; //¶¨Ê±Æ÷0¹Ø±Õ
PWM_OUT = 0; //³õʼ»¯¶æ»ú
ET1 = 1; //¶¨Ê±Æ÷1ÖжÏÔÊÐí
TH1 = 0xFF;
TL1 = 0xA4;
TR1 = 1; //Æô¶¯¶¨Ê±Æ÷1
while(1) //µÈ´ýºìÍâÐźŲúÉúµÄÖжÏ
{
inf();
}
}
//¶¨Ê±Æ÷1ÖжϷþÎñº¯Êý
//Ö÷Òª¸ºÔð²úÉú¶æ»úËùÐèµÄPWM²¨
void timer1()interrupt 3 using 0
{
TH1 = 0xFF;
TL1 = 0xA4; //¶¨Ê±Æ÷1ÖØÐÂ×°ÈëÊýÖµ0.1ms
if(++key_stime_counter >= 200) //20msʱ¼äµ½
{
key_stime_counter = 0;
}
if(key_stime_counter <=se_PWM)//Éú³ÉPWM²¨£¬¿ØÖƶæ»úתÏò
{
PWM_OUT = 1;
}
else
{
PWM_OUT = 0;
}
}
看1楼,我编辑了一下。以后嵌入代码的时候,点击下面所示的按钮,贴进去提交即可。