ARM - STM32 使用11.0592MHz晶振

发布者:Xiangsi最新更新时间:2019-05-14 来源: eefocus关键字:ARM  STM32  晶振 手机看文章 扫描二维码
随时随地手机看文章

这里探究了以下stm32 外部时钟的用法。


这里用的是stm32f103rbt6,usart2,外部晶振11.0592Mhz。


先看时钟树吧


这是上图的配置:


void RCC_Init(void)

{

ErrorStatus      HSEStartUpStatus;

RCC_DeInit();

RCC_HSEConfig(RCC_HSE_ON);   //设置外部高速晶振(HSE)

HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待HSE起振

if(HSEStartUpStatus == SUCCESS) //SUCCESS:HSE晶振稳定且就绪

{

RCC_HCLKConfig(RCC_SYSCLK_Div1);  //设置AHB时钟(HCLK),RCC_SYSCLK_Div1——AHB时钟 = 系统时钟

RCC_PCLK2Config(RCC_HCLK_Div1); //设置高速AHB时钟(PCLK2),RCC_HCLK_Div1——APB2时钟 = HCLK

RCC_PCLK1Config(RCC_HCLK_Div2); //设置低速AHB时钟(PCLK1),RCC_HCLK_Div2——APB1时钟 = HCLK / 2

FLASH_SetLatency(FLASH_Latency_2);    //设置FLASH存储器延时时钟周期数,FLASH_Latency_2  2延时周期

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // 选择FLASH预取指缓存的模式,预取指缓存使能

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_2);

// 设置PLL时钟源及倍频系数,PLL的输入时钟 = HSE时钟频率;RCC_PLLMul_2——PLL输入时钟x 2

RCC_PLLCmd(ENABLE);//使能PLL   

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//检查指定的RCC标志位(PLL准备好标志)设置与否   

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 

//设置系统时钟(SYSCLK),RCC_SYSCLKSource_PLLCLK——选择PLL作为系统时钟,11.0592x2

while(RCC_GetSYSCLKSource() != 0x08);   //PLL返回用作系统时钟的时钟源,0x08:PLL作为系统时钟

  }

RCC_GetClocksFreq(&RCC_ClocksStatus);

}



这里的配置和上面的时钟树意义对应,下面读取时钟的函数可以得到各种时钟的值了。可以验证一下,你自己推算的对不对了。


  RCC_GetClocksFreq(&RCC_ClocksStatus);

  if (usartxbase == USART1_BASE)

  {

    apbclock = RCC_ClocksStatus.PCLK2_Frequency;

  }

  else

  {

    apbclock = RCC_ClocksStatus.PCLK1_Frequency;

  }

  

  /* Determine the integer part */

  if ((USARTx->CR1 & CR1_OVER8_Set) != 0)

  {

    /* Integer part computing in case Oversampling mode is 8 Samples */

    integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));    

  }



其中读取时钟的函数RCC_GetClocksFreq函数如下:




void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)

{

  uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;

 

#ifdef  STM32F10X_CL

  uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;

#endif /* STM32F10X_CL */

 

#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)

  uint32_t prediv1factor = 0;

#endif

    

  /* Get SYSCLK source -------------------------------------------------------*/

  tmp = RCC->CFGR & CFGR_SWS_Mask;

  

  switch (tmp)

  {

    case 0x00:  /* HSI used as system clock */

      RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;

      break;

    case 0x04:  /* HSE used as system clock */

      RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;

      break;

    case 0x08:  /* PLL used as system clock */

 

      /* Get PLL clock source and multiplication factor ----------------------*/

      pllmull = RCC->CFGR & CFGR_PLLMull_Mask;

      pllsource = RCC->CFGR & CFGR_PLLSRC_Mask;

      

#ifndef STM32F10X_CL      

      pllmull = ( pllmull >> 18) + 2;

      

      if (pllsource == 0x00)

      {/* HSI oscillator clock divided by 2 selected as PLL clock entry */

        RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;

      }

      else

      {

 #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)

       prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;

       /* HSE oscillator clock selected as PREDIV1 clock entry */

       RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull; 

 #else

        /* HSE selected as PLL clock entry */

        if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET)

        {/* HSE oscillator clock divided by 2 */

          RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE >> 1) * pllmull;

        }

        else

        {

          RCC_Clocks->SYSCLK_Frequency = HSE_VALUE * pllmull;

        }

 #endif

      }

