加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

MPC5604p的PIT模块进中断问题整理

(2016-05-11 11:02:17)
标签:

mpc5604p

pit

定时中断

pll超频

分类: 单片机
一个小小的疏忽,造成中断长期进不去,进而导致自己开始怀疑CW生成的底层中断表的问题、怀疑自己的CLK初始化和RUN_MODE的设置问题。昨天晚上一晚上的思考、查看别人的程序、对比论坛里面的东西,还是没有解决问题。但是内心强烈的不甘和自己想做出自己东西的欲望,睡了6H后又爬了起来继续。
洗脸时问了强哥关于汇编的问题:eg:asm FUNC()  //定义了一个函数,我要调用时怎样像c中extern那样声明呢?强哥好思路:1.转化为c;2.直接放在main.c页
洗完脸狂搞,终于累了,吃个早餐,想要放弃(自己真的很急躁)时,再坚持了一点儿,于是就去图书馆,准备了问题和程序后,生怕过多耽误学长的时间,去找了大神研究生学长。学长真的很有耐性,他给我的一些思想必须得记录下来:
       1.要抓住自己的专业,不要跑偏,写底层不是我们干的事。价值不大。懂了又能怎么样呢
       2.一定不要怀疑别人都用的东西,尤其是正规软件生成的东西。在此基础上去努力解决问题,在相信前面对的基础上,专注一个方向去搞(节约时间、效率)。还有就是一定要细心,逐个排查(我的问题就出在了:在全局中断允许时没有加INTC.CPR.B.PRI = 0;    
具体程序如下:
//建议放在系统初始化部分
//External oscillator frequency macro define
#define MCG_OSC_4M                     4U
#define MCG_OSC_8M                     8U
#define MCG_S_LOCK_MASK                0x00000008U
#define COMMON_OVER_TIME               (1U)
#define WDG_SLOW_TIMEOUT_VALUE         256000ul                  // 1s
#define WDG_FAST_TIMEOUT_VALUE         1280ul                    //10ms
#define WDG_EN                         0x01ul                    // WDG enable bit
#define WDG_FRZ                        0x02ul                    // wdg stop in debug mode
#define WDG_STP                        0x04ul                    // wdg stop in stop mode
#define WDG_CSL                        0x08ul                    // system or osc clock for wdg ,only osc canbe used in 5604b
 
#define WDG_WND                        0x80ul                   // window watchdog enable
#define WDG_ITR                        0x40ul                    // wdg interrupt enable
#define WDG_HLK                        0x20ul                    // hardware lock bit
#define WDG_SLK                        0x10ul                    // software lock bit
#define WDG_RIA                        0x100ul                   // Reset on Invalid Access
//下面函数的功能是将4M或者8M的晶振转化到40M的系统时钟频率
uint8 cpu_busclkset(uint8 OscFreq, uint8 BusFreq)
{
  uint8 ReturnVal = COMMON_OVER_TIME;
  CGM.FMPLL[0].CR.B.IDF = 0;
  if (OscFreq == MCG_OSC_4M) {
  } else if (OscFreq == MCG_OSC_8M) {
    CGM.FMPLL[0].CR.B.ODF = 1;
    CGM.FMPLL[0].CR.B.NDIV = 32;
  } else {
   
  }

  return(ReturnVal);
}
void cpu_Init(void)
{
 
  ME.MER.R = 0x0000001D;
 
  CGM.CMU_0_CSR.R = 0x000000004;      

  //CGM.FMPLL[0].CR.R = 0x02400100;
 
  cpu_busclkset(8,64);              
  ME.RUN[0].R = 0x001F0074;            
  ME.RUNPC[0].R = 0x00000010;          

 
  ME.PCTL[16].R = 0x00;                
  ME.PCTL[17].R = 0x00;                
  ME.PCTL[68].R = 0x00;                
  ME.PCTL[72].R = 0x00;                
  ME.PCTL[73].R = 0x00;                
  ME.PCTL[32].R = 0x00;                
  ME.PCTL[4].R = 0x00;                
 
  ME.PCTL[92].R = 0x00;       //在用PIT时,这一句挺关键的         
 
  ME.MCTL.R = 0x40005AF0;              
  ME.MCTL.R = 0x4000A50F;              
  while (ME.GS.B.S_MTRANS) {
  }                                    

 
  while (ME.GS.B.S_CURRENTMODE != 4) {
 
                                     
  
        //下面可以不加
  SIU.PCR[14].R = 0x0624;              
  SIU.PCR[15].R = 0x0900;              
  SIU.PCR[16].R = 0x0624;              
  SIU.PCR[17].R = 0x0900;               
}
void disableWatchdog(void)
{
  SWT.SR.R = 0x0000c520;    
  SWT.SR.R = 0x0000d928; 
  SWT.CR.R = 0x8000010A;    
 
//下面建议放在PIT初始化中
void PIT_Init(void) 
  PIT.PITMCR.R = 0x00000001;          
  PIT.CH[0].LDVAL.R = 32000;          
  PIT.CH[0].TCTRL.R = 0x00000003 ;      
  //INTC.PSR[59].R = 11;              
}
void PIT_INTC_Init(void) 
   
  INTC_InstallINTCInterruptHandler(ISR_PIT0, 59, 1);    
  }
void ISR_PIT0(void)
{
  PIT_CNT++;
  PIT.CH[0].TFLG.B.TIF = 1; 
}
//下面建议放在main函数所在页或者文件里面
#define EnableInterrupts()             asm(" wrteei 1")
#define DisableInterrupts()            asm(" wrteei 0")

uint16 PIT_CNT = 0;        //时间计数器
main(void) 
{
  uint8 test_i=0;  
  cpu_Init();
  disableWatchdog();
 
  EXCEP_InitExceptionHandlers();
  INTC_InitINTCInterrupts();
  PIT_INTC_Init();
  PIT_Init();    //0.5ms
  
  EnableInterrupts();    //中断允许
  INTC.CPR.B.PRI = 0;      //!!!我的问题就出在了这里。
 for (;;) {}
}

结果:我在调试界面里面添加的测试计数器(一个变量)PIT_CNT可以在中断服务程序(ISR_PIT0)里面实现自加。
OK

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有