智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 3079|回复: 4
打印 上一主题 下一主题

[单片机] 中断和AD有冲突?

[复制链接]

26

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1557

优秀会员奖章

威望
424
贡献
913
兑换币
60
注册时间
2008-10-21
在线时间
110 小时
跳转到指定楼层
1#
发表于 2011-3-22 10:33:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
300贡献
最近将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;//清中断标志位
}

最佳答案

查看完整内容

有很大的冲突 主要是时间的问题

7

主题

54

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
QQ
威望
280
贡献
1380
兑换币
0
注册时间
2011-3-2
在线时间
35 小时
2#
发表于 2011-3-22 10:33:50 | 只看该作者
有很大的冲突 主要是时间的问题
回复

使用道具 举报

26

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1557

优秀会员奖章

威望
424
贡献
913
兑换币
60
注册时间
2008-10-21
在线时间
110 小时
3#
 楼主| 发表于 2011-3-30 20:01:59 | 只看该作者
错。我已经找到答案了
回复

使用道具 举报

200

主题

2621

帖子

1

精华

杰出人士

蜗牛

Rank: 12Rank: 12Rank: 12

积分
12488

优秀会员奖章活跃会员奖章论坛骨干奖章论坛元老奖章在线王奖章资源大师奖章

QQ
威望
5973
贡献
3101
兑换币
1999
注册时间
2011-10-21
在线时间
1707 小时
4#
发表于 2012-2-15 20:11:18 | 只看该作者
k410533234 发表于 2011-3-30 20:01
错。我已经找到答案了

什么原因,我今天也遇到同样问题了
回复

使用道具 举报

26

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1557

优秀会员奖章

威望
424
贡献
913
兑换币
60
注册时间
2008-10-21
在线时间
110 小时
5#
 楼主| 发表于 2012-7-16 21:42:32 | 只看该作者
qinlu123 发表于 2012-2-15 20:11
什么原因,我今天也遇到同样问题了

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

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-9-22 15:36 , Processed in 0.053185 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表