#else

      pllmull = pllmull >> 18;

      

      if (pllmull != 0x0D)

      {

         pllmull += 2;

      }

      else

      { /* PLL multiplication factor = PLL input clock * 6.5 */

        pllmull = 13 / 2; 

      }

            

      if (pllsource == 0x00)

      {/* HSI oscillator clock divided by 2 selected as PLL clock entry */

        RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;

      }

      else

      {/* PREDIV1 selected as PLL clock entry */

        

        /* Get PREDIV1 clock source and division factor */

        prediv1source = RCC->CFGR2 & CFGR2_PREDIV1SRC;

        prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;

        

        if (prediv1source == 0)

        { /* HSE oscillator clock selected as PREDIV1 clock entry */

          RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull;          

        }

        else

        {/* PLL2 clock selected as PREDIV1 clock entry */

          

          /* Get PREDIV2 division factor and PLL2 multiplication factor */

          prediv2factor = ((RCC->CFGR2 & CFGR2_PREDIV2) >> 4) + 1;

          pll2mull = ((RCC->CFGR2 & CFGR2_PLL2MUL) >> 8 ) + 2; 

          RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                         

        }

      }

#endif /* STM32F10X_CL */ 

      break;

 

    default:

      RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;

      break;

  }

 

  /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/

  /* Get HCLK prescaler */

  tmp = RCC->CFGR & CFGR_HPRE_Set_Mask;

  tmp = tmp >> 4;

  presc = APBAHBPrescTable[tmp];

  /* HCLK clock frequency */

  RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;

  /* Get PCLK1 prescaler */

  tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask;

  tmp = tmp >> 8;

  presc = APBAHBPrescTable[tmp];

  /* PCLK1 clock frequency */

  RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;

  /* Get PCLK2 prescaler */

  tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask;

  tmp = tmp >> 11;

  presc = APBAHBPrescTable[tmp];

  /* PCLK2 clock frequency */

  RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;

  /* Get ADCCLK prescaler */

  tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask;

  tmp = tmp >> 14;

  presc = ADCPrescTable[tmp];

  /* ADCCLK clock frequency */

  RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;

}


stm32f10x.h

#if !defined  HSE_VALUE

 #ifdef STM32F10X_CL   

  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */

 #else 

  #define HSE_VALUE    ((uint32_t)11059200) /*!< Value of the External oscillator in Hz */

 #endif /* STM32F10X_CL */

#endif /* HSE_VALUE */





void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)

{

  uint32_t tmpreg = 0x00, apbclock = 0x00;

  uint32_t integerdivider = 0x00;

  uint32_t fractionaldivider = 0x00;

  uint32_t usartxbase = 0;

  RCC_ClocksTypeDef RCC_ClocksStatus;

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate));  

  assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength));

  assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits));

  assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity));

  assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode));

  assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl));

  /* The hardware flow control is available only for USART1, USART2 and USART3 */

  if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None)

  {

    assert_param(IS_USART_123_PERIPH(USARTx));

  }

 

  usartxbase = (uint32_t)USARTx;

 

/*---------------------------- USART CR2 Configuration -----------------------*/

  tmpreg = USARTx->CR2;

  /* Clear STOP[13:12] bits */

  tmpreg &= CR2_STOP_CLEAR_Mask;

  /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/

  /* Set STOP[13:12] bits according to USART_StopBits value */

  tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits;

  

  /* Write to USART CR2 */

  USARTx->CR2 = (uint16_t)tmpreg;

 

/*---------------------------- USART CR1 Configuration -----------------------*/

[1] [2]
关键字:ARM  STM32  晶振 引用地址:ARM - STM32 使用11.0592MHz晶振

上一篇:STM32F4之串口(三)
下一篇:STM32 systick做为系统时间使用(非简单延时)

推荐阅读最新更新时间:2024-11-13 11:02

