智能车制作

标题: 中断和AD有冲突? [打印本页]

作者: k410533234    时间: 2011-3-22 10:33
标题: 中断和AD有冲突?
最近将38k红外用在飞思卡尔上,红外中用到PIT0作脉冲时间的监测,单独使用时是ok的,可以控制小车前进后退,加AD采样后出现出现程序跑飞现象,将中断关掉后单独,AD可以使用。难道说二者有冲突还是程序有问题,特将全部程序贴出,300贡献求解:

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include <MC9S12Xs128.h>
#define  Ir_Pin      PTH_PTH0
#define  LED1        PTT_PTT0      //数据口
#define  LED2        PTT_PTT2     
#define  LED3        PTT_PTT4
#define  LED4        PTT_PTT6
#define  speed        25
int AD_value[8]={255,255,255,255,255,255,255,255};   //探头探测的信号值
int count,i,j;
unsigned char Led_Buf[4]; //显示缓冲区
unsigned char Ir_Buf[4]; //用于保存解码结果
void advance(void);
void back(void);
void turn_left(int angle);
void turn_right(int angle);
void stop(void);
void PLL_init(void);
void PWM_init(void);
void ad_init(void);
void delayms(int ms);
void caiji(void);
void  Ir_Get_Low(void);
void  Ir_Get_High(void);
void control(void);
void IO(void);
void main(void)
{
   PLL_init();
   PWM_init();
   IO();
  

   ad_init();                        //  将此句注释或将下面一句注释掉,程序都可以运行
   EnableInterrupts;            //将此句注释或将上面一句注释掉,程序都可以运行
                                         //当然注释掉,想要功能就不能实现了
while(1)
     {
         //下面这一段是用于红外接收,led是调试用的标志
         restart:
         while(Ir_Pin);
         LED1=0;
         Ir_Get_Low();  
         if(count<425 || count>475) continue;//引导脉冲低电平9000us
         Ir_Get_High();
         if(count<200 || count>250) continue;//引导脉冲高电平4500  
          LED2=0;
          for(i=0;i<4;i++) //4个字节
          for(j=0;j<8;j++) //每个字节8位
           {    LED3=0;
            
            Ir_Get_Low();
            if(count<10 || count>40) goto restart;
            Ir_Get_High();
            if(count<10 || count>100) goto restart;
            Ir_Buf[i]>>=1;
            if(count>56)
             {
              Ir_Buf[i]|=0x80;
              LED4=0;
             }
           }
     
     control();
     }
}

void PLL_init(void)    //时钟初始化
{
         //40M bus_clock
    CLKSEL=0X00;   
    PLLCTL_PLLON=1;   
    SYNR =0xc0 | 0x04;                       
    REFDV=0x80 | 0x01;
    POSTDIV=0x00;      
    _asm(nop);         
    _asm(nop);
    while(!(CRGFLG_LOCK==1));   
    CLKSEL_PLLSEL =1;         
}
  void PWM_init(void)   //脉宽调制初始化
{
PWME=0x00;              
    PWMCTL_PSWAI=1;   
    PWMCTL_PFRZ=1;   
    PWMPOL=0X00;     
   
    PWMCLK=0Xf0;//  67使用clock SB,45使用clock SA  
    PWMPRCLK=0X33;  //clock A=clock B=5M
    PWMSCLA=5;     //SA=SB=1M
    PWMSCLB=5;  
   
    PWMPER4=25;     
    PWMPER5=25;
    PWMDTY5=0;
    PWMDTY4=0;
    PWMPER6=25;
    PWMPER7=25;
    PWMDTY7=0;
    PWMDTY6=0;     
    PWME=0Xf0;        
}
void ad_init(void)    //AD初始化
  {
   ATD0CTL1=0X00;
   ATD0CTL2=0X42;
   ATD0CTL3=0Xc3;  //0Xe4为12  0xc3为8    6_3转换序列长度1100 12通道
   ATD0CTL4=0xF3;
   ATD0CTL5=0x30;
   ATD0DIEN=0x00;
   }
   
  void caiji(void) //将采集的信号赋值给数组AD_value[]
   {
   AD_value[0]=ATD0DR0;
   AD_value[1]=ATD0DR1;
   AD_value[2]=ATD0DR2;
   AD_value[3]=ATD0DR3;
   AD_value[4]=ATD0DR4;
   AD_value[5]=ATD0DR5;
   AD_value[6]=ATD0DR6;
   AD_value[7]=ATD0DR7;
  }
  
   void  Ir_Get_Low()
      {
     count=0;
     PITCFLMT_PITE=0; //关闭PIT   
     PITCE_PCE0=1;//使能通道0   
      //微定时器的装载寄存器
      PITMTLD0= 40-1;//8位定时器初值设定。40分频,在40MHzBusClock下,为0.01MHz,即1us     
      //定时器的装载寄存器,
      PITLD0  = 20 - 1 ;//16位定时器初值设定//定时20000*0.001ms = 20ms
      
      PITMUX_PMUX0=0;//0:相应16位定时器与微时基0连接           
      PITINTE_PINTE0=1;//PIT相应通道溢出中断使能   
      PITCFLMT_PITE=1; //使能PIT                                 ..
     while(Ir_Pin==0);   
      PITCFLMT_PITE=0; //关闭PIT  
      }
      //==============================================================
   
      
      void  Ir_Get_High(void)
      {
     count=0;
     PITCFLMT_PITE=0; //关闭PIT   
     PITCE_PCE0=1;//使能通道0   
      //微定时器的装载寄存器
      PITMTLD0= 40-1;//8位定时器初值设定。40分频,在40MHzBusClock下,为0.01MHz,即1us     
      //定时器的装载寄存器,
      PITLD0  = 20 - 1 ;//16位定时器初值设定//定时20*0.001ms = 20us   
      PITMUX_PMUX0=0;//0:相应16位定时器与微时基0连接           
      PITINTE_PINTE0=1;//PIT相应通道溢出中断使能   
      PITCFLMT_PITE=1; //使能PIT                                 ..
     while(Ir_Pin==1);   //知道     
      PITCFLMT_PITE=0; //关闭PIT   
      }

