OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10237|回复: 7

关于SetSysClockTo72

[复制链接]

1

主题

10

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2013-12-14
在线时间
0 小时
发表于 2014-1-18 13:07:27 | 显示全部楼层 |阅读模式
static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
  /* Enable HSE */    
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;  
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }  

  if (HSEStatus == (uint32_t)0x01)
  {
    /* Enable Prefetch Buffer */
    FLASH->ACR |= FLASH_ACR_PRFTBE;

    /* Flash 2 wait state */
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    

 
    /* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
    /* PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL
    /* Configure PLLs ------------------------------------------------------*/
    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
        
    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
  
    /* Enable PLL2 */
    RCC->CR |= RCC_CR_PLL2ON;
    /* Wait till PLL2 is ready */
    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
    {
    }
    
   
    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 
    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
                            RCC_CFGR_PLLMULL9); 
#else    
    /*  LL configuration: PLLCLK = HSE * 9 = 72 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL */

    /* Enable PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* Wait till PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
    
    /* Select PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

    /* Wait till PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
  }
  else
  { /* If HSE fails to start-up, the application will have wrong clock 
         configuration. User can add here some code to deal with this error */
  }
}
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2013-12-14
在线时间
0 小时
 楼主| 发表于 2014-1-18 13:09:27 | 显示全部楼层
/* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* CLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
    /* CLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

我搞不清楚这三句到底有什么作用啊,把宏代进来后,前面两个都是RCC->CFGR |=0,后面是RCC->CFGR |=0x400,这样是在做什么?看注释好像在配置HCLK和PCLK?
回复 支持 反对

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2013-12-14
在线时间
0 小时
 楼主| 发表于 2014-1-18 13:12:52 | 显示全部楼层
在库里我看到这三个函数:
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
void RCC_PCLK1Config(uint32_t RCC_HCLK);
void RCC_PCLK2Config(uint32_t RCC_HCLK);
但看它们的实现:
void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
{
  uint32_t tmpreg = 0;
  /* Check the parameters */
  assert_param(IS_RCC_HCLK(RCC_SYSCLK));
  tmpreg = RCC->CFGR;
  /* Clear HPRE[3:0] bits */
  tmpreg &= CFGR_HPRE_Reset_Mask;
  /* Set HPRE[3:0] bits according to RCC_SYSCLK value */
  tmpreg |= RCC_SYSCLK;
  /* Store the new value */
  RCC->CFGR = tmpreg;
}



void RCC_PCLK1Config(uint32_t RCC_HCLK)
{
  uint32_t tmpreg = 0;
  /* Check the parameters */
  assert_param(IS_RCC_PCLK(RCC_HCLK));
  tmpreg = RCC->CFGR;
  /* Clear PRE1[2:0] bits */
  tmpreg &= CFGR_PPRE1_Reset_Mask;
  /* Set PRE1[2:0] bits according to RCC_HCLK value */
  tmpreg |= RCC_HCLK;
  /* Store the new value */
  RCC->CFGR = tmpreg;
}


void RCC_PCLK2Config(uint32_t RCC_HCLK)
{
  uint32_t tmpreg = 0;
  /* Check the parameters */
  assert_param(IS_RCC_PCLK(RCC_HCLK));
  tmpreg = RCC->CFGR;
  /* Clear PRE2[2:0] bits */
  tmpreg &= CFGR_PPRE2_Reset_Mask;
  /* Set PRE2[2:0] bits according to RCC_HCLK value */
  tmpreg |= RCC_HCLK << 3;
  /* Store the new value */
  RCC->CFGR = tmpreg;
}


明显和上面的不一样啊
/* HCLK = SYSCLK */ 
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 
       
    /* CLK2 = HCLK */ 
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 
     
    /* CLK1 = HCLK */ 
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
回复 支持 反对

使用道具 举报

28

主题

1489

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1656
金钱
1656
注册时间
2013-7-24
在线时间
1 小时
发表于 2014-1-18 13:22:06 | 显示全部楼层
这是在配置CFRG寄存器,具体位定义在手册上可以找到。
如果是问明明是0还要进行或操作,这是为了保证一致性,它是一组对应的宏定义。
于20150522停用该账号:http://www.microstar.club
回复 支持 反对

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2013-12-14
在线时间
0 小时
 楼主| 发表于 2014-1-18 13:29:26 | 显示全部楼层
回复【4楼】styleno1:
---------------------------------
/* HCLK = SYSCLK */  
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;  
        
    /* CLK2 = HCLK */  
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;  
      
    /* CLK1 = HCLK */  
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
主要是对这三句注释很疑惑啊
回复 支持 反对

使用道具 举报

13

主题

121

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-12-12
在线时间
13 小时
发表于 2014-1-18 16:52:39 | 显示全部楼层
回复【5楼】新人于波:
---------------------------------
如楼上,对寄存器CFGR的配置,应该是预分频系数的设置!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2014-1-19
在线时间
0 小时
发表于 2014-1-19 16:38:40 | 显示全部楼层
第三句注释错了,应该是:
/* CLK1 = HCLK/2 */   
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 

按照时钟结构图,SYSCLK之后经过AHB预分频器后就是HCLK,第一句就是不分频,让SYSCLK和HCLK相等;
然后HCLK分别经过APB1、APB2配置PCLK1和PCLK2的时钟,分别是2分频和不分频,最后的结果就是
假设SYSCLK=72MHz,那么HCLK=72MHz,PCLK1=36MHz,PCLK2=72MHz

其实你大可不必过多关注注释的内容,每一句程序几乎都有自注释的能力。
回复 支持 反对

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2013-12-14
在线时间
0 小时
 楼主| 发表于 2014-1-20 14:45:17 | 显示全部楼层
回复【7楼】chndemo:
---------------------------------
RCC->CFGR?|=?(uint32_t)RCC_CFGR_HPRE_DIV1; 
前面有定义RCC_CFGR_HPRE_DIV1=0;
那就是说这一句等价为RCC->CFGR?|=?0;任何一个数和0相或后根本不会有任何改变啊,就是说这一句操作后CFGR不会有任何变化,为什么你们说执行后AHB的时钟就设定为sysclk了?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 22:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表