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

[复制链接]
1825|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




#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 | 显示全部楼层
  1. #include "header.h"
  2. #include "1602.h"

  3. unsigned char signal ;
  4. unsigned char duty;
  5. unsigned char TempData[2];
  6. unsigned char IRcord[4];
  7. char code Tab[16]="0123456789ABCDEF";


  8. bit irpro_ok;

  9. void Delay(unsigned int ms)
  10. {
  11.         unsigned char i;
  12.         while(ms--)
  13.         {
  14.                 for ( i=0;i<250;i++)
  15.                 {
  16.                         _nop_();
  17.                         _nop_();
  18.                         _nop_();
  19.                         _nop_();
  20.                 }
  21.         }
  22. }


  23. void main()
  24. {
  25.         EA=1;
  26.         P1M0=0x28; //设置控制继电器IO口为强推挽输出
  27.         P1M1=0x00;
  28.         duty=0;
  29.         Turn1=0;
  30.         Turn2=0;
  31.         Ug1=0;
  32.         signal = 0;
  33.        
  34.         LCD_init();
  35.         PWM_init();
  36.         ADC_init();
  37.         timer_init();
  38.         Int0();
  39.        
  40.         while (1)
  41.         {
  42.                 if (irpro_ok)
  43.                 {
  44.                         TempData[0]=Tab[signal/16];
  45.                         TempData[1]=Tab[signal%16];
  46.                         lcd_showchar(0x46,TempData);
  47.                        
  48.                         switch(signal)
  49.                         {
  50.                                 case 0x44 :
  51.                                 {
  52.                                         if(Turn1==Turn2&&Turn1==0)
  53.                                         {
  54.                                                 duty=120;
  55.                                                 CR=0;
  56.                                                 Delay(600);
  57.                                                 Turn1=1;
  58.                                                 Turn2=1;
  59.                                                 CR=1;
  60.                                         }
  61.                                         else
  62.                                         {
  63.                                                 duty=120;
  64.                                                 Turn1=1;
  65.                                                 Turn2=1;
  66.                                         }
  67.                                 }        break;
  68.                                 case 0x40 :
  69.                                 {
  70.                                         if(Turn1==Turn2&&Turn1==1)
  71.                                         {
  72.                                                 duty=120;
  73.                                                 CR=0;
  74.                                                 Delay(600);
  75.                                                 Turn1=0;
  76.                                                 Turn2=0;
  77.                                                 CR=1;
  78.                                         }
  79.                                 else
  80.                                         {
  81.                                                 duty=120;
  82.                                                 Turn1=0;
  83.                                                 Turn2=0;
  84.                                         }
  85.                                 }        break;
  86.                                 case 0x43:                   
  87.                                 {                                                                                        //停止
  88.                                         duty = 255;
  89.                                         Turn1=0;
  90.                                         Turn2=0;
  91.                                         CR = 0;                                           //关闭PCA模块,停止输出PWM调速信号
  92.                                 }        break;
  93.                
  94.                                 case 0x15:
  95.                                 {                                            //加速
  96.                                         if (duty>14)
  97.                                                 duty=duty-15;
  98.                                         else
  99.                                                 duty = 120;
  100.                                 }        break;
  101.                                 case 0x07:
  102.                                 {                                                                                //减速
  103.                                         if (duty<255)
  104.                                                 duty=duty+15;
  105.                                         else
  106.                                                 duty = 120 ;       
  107.                                 } break;
  108.                                
  109.                                 default :   _nop_();break;
  110.                         }
  111.        
  112.                 CCAP1H=CCAP1L=duty;
  113.                 lcd_showdata(0x05,duty);
  114.                 Delay(15);
  115.                 timer_init();
  116.                 EX0=1;
  117.                 }               
  118.         }
  119. }



  120. void INT0_Rountine() interrupt 0 using 0    //红外信号接收解码
  121. {
  122.         char j,k;
  123.         static unsigned char temp;
  124.         static unsigned int timer0;
  125.        
  126.         //duty = 255;    //停止电机
  127.         CR = 0;                 //停止PWM信号输出
  128.         EX0 = 0;         //关闭中断0
  129.         Delay(15);
  130.        
  131.         if (INT0==1)
  132.         {
  133.                 EX0=1;
  134.                 return ;    //防止重复按键
  135.         }
  136.         signal= 0;
  137.         irpro_ok=0;       
  138.        
  139.         TMOD=0x09;
  140.         TH0=0;
  141.         TL0=0;
  142.         ET0=0;     //关闭定时器中断
  143.         ET1=0;
  144.         TR0=1;                 //启动脉宽测量T0

  145.         while(!INT0)   //跳过红外输出的引导信号9ms低电平
  146.         ;
  147.         while(INT0)    //跳过引导信号4.5ms高电平
  148.   ;
  149.         timer0 = TH0*256+TL0;
  150.         if (4000<timer0&&timer0<5000)
  151.         {
  152.                 timer0 = 0;
  153.                 TH0 = 0;
  154.                 TL0 = 0;
  155.                
  156.                 for(j=0;j<4;j++)
  157.                 {
  158.                         for(k=0;k<8;k++)
  159.                         {
  160.                                 temp>>=1;    //读取红外数据存在高位,每次读取后将数据右移一位
  161.                                 while(!INT0);    //跳过信号低电平段
  162.                                 while(INT0);     //跳过信号高电平段
  163.                                 timer0 = TH0*256 +TL0;  //计算高电平段信号时间
  164.                                 if(450<timer0&&timer0<650)       //根据高电平时间判断信号内容        0.56ms为信号0,1.685ms为信号1
  165.                                         temp=temp&0x7f;       //读取该位为0,存在最高位
  166.                                 else
  167.                                         temp=temp|0x80;      
  168.                                 timer0 = 0;
  169.                                 TH0 = 0;
  170.                                 TL0 = 0;
  171.                         }
  172.                         IRcord[j]=temp;
  173.                         timer0=0;
  174.                         temp=0;
  175.                 }
  176.                
  177.           if(IRcord[2]==~IRcord[3])
  178.                 {
  179.                         signal=IRcord[2];
  180.                         irpro_ok=1;
  181.                         return  ;
  182.                 }
  183.                 else
  184.                 {
  185.                         EX0 = 1;     //从新打开外部中断0,从新接收红外信号
  186.                         irpro_ok=0;
  187.                         return ;
  188.                 }
  189.                
  190.         }
  191.         else
  192.                 {
  193.                         EX0 = 1;     //从新打开外部中断0,从新接收红外信号
  194.                         irpro_ok=0;
  195.                         return ;
  196.                 }

  197. }
  198.        
  199.        
  200.        