void control(void)
{
      if(Ir_Buf[2]==5)
         {
          advance();
          }
       if(Ir_Buf[2]==27)
         {  
           back();                                                                                            
          }
       if(Ir_Buf[2]==8)
         {  
           stop();                                                                                          
          }
         
       if(Ir_Buf[2]==7)
         {  
            turn_left(90);                                                                                         
          }
       if(Ir_Buf[2]==9)
         {  
          turn_right(90);                                                                                         
          }
}

void advance(void)            //前进
{
     PWMDTY4=0;
      PWMDTY5=speed;
        PWMDTY6=0;
          PWMDTY7=speed;
}
void back(void)              //后退
{
     PWMDTY4=speed;
      PWMDTY5=0;
        PWMDTY6=speed;
          PWMDTY7=0;
}
void turn_left(int angle)           //左转
{
     PWMDTY4=25;
      PWMDTY5=0;
        PWMDTY6=0;
          PWMDTY7=25;         
  delayms(angle*14);
  stop();        
}
void turn_right(int angle)            //右转
{
     PWMDTY4=0;
      PWMDTY5=25;
        PWMDTY6=25;
          PWMDTY7=0;   
  delayms(angle*14);
  stop();
}
void stop(void)              //stop
{
     PWMDTY4=0;
      PWMDTY5=0;
        PWMDTY6=0;
          PWMDTY7=0;
}


  void  IO(void)
{   
        
     DDRH_DDRH0=0;
     DDRT_DDRT0=1;   //定义LED口为输出
     DDRT_DDRT2=1;
     DDRT_DDRT4=1;
     DDRT_DDRT6=1;
     LED1=1;
     LED2=1;
     LED3=1;
     LED4=1;
}
void delayms(int ms)            //普通延时环节  调用1次大约1ms
{   
   int ii,jj;
   if (ms<1) ms=1;
   for(ii=0;ii<ms;ii++)
     for(jj=0;jj<3338;jj++);         
}
                        //定时器模块
#pragma CODE_SEG __NEAR_SEG NON_BANKED //指示该程序在不分页区
void interrupt 66 PIT0(void)
{
count++;
PITTF_PTF0=1;//清中断标志位
}
作者: zcs131458    时间: 2011-3-22 10:33
有很大的冲突 主要是时间的问题
作者: k410533234    时间: 2011-3-30 20:01
错。我已经找到答案了
作者: qinlu123    时间: 2012-2-15 20:11
k410533234 发表于 2011-3-30 20:01
错。我已经找到答案了

什么原因,我今天也遇到同样问题了
作者: k410533234    时间: 2012-7-16 21:42
qinlu123 发表于 2012-2-15 20:11
什么原因,我今天也遇到同样问题了

时间太久不记得了,貌似是AD中断后面没有中断函数,即使AD中断使用的是查询方式,但是因为AD中断开了,所以后面一定要有一个中断函数,函数里面是空的都行……




欢迎光临 智能车制作 (http://111.231.132.190/) Powered by Discuz! X3.2