打印

红外遥控电机设计,出了一点问题,主程序读取不了中断

[复制链接]
1332|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zlcn|  楼主 | 2016-12-28 16:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#ifndef  __header_H_
#define  __header_H_

#include <STC12C5A60S2.H>
#include <intrins.h>
#include <stdio.h>

//extern unsigned char signal;
//extern bit irpro_ok,irwork_ok;
//extern unsigned char duty;

sbit Turn1=P1^3;  //µç»úתÏòÐźÅÊä³ö
sbit Turn2=P1^5;
sbit Ug1=P1^4;     //PWMµ÷ËÙÐźÅÊä³ö
sbit Vout1 = P1^7;    //µç»úµçÁ÷Ä£ÄâÁ¿·´À¡ÊäÈë¶Ë
sbit INT0 = P3^2;           //ºìÍâÒ£¿ØÐźŽÓÊÕ¶Ë
sbit Dout = P3^5;    //µç»úËٶȷ´À¡Êý×ÖÁ¿ÊäÈë¶Ë



void Delay(unsigned int ms);
void PWM_init();
void ADC_init();
void timer_init();
void Int0();
//void infrared();
//void        ir_work(unsigned char q,unsigned char p);

#endif 测试 -1.rar (61.15 KB)




#include "header.h"
#include "1602.h"

unsigned char signal ;
unsigned char duty;
unsigned char TempData[2];
unsigned char IRcord[4];
char code Tab[16]="0123456789ABCDEF";


bit irpro_ok;

void Delay(unsigned int ms)
{
        unsigned char i;
        while(ms--)
        {
                for ( i=0;i<250;i++)
                {
                        _nop_();
                        _nop_();
                        _nop_();
                        _nop_();
                }
        }
}


void main()
{
        EA=1;
        P1M0=0x28; //ÉèÖÿØÖƼ̵çÆ÷IO¿ÚΪǿÍÆÍìÊä³ö
        P1M1=0x00;
        duty=0;
        Turn1=0;
        Turn2=0;
        Ug1=0;
        signal = 0;
       
        LCD_init();
        PWM_init();
        ADC_init();
        timer_init();
        Int0();
       
        while (1)
        {
                if (irpro_ok)
                {
                        TempData[0]=Tab[signal/16];
                        TempData[1]=Tab[signal%16];
                        lcd_showchar(0x46,TempData);
                       
                        switch(signal)
                        {
                                case 0x44 :
                                {
                                        if(Turn1==Turn2&&Turn1==0)
                                        {
                                                duty=120;
                                                CR=0;
                                                Delay(600);
                                                Turn1=1;
                                                Turn2=1;
                                                CR=1;
                                        }
                                        else
                                        {
                                                duty=120;
                                                Turn1=1;
                                                Turn2=1;
                                        }
                                }        break;
                                case 0x40 :
                                {
                                        if(Turn1==Turn2&&Turn1==1)
                                        {
                                                duty=120;
                                                CR=0;
                                                Delay(600);
                                                Turn1=0;
                                                Turn2=0;
                                                CR=1;
                                        }
                                else
                                        {
                                                duty=120;
                                                Turn1=0;
                                                Turn2=0;
                                        }
                                }        break;
                                case 0x43:                   
                                {                                                                                        //Í£Ö¹
                                        duty = 255;
                                        Turn1=0;
                                        Turn2=0;
                                        CR = 0;                                           //¹Ø±ÕPCAÄ£¿é£¬Í£Ö¹Êä³öPWMµ÷ËÙÐźÅ
                                }        break;
               
                                case 0x15:
                                {                                            //¼ÓËÙ
                                        if (duty>14)
                                                duty=duty-15;
                                        else
                                                duty = 120;
                                }        break;
                                case 0x07:
                                {                                                                                //¼õËÙ
                                        if (duty<255)
                                                duty=duty+15;
                                        else
                                                duty = 120 ;       
                                } break;
                               
                                default :   _nop_();break;
                        }
       
                CCAP1H=CCAP1L=duty;
                lcd_showdata(0x05,duty);
                Delay(15);
                timer_init();
                EX0=1;
                }               
        }
}