不但标题没打完,程序也没粘完。上面帮你粘完了,哪个变量不对?
 楼主| zlcn 发表于 2016-12-28 20:46 | 显示全部楼层
NE5532 发表于 2016-12-28 16:35
不但标题没打完,程序也没粘完。上面帮你粘完了,哪个变量不对?

不好意思,第一次发帖,没弄好就直接发了;我定义了两个全局变量:signal,duty,分别代表红外信号码值,电机pwm调速占空比;我调试的时候发现,主程序一直读取不到这两个全局变量的变化,所以电机正反转,调速,液晶显示变量这些要实现的东西都执行不了,但是把控制这些内容的程序放到中断程序就可以实现除pwm调速外的功能;所以我猜测是全局变量共享的出了问题,希望你能给一些意见,谢谢啦
NE5532 发表于 2016-12-28 22:11 | 显示全部楼层
你先在仿真器里看看这两个变量的值是多少,你定义全局变量的方法倒是没有错,就是要看算法上是否有问题了。
 楼主| zlcn 发表于 2016-12-28 22:17 | 显示全部楼层
是用什么仿真器?之前都没有用过
 楼主| zlcn 发表于 2016-12-28 22:18 | 显示全部楼层
NE5532 发表于 2016-12-28 22:11
你先在仿真器里看看这两个变量的值是多少,你定义全局变量的方法倒是没有错,就是要看算法上是否有问题了。 ...

是用什么仿真器,之前都没有用过,都是直接下载程序,没有太多经验
NE5532 发表于 2016-12-28 22:36 | 显示全部楼层
STC是号称的内部软仿真,我也没有用过。没有仿真器也没关系,你先整个串口之类,可以把这两个数的值送出来看,或者周期性改变他们的值,就在中断里改,然后去影响PWM的波形,看他们的值是不是真的没有变。
 楼主| zlcn 发表于 2016-12-29 10:17 | 显示全部楼层
NE5532 发表于 2016-12-28 22:36
STC是号称的内部软仿真,我也没有用过。没有仿真器也没关系,你先整个串口之类,可以把这两个数的值送出来 ...

好的,先去试一波
 楼主| zlcn 发表于 2017-1-4 14:11 | 显示全部楼层
又多弄了好几天,发现一个公共的问题,用外部中断红外解码会出现中断程序回不到主程序这个问题,不知道大家有没有试过这样的情况?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

147

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部