智能车制作

标题: XS128 PIT 模块标志位清除问题!!!!! [打印本页]

作者: 1160927    时间: 2010-5-7 18:21
标题: XS128 PIT 模块标志位清除问题!!!!!
//下面的小程序是我测试 PIT 写的,目的是利用级联的24位计数器产生1ms的延时函数,然后调用该函数,使最小系统版上的LED亮一秒,灭一秒
#include <hidef.h>          /* common defines and macros */
#include "derivative.h"     /* derivative information */
static dword   PIT_Timing_00,PIT_Timing_00_Temp=0; //用于8位位计数器0和16位计数器0级联的计数器产生延时用的变量
static byte    Flag_Delay=0;    //定时完成标志

void InitialPLL(void)   //外部时钟为16MHz,PLLCLK=96MHz,BUSCLK=48MHz
{  CLKSEL=0X00;     //disengage PLL to system
   POSTDIV=0x00;    //后除数无效,则PLLCLK=fVCO
   SYNR=0xcb;       //PLLCLK =2*OSCCLK*(SYNR + 1)/(REFDV + 1)=120MHz
   REFDV=0x43;      //SYNR,REFDV最高两位的确定依据数据手册提供的资料
   PLLCTL=0xc0;     //打开时钟监视,并且打开PLL
   CLKSEL=0X80;     //选通PLL时钟提供给总线
   __asm {
     NOP;
     NOP;
     NOP;
    }
   while((CRGFLG&0X08)==0)
     {   }         //时钟校正同步,等待单片机内部时钟稳定
   CLKSEL=0X80;    //再次使能PLLCLK,确保不出错
}



void InitialPIT(void){ //定时计数器初始化,BUSCLK=48MHz
                                //8位微计数器0和16计数器0级联产生一个 1ms 的基准定时,用于其他程序
                     //其它几个计数器作用待定,暂时不用,所以是对位进行的操作
  PITTF=0xff;          //使用定时器前先将所有中断标志位清除,以免不必要错误,注意此寄存器需要写入"1"才能清除
  PITINTE=0x00;       //所有通道中断禁用
  PITCE=0x00;          //所有定时器通道关闭
  PITCFLMT_PITE=0;    //所有定时通道禁用
  
  PITMTLD0=0x2f;      //8位定时器0初值设定,48分频。溢出周期=(PITMTLD + 1) * (PITLD + 1) /BUSCLK。
  PITLD0=0x03e7;      //16位定时器初值设定,在8位微计数器基础上在1000分频,即是级联的24位计数器为BUSCLK的
                      //48*1000分频,所以计数周期为1ms,频率 1KHz
  
  PITMUX_PMUX0=0;     //选定16位计数器0所用的基准8位微计数器0
  
  //因为8位微计数器0和16位计数器0是其它程序调用,用于延时的,所以初始化时并不使能
  //PITINTE_PINTE0=1;   //定时器中断通道0中断使能
  //PITCE_PCE0=1;       //打开16位计数器0的
  //PITCFLMT_PITE=1;    //所有定时器通道使能
}

void   InitialPort(void){
  DDRB=0xff;       //B口作为输出,利用LED组合显示系统状态
  PORTB=0x00;         //复位时最小系统板上接B口的8位LED亮
   }

void   Delay(dword del_ms){
PIT_Timing_00 = del_ms;
  PITTF_PTF0=1;
  PITINTE_PINTE0=1;   //定时器中断通道0中断使能
PITCE_PCE0=1;       //打开16位计数器0的
PITCFLMT_PITE=1;    //所有定时器通道使能  
while(PIT_Timing_00 > PIT_Timing_00_Temp);
Flag_Delay=1;
PIT_Timing_00_Temp=0;
}

void main(void)
{   
  InitialPLL();
  InitialPIT();
  InitialPort();
  EnableInterrupts;
  for(;;) {Delay(1000);}
}

#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 66 PIT0(void) {
  PIT_Timing_00_Temp++;
  if(Flag_Delay){         //Flag_Delay为定时完成的标志位   
    Flag_Delay=0x00;      //达到想要的定时时间,清除标志位               
    PORTB=~PORTB;
    }
PITCE_PCE0=0;
  __asm {
    NOP;
    NOP;
    NOP;
    }  
  PITINTE_PINTE0=0;
  __asm {
    NOP;
    NOP;
    NOP;
    }
  PITTF_PTF0|=0x00;        __asm {
    NOP;
    NOP;
    NOP;
    }
  PITINTE_PINTE=1;
  __asm {
    NOP;
    NOP;
    NOP;
    }   
  PITCE_PCE0=1;}

我的测试结果是,只有这样LED才是亮1秒,熄1秒。问题来了,如果按照datashit所说的清除标志位需要在该计数器没启用或者PITE无效时,向该位写1,LED就一直亮着,只是1秒后亮度小了点(我的猜测是由于标志位没有清除,会一直执行中断函数,导致PB口输出的高低电平周期严重减小)……
在这执行“ PITCE_PCE0=0;”后标志位确实被清除了,但一运行到绿色那句时,PITTF_PTF0 标志位那上就变成 1 了!!!!!!实在是让我很无语有很无奈。。。。。

我在飞思卡尔板块也发了同样的求助帖,希望论坛里车友们解救小弟 ,谢谢!!!!! 由于我的贡献币不多,各位多多包涵~
作者: 1160927    时间: 2010-5-7 18:23
还是自己先顶吧,不然沉了。。。。路过的朋友们都来看看啦
作者: 1160927    时间: 2010-5-7 20:17
哎,没得人帮忙啊……悲剧了。。。。
作者: 1160927    时间: 2010-5-9 17:16
……还是得靠自己来呀,算是解决了一般问题了
作者: 1160927    时间: 2010-5-19 12:16
………………
作者: hcm    时间: 2010-10-29 20:39
你好,我是一个新手,这句话void interrupt 66 PIT0(void)不太懂。66、PIT0是怎么来的
作者: 835304205    时间: 2010-11-27 10:17
标志位寄存器清除要向里面写1不是写0,这是硬件决定的。
作者: 835304205    时间: 2010-11-27 10:17
标志位寄存器清除要向里面写1不是写0,这是硬件决定的。
作者: 835304205    时间: 2010-11-27 10:18
标志位寄存器清除要向里面写1不是写0,这是硬件决定的。
作者: 835304205    时间: 2010-11-27 10:18
标志位寄存器清除要向里面写1不是写0,这是硬件决定的。
作者: zhangjiarui    时间: 2010-11-29 10:46
我也是刚学 你可以参考下这个帖http://www.znczz.com/thread-16534-1-1.html
作者: 437334816    时间: 2010-11-29 11:32
学习
作者: 梧桐1209    时间: 2010-11-30 20:14
正在摸索。。。。。。。。。。。。
作者: chensi291    时间: 2011-1-21 11:37
回复 6# hcm


这是PIT0的中断服务程序,PIT0 是自己给中断服务程序取的名字,任意的合法命名都行,66是PIT通道0 的中断向量号,可以在 C:\Program Files\Freescale\CodeWarrior for HCS12 V4.7\lib\hc12c\include\mc9s12xs128.h 找到,其他的中断的向量号也都在里面。
作者: Jarylove    时间: 2011-4-20 22:02
不懂
作者: 诗雨依然    时间: 2011-4-23 16:59

作者: KAI990610    时间: 2011-10-19 20:49
贴出我的PIT中断处理程序!
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 66 void PIT0(void)
{
    // PITTF_PTF0 = 1;
    //用这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 thecorresponding timer channel is disabled.

   PITCE_PCE0=0;    //通道禁止
   PITCE_PCE0=1;
    i++;
    if(i==1000)
   {
    i = 0;  
    PORTB_PB0 = ~PORTB_PB0;
    }
   
}
作者: KAI990610    时间: 2011-10-19 20:49
贴出我的PIT中断处理程序!
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 66 void PIT0(void)
{
    // PITTF_PTF0 = 1;
    //用这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 thecorresponding timer channel is disabled.

   PITCE_PCE0=0;    //通道禁止
   PITCE_PCE0=1;
    i++;
    if(i==1000)
   {
    i = 0;  
    PORTB_PB0 = ~PORTB_PB0;
    }
   
}
作者: xnhzl    时间: 2011-10-31 23:19

作者: 1637557819    时间: 2012-4-29 15:59
搞不懂




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