相关帖子

沙发
zlcn|  楼主 | 2016-12-28 16:27 | 只看该作者
标题没打全就发帖了,失误,中断程序里面处理的全局变量,在主程序中无法读取,希望大家多多帮助,还有的就是初始化和显示的程序没粘贴上来

使用特权

评论回复
板凳
NE5532| | 2016-12-28 16:35 | 只看该作者
#include "header.h"
#include "1602.h"

unsigned char signal ;
unsigned char duty;
unsigned char TempData[2];
unsigned char IRcord[4];
char code Tab[16]="0123456789ABCDEF";


bit irpro_ok;

void Delay(unsigned int ms)
{
        unsigned char i;
        while(ms--)
        {
                for ( i=0;i<250;i++)
                {
                        _nop_();
                        _nop_();
                        _nop_();
                        _nop_();
                }
        }
}


void main()
{
        EA=1;
        P1M0=0x28; //设置控制继电器IO口为强推挽输出
        P1M1=0x00;
        duty=0;
        Turn1=0;
        Turn2=0;
        Ug1=0;
        signal = 0;
       
        LCD_init();
        PWM_init();
        ADC_init();
        timer_init();
        Int0();
       
        while (1)
        {
                if (irpro_ok)
                {
                        TempData[0]=Tab[signal/16];
                        TempData[1]=Tab[signal%16];
                        lcd_showchar(0x46,TempData);
                       
                        switch(signal)
                        {
                                case 0x44 :
                                {
                                        if(Turn1==Turn2&&Turn1==0)
                                        {
                                                duty=120;
                                                CR=0;
                                                Delay(600);
                                                Turn1=1;
                                                Turn2=1;
                                                CR=1;
                                        }
                                        else
                                        {
                                                duty=120;
                                                Turn1=1;
                                                Turn2=1;
                                        }
                                }        break;
                                case 0x40 :
                                {
                                        if(Turn1==Turn2&&Turn1==1)
                                        {
                                                duty=120;
                                                CR=0;
                                                Delay(600);
                                                Turn1=0;
                                                Turn2=0;
                                                CR=1;
                                        }
                                else
                                        {
                                                duty=120;
                                                Turn1=0;
                                                Turn2=0;
                                        }
                                }        break;
                                case 0x43:                   
                                {                                                                                        //停止
                                        duty = 255;
                                        Turn1=0;
                                        Turn2=0;
                                        CR = 0;                                           //关闭PCA模块,停止输出PWM调速信号
                                }        break;
               
                                case 0x15:
                                {                                            //加速
                                        if (duty>14)
                                                duty=duty-15;
                                        else
                                                duty = 120;
                                }        break;
                                case 0x07:
                                {                                                                                //减速
                                        if (duty<255)
                                                duty=duty+15;
                                        else
                                                duty = 120 ;       
                                } break;
                               
                                default :   _nop_();break;
                        }
       
                CCAP1H=CCAP1L=duty;
                lcd_showdata(0x05,duty);
                Delay(15);
                timer_init();
                EX0=1;
                }               
        }
}



