[技术问答] 【七,八楼已更正说明】为什么工程配置时设置频率为50MHZ

[复制链接]
3539|11
 楼主| niuyaliang 发表于 2013-12-6 22:37 | 显示全部楼层 |阅读模式
本帖最后由 niuyaliang 于 2013-12-8 09:15 编辑

    在我的上一个帖子配置M058S的工程时,曾经有疑问,以前的单片机设置频率时,我用多大的晶振,就设置多少的频率,为什么新塘官网给的例程都把晶振设置为50MHZ呢?曾经以为这种做法是错误的,我配置成实际的12MHZ即可,今天经过一位网友的解释,我恍然大悟。
/**************************
    原来在MCU执行main函数之前,他会先执行system_M051series.c中的程序,在这里程序宏定义了MCU的时钟为PLL倍频后的时钟,即为固定的50MHZ,所以在工程中需要配置频率为50MHZ。
**************************/
    见七楼的更正
 楼主| niuyaliang 发表于 2013-12-6 23:08 | 显示全部楼层
本帖最后由 niuyaliang 于 2013-12-6 23:16 编辑
  1. uint32_t SystemCoreClock  = __HSI;              /*!< System Clock Frequency (Core Clock) */
  2. uint32_t CyclesPerUs      = (__HSI / 1000000);  /*!< Cycles per micro second             */
  3. uint32_t PllClock         = __HSI;              /*!< PLL Output Clock Frequency   
  1. #define __XTAL      (12000000UL)    /*!< External Crystal Clock Frequency     */
  2. #define __IRC22M    (22118400UL)    /*!< Internal 22M RC Oscillator Frequency */
  3. #define __IRC10K    (10000UL)       /*!< Internal 10K RC Oscillator Frequency */
  4. #define __HSI       (50000000UL)    /*!< PLL default output is 48MHz@12M X'tal or 48.065MHz@22.1184MHz IRC */

bobde163 发表于 2013-12-7 19:43 | 显示全部楼层
50Hz还是50MHz?
 楼主| niuyaliang 发表于 2013-12-7 20:28 | 显示全部楼层
bobde163 发表于 2013-12-7 19:43
50Hz还是50MHz?

晕,50MHZ的,竟然三处都没打上M,太诡异了
黄小俊 发表于 2013-12-7 23:18 | 显示全部楼层
bobde163 发表于 2013-12-7 23:48 | 显示全部楼层
niuyaliang 发表于 2013-12-7 20:28
晕,50MHZ的,竟然三处都没打上M,太诡异了

我看到三处都是50Hz,觉得奇怪,所以确认一下
 楼主| niuyaliang 发表于 2013-12-8 09:09 | 显示全部楼层
在执行主函数之前,MCU会先编译宏定义指令,PLL倍频为50MHZ的指令在SYS.h函数中
  1. #if (__XTAL == 12000000)
  2. #define SYSCLK_PLLCON_50MHz_XTAL   (SYSCLK_PLLCON_FIN_XTAL | SYSCLK_PLLCON_NR(3) | SYSCLK_PLLCON_NF( 25) | SYSCLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 50MHz PLL output with 12MHz X'tal */
  3. #define SYSCLK_PLLCON_48MHz_XTAL   (SYSCLK_PLLCON_FIN_XTAL | SYSCLK_PLLCON_NR(7) | SYSCLK_PLLCON_NF(112) | SYSCLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 48MHz PLL output with 12MHz X'tal */
  4. #define SYSCLK_PLLCON_36MHz_XTAL   (SYSCLK_PLLCON_FIN_XTAL | SYSCLK_PLLCON_NR(7) | SYSCLK_PLLCON_NF( 84) | SYSCLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 36MHz PLL output with 12MHz X'tal */
  5. #define SYSCLK_PLLCON_32MHz_XTAL   (SYSCLK_PLLCON_FIN_XTAL | SYSCLK_PLLCON_NR(6) | SYSCLK_PLLCON_NF( 64) | SYSCLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 32MHz PLL output with 12MHz X'tal */
  6. #else
