智能车制作

标题: 关于PIT模块同时使用两个中断实现两灯互闪的问题 [打印本页]

作者: E08610318    时间: 2010-10-5 23:39
标题: 关于PIT模块同时使用两个中断实现两灯互闪的问题
我是个初学者,最近在实验的过程中想到同时使用PIT模块的0,1定时通道,实现两盏LED灯实现2比1频率的闪动。
程序代码如下:




#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#define unsigned int uint
#define BUS_CLOCK 24000000
uint i=0;
uint j=0;
byte shuma[20]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,       //0~9对应的段码
                0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
void INIT_PLL(void)
{
    CLKSEL &= 0x7f;       //set OSCCLK as sysclk
    PLLCTL &= 0x8F;       //Disable PLL circuit
    CRGINT &= 0xDF;
   
    #if(BUS_CLOCK == 40000000)
      SYNR = 0x44;
    #elif(BUS_CLOCK == 32000000)
      SYNR = 0x43;     
    #elif(BUS_CLOCK == 24000000)
      SYNR = 0x42;
    #endif
    REFDV = 0x81;         //PLLCLK=2×OSCCLK×(SYNR+1)/(REFDV+1)=64MHz ,fbus=32M
    PLLCTL =PLLCTL|0x70;  //Enable PLL circuit
    asm NOP;
    asm NOP;
    while(!(CRGFLG&0x08)); //PLLCLK is Locked already
    CLKSEL |= 0x80;        //set PLLCLK as sysclk
}
void PitInit(void){
  PITCFLMT_PITE = 1; //使能PIT模块
  PITCE = 0X00;      //通道0,1 PIT模块禁止
  PITINTE = 0x03;    //通道0,1中断使能
  PITMUX = 0x00;      //16位定时通道0使用0号8位微计数器,16位定时器1使用1号微计数器
  PITLD0 = 240-1;
  PITMTLD0 = 100-1;
  PITLD1 = 120-1;
  PITCE = 0X03;      //通道0,1 PIT模块使能
}
void InitPortb(void){
  DDRB = 0XFF;
  PORTB = 0XFF;
}
void main(void) {
  INIT_PLL();    //设置锁相环
  PitInit();     
  InitPortb();
EnableInterrupts;

  for(;;) {
   
  } /* loop forever */
  /* please make sure that you never leave main */
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 66 void PIT0(void){
    PITTF_PTF0 = 1;
    i++;
    if(i==1000){
    i = 0;  
    PORTB_PB0 = ~PORTB_PB0;
    }
}
interrupt 67 void PIT1(void){
    PITTF_PTF1 = 1;
    j++;
    if(j==1000){
    j = 0;
    PORTB_PB1 = ~PORTB_PB1;
    }
}


但是我实际运行发现,两盏灯居然同频率闪,我之前已经设置了PITLD0,PITLD1一个是240-1,一个是120-1,两个通道同时使用0微计数器,数值为100-1,中断向量也对了,感觉也没什么问题,大惑不解。我感觉两个中断都进入了,那么我就试着改了一下PITLD,把他们都改成同一个数值240-1,结果一运行,晕死我了,这回只有一盏灯在闪(亮一秒灭一秒),PIT通道2中断感觉是进不去了,非常疑惑。
请高手赐教到底什么原因。
作者: 44822886    时间: 2010-10-10 13:45
两个中断同时发生,cpu响应优先级高的那个,优先级低的中断忽略了
作者: E08610318    时间: 2010-10-11 07:20
但是我在设定的时候,两个中断没有同时发生吧,一个是1ms发生一次,一个是0.5ms发生一次,而我觉得中断程序运行也就是微秒级的时间,不会有冲突,再说了一个中断发生时总中断应该是自动关闭的,需要手动打开的,不会有优先级的问题吧。希望有大师们复制下程序到自己的单片机试试看
作者: xiaolezizhl    时间: 2010-10-15 20:30
你将中断服务程序中的PITTF_PTF0 = 1;改为PITCE_PCE0=0ITCE_PCE0=1;这两句,还有1通道的也改下应该就好了,试试看行不行
作者: E08610318    时间: 2010-10-19 17:59
成功了!谢谢这位同学了,但是你能告诉我这个什么道理吗?
作者: xiaolezizhl    时间: 2010-10-21 10:11
我调试时看了下   用这PITTF_PTF0 = 1好像清除不了标志位,翻了下数据手册看到If flag clearing by writing a one and flag setting happen in the same bus clock cycle, the flag remains set. The flag bits are cleared if the PIT module is disabled or if the corresponding timer channel is disabled.我想应该是这个问题吧   我也是新手,看到你发的这个程序我才去学习了下这个模块  呵呵
作者: E08610318    时间: 2010-10-23 14:48
恍然大悟,哎,还是你比较认真,DATASHEET这部分我之前也看了,没在意,当时没有做实验,原来是这么回事,还是多做实验好啊,记得牢。
作者: zhangjiarui    时间: 2010-11-29 09:45
学习
作者: zhangjiarui    时间: 2010-11-29 15:24
很实用
作者: 赵超超    时间: 2011-3-7 10:28
其实我也能回答出来
作者: xxr223    时间: 2011-3-16 22:04
围观
作者: 中国风    时间: 2011-5-15 10:24
我这个改了怎么还是不行啊?高手帮我看看,谢谢
void PIT_init(void)
{
    DisableInterrupts;
    PITCFLMT_PITE=0; //PIT关   
    PITCE=0x00;//定时器通道不使能
    PITMUX = 0x02;//16位定时通道0使用0号8位微计数器,16位定时器1使用1号微计数器    PITMTLD0=240-1;//8位定时器初值设定,160分频,在24MHzBusClock下,为0.1MHz。即0.01ms
    PITMTLD0=120-1;//8位定时器初值设定,160分频,在24MHzBusClock下,为0.1MHz。即0.01ms
    PITMTLD1=120-1;
    PITLD0=PITTIME-1;//16位定时器初值设定。PITTIME*0.01MS
    PITLD1=PITTIME-1;//16位定时器初值设定。PITTIME*0.01MS
    PITCE=0x03;//定时器通道0.1使能   
    PITINTE=0x03;//定时器中断通道0.1中断使能
    PITCFLMT_PITE=1;//PIT使能
    EnableInterrupts;
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED //指示该程序在不分页区
void interrupt 66 PIT0(void)
{
    count0++;
      if(count0==10)
       {
         count0=0;
         PORTE_PE5=~PORTE_PE5;
    }
  PITCE_PCE0=1;//清中断标志位
}

void interrupt 67 PIT1(void)
{
     count1++;
      if(count1==10)
       {
         count1=0;
         PORTE_PE6=~PORTE_PE6;
    }
  PITCE_PCE1=1;//清中断标志位
}
作者: 中国风    时间: 2011-5-15 10:24
我这个改了怎么还是不行啊?高手帮我看看,谢谢
void PIT_init(void)
{
    DisableInterrupts;
    PITCFLMT_PITE=0; //PIT关   
    PITCE=0x00;//定时器通道不使能
    PITMUX = 0x02;//16位定时通道0使用0号8位微计数器,16位定时器1使用1号微计数器    PITMTLD0=240-1;//8位定时器初值设定,160分频,在24MHzBusClock下,为0.1MHz。即0.01ms
    PITMTLD0=120-1;//8位定时器初值设定,160分频,在24MHzBusClock下,为0.1MHz。即0.01ms
    PITMTLD1=120-1;
    PITLD0=PITTIME-1;//16位定时器初值设定。PITTIME*0.01MS
    PITLD1=PITTIME-1;//16位定时器初值设定。PITTIME*0.01MS
    PITCE=0x03;//定时器通道0.1使能   
    PITINTE=0x03;//定时器中断通道0.1中断使能
    PITCFLMT_PITE=1;//PIT使能
    EnableInterrupts;
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED //指示该程序在不分页区
void interrupt 66 PIT0(void)
{
    count0++;
      if(count0==10)
       {
         count0=0;
         PORTE_PE5=~PORTE_PE5;
    }
  PITCE_PCE0=1;//清中断标志位
}

void interrupt 67 PIT1(void)
{
     count1++;
      if(count1==10)
       {
         count1=0;
         PORTE_PE6=~PORTE_PE6;
    }
  PITCE_PCE1=1;//清中断标志位
}
作者: 中国风    时间: 2011-5-15 10:25
我这个改了怎么还是不行啊?高手帮我看看,谢谢
void PIT_init(void)
{
    DisableInterrupts;
    PITCFLMT_PITE=0; //PIT关   
    PITCE=0x00;//定时器通道不使能
    PITMUX = 0x02;//16位定时通道0使用0号8位微计数器,16位定时器1使用1号微计数器    PITMTLD0=240-1;//8位定时器初值设定,160分频,在24MHzBusClock下,为0.1MHz。即0.01ms
    PITMTLD0=120-1;//8位定时器初值设定,160分频,在24MHzBusClock下,为0.1MHz。即0.01ms
    PITMTLD1=120-1;
    PITLD0=PITTIME-1;//16位定时器初值设定。PITTIME*0.01MS
    PITLD1=PITTIME-1;//16位定时器初值设定。PITTIME*0.01MS
    PITCE=0x03;//定时器通道0.1使能   
    PITINTE=0x03;//定时器中断通道0.1中断使能
    PITCFLMT_PITE=1;//PIT使能
    EnableInterrupts;
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED //指示该程序在不分页区
void interrupt 66 PIT0(void)
{
    count0++;
      if(count0==10)
       {
         count0=0;
         PORTE_PE5=~PORTE_PE5;
    }
  PITCE_PCE0=1;//清中断标志位
}

void interrupt 67 PIT1(void)
{
     count1++;
      if(count1==10)
       {
         count1=0;
         PORTE_PE6=~PORTE_PE6;
    }
  PITCE_PCE1=1;//清中断标志位
}
作者: 中国风    时间: 2011-5-15 10:33
这样好像也不行也,
作者: 中国风    时间: 2011-5-15 10:33
这样好像也不行也,
作者: 中国风    时间: 2011-5-15 10:33
这样好像也不行也,
作者: wys839348916    时间: 2011-6-1 22:53
学习。。。不错,很强大
作者: hello1043    时间: 2011-6-9 00:51
很好
作者: 中国风    时间: 2011-7-16 10:07
到底是怎么回事啊?看不懂也?
作者: 中国风    时间: 2011-7-16 10:07
到底是怎么回事啊?看不懂也?
作者: 中国风    时间: 2011-7-16 10:07
到底是怎么回事啊?看不懂也?
作者: 中国风    时间: 2011-7-16 10:07
到底是怎么回事啊?看不懂也?
作者: 中国风    时间: 2011-7-16 10:07
到底是怎么回事啊?看不懂也?
作者: tianma    时间: 2012-7-6 17:06
啊。学习了。我也遇到两个定时器中断只能进定时器0而进不了定时器中断1的情况了。
作者: nst11305    时间: 2012-8-3 00:05
E08610318 发表于 2010-10-23 14:48
恍然大悟,哎,还是你比较认真,DATASHEET这部分我之前也看了,没在意,当时没有做实验,原来是这么回事,还 ...

额,其实还有更深层次的原因,给你个链接吧
http://www.znczz.com/thread-56088-1-1.html

刚刚那位大神的解决方法也挺好的,因为关闭了PIT之后,标志位就自动清零了
不是因为写1 和置位同时发生的问题

加油

作者: zsk-    时间: 2012-8-6 23:19
赵超超 发表于 2011-3-7 10:28
其实我也能回答出来

2b  
作者: zsk-    时间: 2012-8-7 01:39
xiaolezizhl 发表于 2010-10-21 10:11
我调试时看了下   用这PITTF_PTF0 = 1好像清除不了标志位,翻了下数据手册看到If flag clearing by writing ...

那么请问若是楼主的程序么有清楚标志位,为什么仅用一个中断的时候应该也没有清标志位,为什么程序能正常运行?
比如  switch(PORTE&0x14)
  
  {
    case 0x14:{
                    Object_speed=22;
                    break;
              }
    case 0x04:{
                    Object_speed=26;
                    break;
              }
    case 0x10:{
                    Object_speed=30;
                    break;
              }
    case 0x00:{
                    Object_speed=35;
                    break;
              }
    default:break;
  }
  delay2s();//延时2秒发车
EnableInterrupts;
  
  for(;;) {
    _FEED_COP(); /* feeds the dog */  
   saomiao();
   chuli();
   Tiaosu();
   driver();
  } /* loop forever */
  /* please make sure that you never leave main */  
}
/***********************测速***********************/
//#pragma CODE_SEG NON_BANKED
void interrupt 66 PIT0(void)
{
      PITTF_PTF0=1;
      pulse_speed=PACNT;
      PACNT=0x0000;
         
}
#pragma CODE_SEG DEFAULT
这是我的小车程序的一部分,我感觉程序是正常运行的,应该肯定出中断了

作者: 孟鹏涛    时间: 2012-10-13 19:35
Wonderful!
作者: 孟鹏涛    时间: 2012-10-13 21:28
学习
作者: main    时间: 2012-10-21 14:39
interrupt 66 void PIT0
请问楼主,这个 66怎么来的?我看了中断向量,可我不知道这个66与中断向量什么关系,初学者求指教,
作者: sdlibin007@qq.c    时间: 2012-10-22 17:50
:)
作者: 小诸    时间: 2013-2-27 21:13
学习了,真的有用!还是要认真学啊!
作者: Mr.不弃    时间: 2015-5-6 20:52
;p
学习了




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