打印
[资料分享与下载]

KL46时钟输出

[复制链接]
951|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ccw1986|  楼主 | 2015-7-10 09:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有辛得到到了一套飞思卡尔的开发套件,是万利电子出品的。做工很赞,很高大上。首先我从它的时钟系统入手。去官网下了个数据手册和参考手册下来。         主要是看数据手册的时钟模块。一看手册,真晕了,时钟系统好复杂。整个时钟系统由 MCG、OSC 和 RTC 几部分组成,此外还与 SIM 有关系,这是因为 SIM 控制了大多数模块的时钟门控。这个跟STM32也是类似的,要用到那个外设,先要把相应的时钟打开。下面我自己用例程工程,配置了时钟,并且把总线时钟频率二分频输出到PTC3口上输出,如下图可以看出PTC3有个复用功能是时钟输出。然后我从官网下载一些KL46 Demo板的源代码。然后就找到同一型号的芯片的例程。这个例程刚好满足的要求,用PTC3输出时钟,例程还有串口的程序,这部分用不到,我就注释了。我用了Keil v5.1的编译环境。大家注意的是从keil v5版本开始,芯片的支持包要用户选择下载。具体的方法如下:把例程打开后:我这里是用Jlink V8进行仿真和下载程序的,所以工程的配置还要设置一下才能用,方法如下:成功仿真器连上板子的的仿真接口后会出现红框里的信息,仿真接口模式要选择SW模式。
接着就是配置flash要想在PTC3口输出时钟还要做一下工作:大家可以看到这里有个条件编译,要把这个参数填进去预定义方框才行,或者你可以直接将ENABLE_CLKOUT改为1,这样编译器就会编译这部分代码,在编译器预定义方框打开的步骤如图:做完这些工作就可以编译工程和下载程序进行验证了:主程序很简单,代码如下:int main (void){             charch;
#ifdef CMSIS// If we are conforming to CMSIS, we need tocall start here    start();#endif
       printf("\n\rRunningthe platinum project.\n\r");
         while(1)         {                   //ch = in_char();                   //out_char(ch);         } }首先程序会执行start();进行一些系统的初始化。我们来看看start();的内部吧:void start(void){                    /* Disable the watchdog timer */    SIM_COPC = 0x00;#ifndef CMSIS    // If conforming to CMSIS, we do not needto perform this code

         /* Copy any vector or data sections that need to be in RAM*/         common_startup();#endif
         /* Perform clock initialization, default UARTinitialization,         * initializes clock out function, andenables the abort button         */                            // common_startup();            sysinit();
      printf("\n\r\n\r");
         /* Determine the last cause(s) of reset */         outSRS();
         /* Determine specific Kinetis L Family device and revision*/         cpu_identify();
#ifndef CMSIS    // If conforming to CMSIS, we do not needto perform this code         /* Jump to main process */         main();
         /* No actions to perform after this so wait forever */         while(1);#endif }最重要的是sysinit();函数,因为这个是初始化系统时钟的。源代码如下:/********************************************************************/void sysinit (void){      /* Enable all of the port clocks. Thesehave to be enabled to configure         * pin muxing options, so most codewill need all of these on anyway.         */      SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK                      | SIM_SCGC5_PORTB_MASK                      | SIM_SCGC5_PORTC_MASK                      | SIM_SCGC5_PORTD_MASK                      | SIM_SCGC5_PORTE_MASK );
      // Release hold with ACKISO:Only has an effect if recovering from VLLS1,VLLS2, or VLLS3      // if ACKISO is set you must clearackiso before calling pll_init       //   or pll init hangs waiting for OSC to initialize      // if osc enabled in low power modes -enable it first before ack      // if I/O needs to be maintainedwithout glitches enable outputs and modules first before ack.      if (PMC_REGSC &PMC_REGSC_ACKISO_MASK)      PMC_REGSC |= PMC_REGSC_ACKISO_MASK;
#ifdef ENABLE_CLKOUT      // Initialize trace clk functionality      clk_out_init();#endif
#if defined(NO_PLL_INIT)      mcg_clk_hz = 21000000; //FEI mode
      SIM_SOPT2 &=~SIM_SOPT2_PLLFLLSEL_MASK; // clear PLLFLLSEL to select the FLL for this clocksource
      uart0_clk_khz = (mcg_clk_hz / 1000); //the uart0 clock frequency will equal the FLL frequency
#else        /* Ramp up the system clock */       /* Set the system dividers */       /* NOTE: The PLL init will not configurethe system clock dividers,      * so they must be configuredappropriately before calling the PLL      * init function to ensure that clocksremain in valid ranges.      */       SIM_CLKDIV1 = ( 0                        |SIM_CLKDIV1_OUTDIV1(0)                        |SIM_CLKDIV1_OUTDIV4(1) );
       /* Initialize PLL */       /* PLL will be the source for MCG CLKOUTso the core, system, and flash clocks are derived from it */        mcg_clk_hz = pll_init(CLK0_FREQ_HZ,/* CLKIN0 frequency */                           LOW_POWER,   /* Set the oscillator for low power mode*/                           CLK0_TYPE,   /* Crystal or canned oscillator clockinput */                           PLL0_PRDIV,    /* PLL predivider value */                           PLL0_VDIV,    /* PLL multiplier */                           MCGOUT);       /* Use the output from this PLL as theMCGOUT */
       /* Check the value returned frompll_init() to make sure there wasn't an error */       if (mcg_clk_hz < 0x100)         while(1);
       SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;// set PLLFLLSEL to select the PLL for this clock source
       uart0_clk_khz = ((mcg_clk_hz / 2) /1000); // UART0 clock frequency will equal half the PLL frequency#endif      
         /*         * Use the value obtained from thepll_init function to define variables          * for the core clockin kHz and also the peripheral clock. These          * variables can beused by other functions that need awareness of the          * system frequency.          */      mcg_clk_khz = mcg_clk_hz / 1000;       core_clk_khz= mcg_clk_khz / (((SIM_CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> 28)+1);      periph_clk_khz = core_clk_khz /(((SIM_CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> 16)+ 1);
      /* Enable pin interrupt for the abortbutton - PTA4 */      /* This pin could also be used as theNMI interrupt, but since the NMI         * is level sensitive each button presswill cause multiple interrupts.         * Using the GPIO interrupt insteadmeans we can configure for an edge         * sensitive interrupt instead = oneinterrupt per button press.         */      enable_abort_button();

      if (TERM_PORT_NUM == 0)      {         /* Enable the pins for the selected UART */#ifdef FREEDOM          /* Enable the UART_TXD function onPTA1 */          PORTA_PCR1 = PORT_PCR_MUX(0x2);
          /* Enable the UART_TXD function onPTA2 */          PORTA_PCR2 = PORT_PCR_MUX(0x2);#endif
#ifdef BACES          /* Enable the UART_TXD function onPTA1 */          PORTA_PCR1 = PORT_PCR_MUX(0x2);
          /* Enable the UART_TXD function onPTA2 */          PORTA_PCR2 = PORT_PCR_MUX(0x2);#endif         
#ifdef FIREBIRD                /* Enable the UART_TXD function on PTA1*/          PORTA_PCR1 = PORT_PCR_MUX(0x2);
          /* Enable the UART_TXD function onPTA2 */          PORTA_PCR2 = PORT_PCR_MUX(0x2);#endif
#ifdef TOWER         
          /* Enable the UART_TXD function on PTA14 */         PORTA_PCR14 = PORT_PCR_MUX(0x3); // UART0 isalt3 function for this pin
         /* Enable the UART_RXD function on PTA15 */         PORTA_PCR15 = PORT_PCR_MUX(0x3); // UART0 isalt3 function for this pin#endif


          SIM_SOPT2 |= SIM_SOPT2_UART0SRC(1);// select the PLLFLLCLK as UART0 clock source      }       if(TERM_PORT_NUM == 1)       {                /* Enable the UART_TXD functionon PTC4 */                PORTC_PCR4= PORT_PCR_MUX(0x3); // UART1 is alt3 function for this pin
                /*Enable the UART_RXD function on PTC3 */                PORTC_PCR3= PORT_PCR_MUX(0x3); // UART1 is alt3 function for this pin       }
      if (TERM_PORT_NUM == 2)       {               /* Enable the UART_TXDfunction on PTD3 */                PORTE_PCR16= PORT_PCR_MUX(0x3); // UART2 is alt3 function for this pin
                /*Enable the UART_RXD function on PTD2 */                PORTE_PCR17= PORT_PCR_MUX(0x3); // UART2 is alt3 function for this pin       }
       /*UART0 is clocked asynchronously to the core clock, but all other UARTs are         * clocked from the peripheral clock.So we have to determine which clock         * to send to the UART_init function.         */      if (TERM_PORT_NUM == 0)         uart0_init (UART0_BASE_PTR, uart0_clk_khz, TERMINAL_BAUD);      else if (TERM_PORT_NUM == 1)         uart_init (UART1_BASE_PTR, periph_clk_khz,TERMINAL_BAUD);      else if (TERM_PORT_NUM == 2)            uart_init (UART2_BASE_PTR, periph_clk_khz,TERMINAL_BAUD);      else          while(1);}一开始关闭看门狗:SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK                      | SIM_SCGC5_PORTB_MASK                      | SIM_SCGC5_PORTC_MASK                      | SIM_SCGC5_PORTD_MASK                      | SIM_SCGC5_PORTE_MASK );
这里是打开所有GPIO的时钟,如下图的手册说明:然后程序主要的部分是PLL配置了:      /* Initialize PLL */      /* PLL will be the source for MCG CLKOUT so the core, system, and flashclocks are derived from it */       mcg_clk_hz = pll_init(CLK0_FREQ_HZ,/* CLKIN0 frequency */                           LOW_POWER,   /* Set the oscillator for low power mode*/                           CLK0_TYPE,   /* Crystal or canned oscillator clockinput */                           PLL0_PRDIV,    /* PLL predivider value */                           PLL0_VDIV,   /* PLL multiplier */                           MCGOUT);       /* Use the output from this PLL as theMCGOUT */
      /* Check the value returned from pll_init() to make sure there wasn't anerror */      if (mcg_clk_hz < 0x100)      while(1);
      SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; // set PLLFLLSEL to select thePLL for this clock source填进去pll_init函数里的几个参数,是可以改的,可以找到相应的头文件修改。


相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

925

帖子

6

粉丝