在这里定义,当外部晶振为12MHZ时,PLL倍频为50MHZ,SYSCLK_PLLCON_50MHz_XTAL
 楼主| niuyaliang 发表于 2013-12-8 09:12 | 显示全部楼层
然后在启动文件中定义
  1. Reset_Handler   PROC
  2.                 EXPORT  Reset_Handler             [WEAK]
  3.                 IMPORT  SystemInit
  4.                 IMPORT  __main
即在执行main函数之前,先执行SystemInit这个函数
  1. void SystemInit(void)
  2. {
  3. #ifdef INIT_SYSCLK_AT_BOOTING
  4.     int32_t i32TimeoutCnt;
  5.     uint32_t u32HclkSelect;
  6.     int8_t i8IsPllEn;

  7.     PllClock = 0;
  8.     i8IsPllEn = 0;
  9.     u32HclkSelect = SYSCLK->CLKSEL0 & SYSCLK_CLKSEL0_HCLK_S_Msk;
  10.     if(u32HclkSelect == SYSCLK_CLKSEL0_HCLK_XTAL)
  11.     {
  12.         /* Set to 50MHz system clock frequency when clock source is from external 12MHz */
  13.         SYSCLK->PLLCON = SYSCLK_PLLCON_50MHz_XTAL;      
  14.         
  15.         /* Waiting for PLL ready */
  16.         i32TimeoutCnt = (__XTAL / 1000); /* Timeout is about 1ms */
  17.         while((SYSCLK->CLKSTATUS & SYSCLK_CLKSTATUS_PLL_STB_Msk) == 0 )
  18.         {
  19.             if(i32TimeoutCnt-- <= 0)
  20.                 break;   
  21.         }

  22.         i8IsPllEn = 1;
  23.     }
  24.     else if(u32HclkSelect == SYSCLK_CLKSEL0_HCLK_IRC22M)
  25.     {
  26.         /* Set to 50.1918MHz system clock frequency when clock source is from internal 22.1184MHz RC clock */
  27.         SYSCLK->PLLCON = SYSCLK_PLLCON_50MHz_IRC22M;      
  28.         
  29.         /* Waiting for PLL ready */
  30.         i32TimeoutCnt = (__IRC22M / 1000); /* Timeout is about 1ms */
  31.         while((SYSCLK->CLKSTATUS & SYSCLK_CLKSTATUS_PLL_STB_Msk) == 0 )
  32.         {
  33.             if(i32TimeoutCnt-- <= 0)
  34.                 break;   
  35.         }

  36.         i8IsPllEn = 1;
  37.     }

  38.     if(i8IsPllEn)   
  39.     {
  40.         /* Set PLL as HCLK clock source (HCLK_S is locked setting)*/
  41.         SYS_UnlockReg();
  42.         SYSCLK->CLKSEL0 = SYSCLK_CLKSEL0_HCLK_PLL;
  43.         SYS_LockReg();
  44.     }
  45. #endif
  46. }
这样就能理解,为什么在工程中选择50MHZ的频率了
骗子的片子 发表于 2014-1-20 16:01 | 显示全部楼层
楼主很给力啊,这么好学
zxf0168 发表于 2014-2-11 19:39 来自手机 | 显示全部楼层
在MCU执行main函数之前,他会先执行system_M051series.c中的程序,在这里程序宏定义了MCU的时钟为PLL倍频后的时钟,即为固定的50MHZ,所以在工程中需要配置频率为50MHZ。
astudent 发表于 2014-12-29 21:29 | 显示全部楼层
8楼正解


               
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  SystemInit
                IMPORT  __main
 楼主| niuyaliang 发表于 2015-1-6 17:19 | 显示全部楼层
astudent 发表于 2014-12-29 21:29
8楼正解

最后执行的才是主函数
您需要登录后才可以回帖 登录 | 注册

本版积分规则

212

主题

2427

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部