STM32 C语言编程易错问题总结
(1)注意数组越界问题;有时候前面定义一个数组,在后面使用时候,对数组越界赋值或者操作; (2)错误的条件判断方式;If(0 data 100);//这是错误的写法 应该改成if(0 data && data 100); (3)Switch语句使用:switch和case中间的代码是不会被执行的; (4)在定时器中断服务函数中,定义的变量,一定要修改成全局,否则这个变量会一直被重新定义。这里可以使用static,把函数中的局部变量修改成全局变量。 易错分析,在中断服务函数内部很里面定义一个局部变量,就会出现这个错误; 不仅仅是定时器中断服务函数,其他中断服务函数也是一样的道理; 对比: (5)函数里面定义的局部
[单片机]
<font color='red'>STM32</font> C语言编程易错问题总结
ARMLinux驱动RTC(实时时钟)驱动分析
硬件平台:FL2440(S3C2440) 内核版本:Linux 2.6.28 主机平台:Ubuntu 11.04 内核版本:Linux 2.6.39 交叉编译器版本:arm-linux-gcc 3.4.1 原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/6584285 1、实时时钟概述 实时时钟(RTC)单元可以在断电的情况下使用纽扣电池继续计时工作。RTC使用STRB/LDRB ARM操作传输二进制码十进制数的8位数据给CPU。其中的数据包括秒、分、时、日期、天、月、年的时间信息。可以执行报警功能。 2、实时时钟操作 下面是RTC模块的电路图
[单片机]
ARMLinux驱动RTC(实时时钟)驱动分析
ARM与台积电完成16nm FinFET测试
对于英特尔来说,要想在移动芯片市场多分得一杯羹,就需要借助其更加先进的制造能力的优势。而今日宣布的新款Atom SoCs——举例来说——即基于22nm的3D或“三栅极晶体管”工艺。与传统的(基于平面晶体管结构的)芯片相比,新架构使得芯片可以在较低的电压水平上,更有效率地运作——在降低能耗的同时,更能延长系统的续航时间。 至于半导体行业中的其它公司,已经在向3D晶体管工艺(更常用的称呼为“FinFETs”)迁移的过程中,落后于英特尔。 如果没有这种新的结构,那么向28nm以下制程迁移的过程就会变缓。其中一部分原因为,随着平面型晶体管(planar transistor)变得更小,其能源效率和成本就变得不那么有吸
[半导体设计/制造]
<font color='red'>ARM</font>与台积电完成16nm FinFET测试
ARM+LINUX上使用pppd拔号上网(GPRS)流程
我的编程环境是vmware + fedora9, ARM目标板为ATMEL 9G45,LINUX内核2.6.30, GPRS模块为TELIT公司的GC864-DUAL-V2,使用3线制串口连接(TXD RXD GND) 1.修改2.6.30内核选项, make menuconfig Device drivers - Networking device support - PPP(point to point protocol) support 我选了以下模块(以M方式即module方式) PPP support for async serial ports PPP support for sync tty ports PPP
[单片机]
基于ARM的校园LED公告板系统设计
  近年来, LED 电子显示屏作为一种高科技产品日益引起人们的重视。它可以实时显示或循环播放文字、图形和图像信息,具有显示方式丰富、观赏性强、显示内容修改方便、亮度高、显示稳定且寿命长等多种优点,被广泛应用于诸多领域。随着LED 显示屏行业的不断发展, 人们对LED 显示屏的控制要求越来越高,尤其是LED 显示屏的远程控制,传统的单个LED 显示屏的控制已经很难满足多个LED 显示屏的应用场合。   目前,校园内的LED 公告板的使用越来越多,用于各类通知的宣传和传播,但其控制仍是以单块LED 公告板控制为主流,操作和更新显示屏信息十分不方便。在这种背景下,本设计对目前校园内的LED 公告板系统进行研究和改进,在原有的LE
[电源管理]
基于<font color='red'>ARM</font>的校园LED公告板系统设计
STM32 低功耗模式STOP、STANDBY配合RTC应用实例
项目背景 目标:进入低功耗模式120s左右唤醒。 结果:完成低功耗驱动,完成RTC定时驱动,完成目标; Tip:使用一个新的模块时应主要参考官方文档和官方例程,有问题再上网寻找思路;(本文使用的例程在最后 ) 环境:STM32F205、 IAR6.7、J-Link 附:因为考虑到项目以后需要移植到 stm32F0系列上,而且 stm32F0系列没有 backup SRAM,所以这部分驱动不使用 backup SRAM; 注意:看门狗是不能开启的,否则会在sleep时watch dog重启; 一、STOP模式 +RTC STOP模式: 可以理解为程序进入STOP模式后会暂停运行,直到中断触发退出STOP模式,程序会
[单片机]
<font color='red'>STM32</font> 低功耗模式STOP、STANDBY配合RTC应用实例
STM32的位带操作分析
8051单片机可以直接对某一位IO进行读写操作,而Cortex-M3的位带操作是8051位寻址区的加强版。使用位带操作后,可以使用普通的加载/存储指令对单一的比特进行读写操作。 一、相关概念。 位带区:支持位带操作的地址区。 位带别名区:对别名地址的访问最终作用到位带区的访问上。位带别名区对位带区的访问有个地址映射过程。 二、位带操作的原理 位带操作的最终目的是想对位带区的比特位进行独立的读写操作。但它是通过对位带别名区的操作来实现的。 具体过程如下: 对位带别名区进行读写访问,位带别名区通过地址映射关系映射到相应的位带区,对位带区进行原始比特的读写操作。 三、地址映射 上面对位带操作进行了简
[单片机]
<font color='red'>STM32</font>的位带操作分析
基于ARM-UClinux的无线家庭网关设计
引言   随着网络技术和信息家电的飞速发展,越来越多的家庭要求建立家庭网络。家庭网关是整个家庭网络的核心,它主要实现Internet接入、远程控制,以及连接家庭内部异构子网的功能。基于PC机方案的家庭网关不仅成本较高,而且要求计算机一直处于开机并可进行通信的状态,还不能在计算机上运行干扰通信任务的软件和硬件。所以,为适应普通用户,家庭网关应设计为基于廉价的非PC机设备。但是,若采用8位、16位单片机,由于速度慢且资源有限,实现TCP/IP协议比较困难,所以也不太理想。   因此本文以ARM核的32位嵌入式微处理器作为硬件平台,结合无线通信技术,通过移植嵌入式操作系统?Clinux,并在其上开发相应的驱动程序、应用程序和嵌入式Web
[模拟电子]
基于<font color='red'>ARM</font>-UClinux的无线家庭网关设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved