登录站点

用户名

密码

MC9S12XS128 中 PIT (周期中断定时器) 的使用

2已有 2129 次阅读  2010-09-29 11:37   标签PIT  定时器  周期  飞思卡尔  MC9S12XS128 
 
 
写在前面的话->:
在 MC9S12XS128 这款单片机中 没有像 51 或者 AVR 那样的递减计数器,即在一个计时计数器中装一个数,单片机 让这个数在一定的时钟周期性 减 1 ,直道这个数减到 0 为止来实现多少时间的定时。当寄存器的值变为0时又重新装入数来再计时,装数有自动装载和手动装载两种,学过 51 跟 AVR 的朋友应该明白这两种模式。虽然 MC9S12XS128 这款单片机没有这样的定时器,但是它提供了 PIT 定时器,即  Periodic Interrupt Timer (S12PIT24B4CV1),即周期性中断定时器。PIT 分为 PIT0、PIT1、PIT2、PIT3 ,它们均是以中断的方式来实现定时的,具体能够实现多大范围的定时可参考 datasheet . PIT0、PIT1、PIT2、PIT3 对应的中断向量号分别为 66、67、68、69。还要注意 PIT 是没有外部引脚的。
那么如何通过编程来实现 PIT 来定时呢?在 数据手册的 363 页给出了 汇编代码的实现,当初我使用的时候已经把汇编转化成 C 语言了。
下面简单地来说下 PIT 的编程过程->:
1、8-Bit Micro Timer 0 跟 8-Bit Micro Timer 1 从 Bus Clock 里面获取时钟信号,通过编程 PITMTLDX 这 
  个寄存器来 获得分频系数。
2、让 PITX 连接到 8-Bit Micro Timer X 。通过编程 16 位的寄存器 PITLDX 来实现多少时间的定时
3、具体定时的公式可参考数据手册 Chapter 12 里面的公式。最好能弄明白 360 页的  PIT24B4C Detailed
   Block Diagram。
对程序的一些说明->:
该例程只是 以 PIT0 来做实验,用户想用其他 PITX 的话只需修改 PITCE_PCEX、PITMUX_PMUXX、PITMTLDX、PITLDX、PITINTE_PINTEX、PITTF_PTFX 中的 X 即可,X 可去取 0、1、2、3。要实现不同时间的定时可通过修改寄存器 PITMTLDX (8-bit)、PITLDX (16-bit) 的值即可。实现的公式为:
             time-out period = (PITMTLD + 1) * (PITLD + 1) / fBUS.
/**********************以下为代码实现**********************************/
#include <hidef.h>      /* common defines and macros */
#include <MC9S12XS128.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"
#define uchar  unsigned char
#define uint  unsigned int
/*--------函数原型声明-------------------------*/
void SetBusCLK_40M(void);
void  Pit0_Init(void);
/*----------------主函数------------------------/
 *
 *主函数中等待 PIT0 中断的到来,当中断到来后在中断
 *服务程序中 LED 以 480 MS 的频率 亮灭
 *
 **/
void main(void)
{
  /* put your own code here */
  SetBusCLK_40M();  
 
  DDRB=0XFF;      //PB 口设置为输出
  PORTB=0XFF;     //PB 口初始化输出高电平,即 8 路 LED 全灭
  
  EnableInterrupts;        //要打开全局中断,因为 PIT 是以中断的方式来实现的
  Pit0_Init();
  for(;;) {}      //等待中断的到来
  /* please make sure that you never leave this function */
}
 
/*-----------------配置系统时钟------------------*/  
void SetBusCLK_40M(void)
{  
    CLKSEL=0X00;    //disengage PLL to system
    PLLCTL_PLLON=1;   //turn on PLL
    SYNR =0xc0 | 0x04;                       
    REFDV=0xc0 | 0x01;
    POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=80MHz;
    _asm(nop);          //BUS CLOCK=40M
    _asm(nop);
    while(!(CRGFLG_LOCK==1));   //when pll is steady ,then use it;
    CLKSEL_PLLSEL =1;          //engage PLL to system;
}
/*-----------------PIT0初始化------------------*/
void  Pit0_Init(void)
{
   PITCFLMT_PITE=0;          //disable PIT
  
   PITCE_PCE0=1;             //enable timer channel 0
   PITMUX_PMUX0=0;           //ch0 connected to micro timer 0
  
   PITMTLD0=0XFF ;           //micro time base 0 equals 255 clock cycles  
   PITLD0=0XFFFF;            //time-out period = (PITMTLD + 1) * (PITLD + 1) / fBUS.
                        
   PITINTE_PINTE0=1;         //enable interupt channel 0   
         
   PITCFLMT_PITE=1;          //enable PIT
}
/*-----------------PIT0中断服务程序------------------*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 66 PIT0_ISR(void)                       
{   // 40MHZ 420Ms timer overflow
  PITTF_PTF0=1;    //CLER FLAG   
  PORTB=~PORTB;                                                                            
}
/*---------------end of file----------------------*/
                        不才,欢迎拍砖。

上一篇: VIVI 源码的目录结构分析 下一篇: MC9S12XS128 中 RTI (实时时钟中断) 的使用

分享 举报

发表评论 评论 (1 个评论)

涂鸦板