void INT0_Rountine() interrupt 0 using 0    //红外信号接收解码
{
        char j,k;
        static unsigned char temp;
        static unsigned int timer0;
       
        //duty = 255;    //停止电机
        CR = 0;                 //停止PWM信号输出
        EX0 = 0;         //关闭中断0
        Delay(15);
       
        if (INT0==1)
        {
                EX0=1;
                return ;    //防止重复按键
        }
        signal= 0;
        irpro_ok=0;       
       
        TMOD=0x09;
        TH0=0;
        TL0=0;
        ET0=0;     //关闭定时器中断
        ET1=0;
        TR0=1;                 //启动脉宽测量T0

        while(!INT0)   //跳过红外输出的引导信号9ms低电平
        ;
        while(INT0)    //跳过引导信号4.5ms高电平
  ;
        timer0 = TH0*256+TL0;
        if (4000<timer0&&timer0<5000)
        {
                timer0 = 0;
                TH0 = 0;
                TL0 = 0;
               
                for(j=0;j<4;j++)
                {
                        for(k=0;k<8;k++)
                        {
                                temp>>=1;    //读取红外数据存在高位,每次读取后将数据右移一位
                                while(!INT0);    //跳过信号低电平段
                                while(INT0);     //跳过信号高电平段
                                timer0 = TH0*256 +TL0;  //计算高电平段信号时间
                                if(450<timer0&&timer0<650)       //根据高电平时间判断信号内容        0.56ms为信号0,1.685ms为信号1
                                        temp=temp&0x7f;       //读取该位为0,存在最高位
                                else
                                        temp=temp|0x80;      
                                timer0 = 0;
                                TH0 = 0;
                                TL0 = 0;
                        }
                        IRcord[j]=temp;
                        timer0=0;
                        temp=0;
                }
               
          if(IRcord[2]==~IRcord[3])
                {
                        signal=IRcord[2];
                        irpro_ok=1;
                        return  ;
                }
                else
                {
                        EX0 = 1;     //从新打开外部中断0,从新接收红外信号
                        irpro_ok=0;
                        return ;
                }
               
        }
        else
                {
                        EX0 = 1;     //从新打开外部中断0,从新接收红外信号
                        irpro_ok=0;
                        return ;
                }

}
       
       
       
不但标题没打完,程序也没粘完。上面帮你粘完了,哪个变量不对?

使用特权

评论回复
地板
zlcn|  楼主 | 2016-12-28 20:46 | 只看该作者
NE5532 发表于 2016-12-28 16:35
不但标题没打完,程序也没粘完。上面帮你粘完了,哪个变量不对?

不好意思,第一次发帖,没弄好就直接发了;我定义了两个全局变量:signal,duty,分别代表红外信号码值,电机pwm调速占空比;我调试的时候发现,主程序一直读取不到这两个全局变量的变化,所以电机正反转,调速,液晶显示变量这些要实现的东西都执行不了,但是把控制这些内容的程序放到中断程序就可以实现除pwm调速外的功能;所以我猜测是全局变量共享的出了问题,希望你能给一些意见,谢谢啦

使用特权

评论回复
5
NE5532| | 2016-12-28 22:11 | 只看该作者
你先在仿真器里看看这两个变量的值是多少,你定义全局变量的方法倒是没有错,就是要看算法上是否有问题了。

使用特权

评论回复
6
zlcn|  楼主 | 2016-12-28 22:17 | 只看该作者
是用什么仿真器?之前都没有用过

使用特权

评论回复
7
zlcn|  楼主 | 2016-12-28 22:18 | 只看该作者
NE5532 发表于 2016-12-28 22:11
你先在仿真器里看看这两个变量的值是多少,你定义全局变量的方法倒是没有错,就是要看算法上是否有问题了。 ...

是用什么仿真器,之前都没有用过,都是直接下载程序,没有太多经验

使用特权

评论回复
8
NE5532| | 2016-12-28 22:36 | 只看该作者
STC是号称的内部软仿真,我也没有用过。没有仿真器也没关系,你先整个串口之类,可以把这两个数的值送出来看,或者周期性改变他们的值,就在中断里改,然后去影响PWM的波形,看他们的值是不是真的没有变。

使用特权

评论回复
9
zlcn|  楼主 | 2016-12-29 10:17 | 只看该作者
NE5532 发表于 2016-12-28 22:36
STC是号称的内部软仿真,我也没有用过。没有仿真器也没关系,你先整个串口之类,可以把这两个数的值送出来 ...

好的,先去试一波

使用特权

评论回复
10
zlcn|  楼主 | 2017-1-4 14:11 | 只看该作者
又多弄了好几天,发现一个公共的问题,用外部中断红外解码会出现中断程序回不到主程序这个问题,不知道大家有没有试过这样的情况?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

134

帖子

4

粉丝