恩智浦 龙邱K66 PIT例程20.01.21

恩智浦 龙邱K66 PIT例程

  1. 宏定义
    #define SIM_SCGC6                                SIM_SCGC6_REG(SIM)
    #define SIM_SCGC6_REG(base)                      ((base)->SCGC6)
    #define SIM                                      ((SIM_Type *)SIM_BASE)
    #define SIM_BASE                                 (0x40047000u)	//SIM地址
    #define SIM_SCGC6_PIT_MASK                       0x800000u	//1000 0000 0000 0000 0000 0000
    #define PIT_MCR                                  PIT_MCR_REG(PIT)
    #define PIT                                      ((PIT_Type *)PIT_BASE)
    #define PIT_BASE                                 (0x40037000u)	//‭PIT_MCR地址
    #define PIT_MCR_MDIS_MASK                        0x2u	//0010	MDIS位置1
    #define PIT_MCR_FRZ_MASK                         0x1u	//0001	FRZ位置0
    #define PIT_LDVAL(index)                         PIT_LDVAL_REG(PIT,index)
    #define PIT_LDVAL_REG(base,index)                ((base)->CHANNEL[index].LDVAL)
    #define PIT_Flag_Clear(PITn)   PIT_TFLG(PITn)|=PIT_TFLG_TIF_MASK      //清中断标志
    #define PIT_TFLG(index)                          PIT_TFLG_REG(PIT,index)
    #define PIT_TFLG_REG(base,index)                 ((base)->CHANNEL[index].TFLG)
    #define PIT_TFLG_TIF_MASK                        0x1u	//0001 1表示超时已发生
    #define PIT_TCTRL(index)                         PIT_TCTRL_REG(PIT,index)
    #define PIT_TCTRL_REG(base,index)                ((base)->CHANNEL[index].TCTRL)
    #define PIT_TCTRL_TEN_MASK                       0x1u	//0001 TEN位置0 启用计时器
    #define PIT_TCTRL_TIE_MASK                       0x2u	//0010 TIE位置1 启用计时器中断
    #define MCG_C1_CLKS(x)                           (((uint8_t)(((uint8_t)(x))<<MCG_C1_CLKS_SHIFT))&MCG_C1_CLKS_MASK)
    #define MCG_C5_PRDIV(x)                          (((uint8_t)(((uint8_t)(x))<<MCG_C5_PRDIV_SHIFT))&MCG_C5_PRDIV_MASK)
  2. 初始化全局变量、枚举与结构体(请自行查找文档)
    PIT channel

    uint8_t core_clk;//单位MHZ
    uint8_t bus_clk;//单位MHZ
    /** PIT - Register Layout Typedef */
    typedef struct {
      __IO uint32_t MCR;                               /**< PIT Module Control Register, offset: 0x0 */
           uint8_t RESERVED_0[220];
      __I  uint32_t LTMR64H;                           /**< PIT Upper Lifetime Timer Register, offset: 0xE0 */
      __I  uint32_t LTMR64L;                           /**< PIT Lower Lifetime Timer Register, offset: 0xE4 */
           uint8_t RESERVED_1[24];
      struct {                                         /* offset: 0x100, array step: 0x10 */
        __IO uint32_t LDVAL;                             /**< Timer Load Value Register, array offset: 0x100, array step: 0x10 */
        __I  uint32_t CVAL;                              /**< Current Timer Value Register, array offset: 0x104, array step: 0x10 */
        __IO uint32_t TCTRL;                             /**< Timer Control Register, array offset: 0x108, array step: 0x10 */
        __IO uint32_t TFLG;                              /**< Timer Flag Register, array offset: 0x10C, array step: 0x10 */
      } CHANNEL[4];
    } PIT_Type, *PIT_MemMapPtr;
    typedef enum PITn
    {
        PIT0,
        PIT1,
        PIT2,
        PIT3
    } PITn;
    //PLL参数
    typedef enum clk_option
    {
        PLLUNULL ,
        PLL80    ,
        PLL90    ,
        PLL100   ,
        PLL120   ,
        PLL130   ,
        PLL140   ,
        PLL150   ,
        PLL160   ,
        PLL170   ,
        PLL180   ,
        PLL200   ,
        PLL220   ,
        PLL225   ,
        PLL230   ,
        PLL235   ,
        PLL237_5 , //实际为237.5M
    } clk_option;//单片机频率
  3. 系统函数
    PLL_prdiv

    PLL_vdiv

    /*************************************************************************
    *                        龙丘智能科技有限公司
    *
    *  函数名称:pll_init
    *  功能说明:时钟初始化,用于设定频率。
    *  参数说明:PLL_?
    *  函数返回:无
    *  修改时间:2016-8-20
    *  备    注:内核时钟(系统时钟)=外部时钟(50M晶振频率)/ (pll_prdiv+1)*(pll_vdiv+16);
                 MCG=PLL, core = MCG, bus = MCG/5, FlexBus = MCG/3, Flash clock= MCG/8
    *  例    子:pll_init(PLL180);
    *************************************************************************/
    void PLL_Init(clk_option opt)
    {
         char pll_prdiv;
         char pll_vdiv;
    
         SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK
                     | SIM_SCGC5_PORTB_MASK
                     | SIM_SCGC5_PORTC_MASK
                     | SIM_SCGC5_PORTD_MASK
                     | SIM_SCGC5_PORTE_MASK );
    
        u32 temp_reg;
    
        if(opt!= PLLUNULL )
        {
            //设置PLL时钟
            switch(opt)
            {
            case PLL80:
                pll_prdiv       = 4;
                pll_vdiv        = 0;
                break;
            case PLL90:
                pll_prdiv       = 4;
                pll_vdiv        = 2;
                break;
            case PLL100:
                pll_prdiv       = 4;
                pll_vdiv        = 4;
                break;
            case PLL120:
                pll_prdiv       = 4;
                pll_vdiv        = 8;
                break;
            case PLL130:
                pll_prdiv       = 4;
                pll_vdiv        = 10;
                break;
            case PLL140:
                pll_prdiv       = 4;
                pll_vdiv        = 12;
                break;
            case PLL150:
                pll_prdiv       = 4;
                pll_vdiv        = 14;
                break;
            case PLL160:
                pll_prdiv       = 4;
                pll_vdiv        = 16;
                break;
            case PLL170:
                pll_prdiv       = 4;
                pll_vdiv        = 18;
                break;
            case PLL180:
                pll_prdiv       = 4;
                pll_vdiv        = 20;
                break;
            case PLL200:
                pll_prdiv       = 4;
                pll_vdiv        = 24;
                break;
           case PLL225:
                pll_prdiv       = 4;
                pll_vdiv        = 28;
                break;
            case PLL220:
                pll_prdiv       = 4;
                pll_vdiv        = 29;
                break;
            case PLL230:
                pll_prdiv       = 4;    //稳定
                pll_vdiv        = 30;
                break;
           case PLL235:
                pll_prdiv       = 4;    //不稳定
                pll_vdiv        = 31;
                break;
           case PLL237_5:               //很不稳定
                pll_prdiv       = 3;
                pll_vdiv        = 22;
                break;
            default:               break;//(初始化未成功,系统默认系统时钟为180M)
    
            }
        }
        MCG_C1 = MCG_C1_CLKS(2) ;//选择外部时钟
      //1内部 2外部 3保留
    
        MCG_C5 = MCG_C5_PRDIV(pll_prdiv);//晶振为50M,分频结果范围要在8M~16M 此时为 50/(prdiv+1)
    
    
       temp_reg = FMC_PFAPR;
    
        //通过M&PFD置位M0PFD来禁止预取功能
        FMC_PFAPR |= FMC_PFAPR_M7PFD_MASK | FMC_PFAPR_M6PFD_MASK | FMC_PFAPR_M5PFD_MASK
                         | FMC_PFAPR_M4PFD_MASK | FMC_PFAPR_M3PFD_MASK | FMC_PFAPR_M2PFD_MASK
                         | FMC_PFAPR_M1PFD_MASK | FMC_PFAPR_M0PFD_MASK;
        ///设置系统分频器
        //MCG=PLL, core = MCG,  
        SIM_CLKDIV1 =  SIM_CLKDIV1_OUTDIV1(0)    //core = MCG
                     | SIM_CLKDIV1_OUTDIV2(1)    //bus = MCG/2,
                     | SIM_CLKDIV1_OUTDIV3(2)    //FlexBus = MCG/(2+1)
                     | SIM_CLKDIV1_OUTDIV4(7);   //Flash clock= MCG/8
    
        //从新存FMC_PFAPR的原始值
        FMC_PFAPR = temp_reg;
    
        MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(pll_vdiv);//PLL =  50M/(prdiv+1) * (pll_vdiv+16)
      //设置C6之前要配置好C5
        while (!(MCG_S & MCG_S_PLLST_MASK)){}; // wait for PLL status bit to set
        while (!(MCG_S & MCG_S_LOCK0_MASK)){}; // Wait for LOCK bit to set
    
    
        MCG_C1=0x00;
    
        //等待时钟状态位更新
        while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){};
    
    
        core_clk = 50 * ( pll_vdiv+16 )/2/(pll_prdiv+1);
        bus_clk =core_clk/2;   
    
        
     /*
            //设置跟踪时钟为内核时钟
        SIM_SOPT2 |= SIM_SOPT2_TRACECLKSEL_MASK;
        //在PTA6引脚上使能TRACE_CLKOU功能
        PORTA_PCR6 = ( PORT_PCR_MUX(0x7));
        //使能FlexBus模块时钟
        SIM_SCGC7 |= SIM_SCGC7_FLEXBUS_MASK;
        //在PTA6引脚上使能FB_CLKOUT功能
        PORTC_PCR3 = ( PORT_PCR_MUX(0x5));
        */
    }
    void PIT_Init(PITn pitn, uint32_t ms)
    {
        //PIT 用的是 Bus Clock 总线频率
    
        /* 开启时钟*/
        SIM_SCGC6       |= SIM_SCGC6_PIT_MASK;                          
      //SIM->SCGC6 FTM0[位置24] 1开启时钟
        /* 使能PIT定时器时钟 ,调试模式下继续运行 */
        PIT_MCR         &= ~(PIT_MCR_MDIS_MASK | PIT_MCR_FRZ_MASK );   
      //PIT_MCR &= ~(10|01) 位置1清零激活定时器 位置0清零激活调试模式
        /* 设置溢出中断时间 */
        PIT_LDVAL(pitn)  = ms * bus_clk * 1000;                                       
      
        /* 清中断标志位 */
        PIT_Flag_Clear(pitn);                                           
      //PIT->TFLGn TIF[位置0]置1 表示超时 如PIT->TCTRL->TIE==TEN==1则会发生中断
        /* 使能 PITn定时器,并开PITn中断 */
        PIT_TCTRL(pitn) |= ( PIT_TCTRL_TEN_MASK | PIT_TCTRL_TIE_MASK );   
      //PIT->TCTRL |= (启用定时器中断|启用定时器)
    }
    

     

发表评论

电子邮件地址不会被公开。 必填项已用*标注