[讨论] NXP PLC2366定时器2中断程序

小魏哥哥   2019-12-19 10:49 楼主

最近做项目使用了LPC2366单片机  要增加一个定时器中断来处理接收到的智能设备数据  一下为定时器2设置程序

void Timer2_init(void)
{
   PCONP     |= (1 << 22);    //这里是开Timer2 定时器时钟  因为默认定时器2和定时器3的时钟是关闭的
    T2TC   = 0;                // 这里直接为0
    T2PR   = 0;            // 时钟不分频
    T2MCR  = 0xC0;        /* 设置T2MR2匹配后复位T2TC,并产生中断标志    对应MR2            */
    T2MR2  = Fpclk/20;    //50ms一次中断  Fpclk在下面解释
    T2TCR  = 0x01;          // 启动定时器
    ///////////    
    
    /* 设置定时器0中断IRQ */
    VICIntSelect = 0x00;                /* 所有中断通道设置为IRQ中断            */
    VICVectPri26 = 0x05;                    /* 设置定时器2中断通道分配优先级5    因为是Timer2  所以是 VICVectPri26    */
    //VICVectAddr5 = (uint32)IRQ_Timer1;    /* 设置中断服务程序地址                    */
    VICIntEnable |= (1 <<  26);            /* 使能定时器2中断                        */    
    SetVICIRQ(26,0x05,(uint32)IRQ_Timer2);
}

 

//下面这段代码在另一个头文件中定义   解释T2MR2  = Fpclk/20;   

#define    USE_USB                0

#define Fosc                12000000            //    OSC = 12MHz

#if USE_USB    
    
    #define Fusbclk    48000000
    
    #define Fcclk    (Fosc * 4)                    // 主频 Fcclk = 48MHz
    #define Fcco    (Fusbclk * (USBCLKDivValue+1))        // 如果用了USB,则Fcco是Fcclk与Fusbclk在275~550M之间的最小公倍数
                                                        // Fcco是Fcclk在275~550M之间的最小倍数
    #define Fpclk    (Fcclk / 4)
    
    #define PLL_NValue            1
    #define PLL_MValue            (((Fcco/Fosc)*(PLL_NValue+1)/2)-1)
    #define CCLKDivValue        (Fcco/Fcclk-1)
    #define USBCLKDivValue        5    
#else
    #define Fcclk    (Fosc * 4)                            // 主频 Fcclk = 48MHz
    #define Fcco    (Fcclk* 6)
    
    #define Fpclk    (Fcclk / 4)
    
    #define PLL_NValue            1    
    #define PLL_MValue            (((Fcco/Fosc)*(PLL_NValue+1)/2)-1)
    #define CCLKDivValue        (Fcco/Fcclk-1)
    #define USBCLKDivValue        254        
#endif    
 

/*********************************************************************************************************
** Function name:            SetVICIRQ
** Descriptions:            设置所选外设的中断优先级、中断服务函数地址,并使能中断
** input parameters:        channel        :外设对应的中断通道号
**                            PRI           :中断优先级
**                            ISRFuction     :中断服务函数地址

** Returned value:            成功        :返回 1
**                            失败        :返回 0
*********************************************************************************************************/
__inline uint32 SetVICIRQ(uint32 channel,uint32 PRI,uint32 ISRFuction)
{
    return(OsSwiHandle1(0x100,channel,PRI,ISRFuction));    

 

///////////////////////////////////////////////////////////////

/* *********************************************************************************************************
*                    与ARM7体系结构相关的一些定义
**********************************************************************************************************/
#define     OS_CRITICAL_METHOD     2            /* 选择开、关中断的方式 */

__swi(0x00) int OsSwiHandle1(int Handle,...);
__swi(0x01) void *OsSwiHandle2(int Handle, int Index);

#define OS_TASK_SW() OsSwiHandle1(0)                        /* 任务级任务切换函数          */
#define _OSStartHighRdy() OsSwiHandle1(1)                   /* 运行优先级最高的任务        */
#define OS_ENTER_CRITICAL()  OsSwiHandle1(2)                /* 关中断                      */
#define OS_EXIT_CRITICAL()  OsSwiHandle1(3)                 /* 开中断                      */

#define ChangeToSYSMode() OsSwiHandle1(4)                   /*  任务切换到系统模式          */
#define ChangeToUSRMode() OsSwiHandle1(5)                   /*  任务切换到用户模式          */

#define OSISRBegin()  OsSwiHandle1(6)                       /*  中断开始处理                */
#define OSISRNeedSwap() OsSwiHandle1(7)                     /*  判断中断是否需要切换        */

#define OS_STK_GROWTH    1                      /*  堆栈是从上往下长的          */

#define     USR32Mode       0x10                /*  用户模式                    */
#define     SYS32Mode       0x1f                /*  系统模式                    */
#define     NoInt           0x80

#ifndef USER_USING_MODE
#define    USER_USING_MODE    USR32Mode               /*  任务缺省模式                 */
#endif

#ifndef OS_SELF_EN
#define    OS_SELF_EN     0                        /*  允许返回OS与任务分别编译、固化*/    
#endif


OS_CPU_EXT INT32U OsEnterSum;                   /*  关中断计数器(开关中断的信号量)    */


/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/
 

 //  中断函数

 

void IRQ_Timer2 (void)
{
    uint8 test[2]={0},test1[4]={0x04,0x04,0x04,0x04};
    static unsigned char ttt;
        
    OS_ENTER_CRITICAL();//关中断
    
    T2IR = 0x04;                // 清除MR2中断标志    
    /////////////////////////////////////////
  WDFEED = 0xAA;  //喂狗
  WDFEED = 0x55;    
  
  WDI706Feed();
  
  ///////////////////////////////////
   //验证定时器功能
      ttt++;
  
  if(ttt>100)
  {
          ttt=0;
    
         zhi++;
         if(zhi<50)
         {
           test[0]=zhi;
           test[1]=zhi;
           memcpy(SendDataBuf,&test[0],2);
           MainC_SendMessage(2);
           OSTimeDly(OS_Time_500ms); 
         }
         else
         {
          zhi =0;
         }  
  }

 
    OS_EXIT_CRITICAL();  //开中断
    VICVectAddr = 0x00;            // 通知VIC中断处理结束                            

 

 

回复评论 (1)

在定时器中断中  不能直接调用函数    另外结构体数组数据用完一定清零

点赞  2019-12-24 13:49
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复