历史上的今天
今天是:2024年10月15日(星期二)
2018年10月15日 | STM32时钟使能函数
2018-10-15 来源:eefocus
最近在学习STM32单片机,之所以选择这款单片机作为入门原因有以下几点:
1. 配套资料详细
2. 工作中正在用这款单片机,有疑问可以请教同事,熟悉了这款单片机能更好服务于工作
3. ST单片机非常火爆,很多公司都在用
对于单片机小白的我,想要学好一款单片机,不仅仅是一时的冲动,凭借的更是长期的毅力和兴趣,这点觉悟必须具备。为什么要写博文呢?因为怕忘记,有时候花很长时间琢磨的函数,再见面只有相见无言唯有泪千行!!!所以做笔记尤其重要啊!!!
使用一个外设时,必须先使能它的时钟,这些时钟函数可大致分为三类:一)外设时钟使能函数 二)时钟源和倍频因子配置函数 三)外设复位函数
外设时钟使能函数又包括外设时钟使能和时钟源使能,因为外设是挂在AHB和APB总线上的,所以使能外设时钟就是使能对应外设所挂的总线时钟,比如GPIO 外设它是挂接在APB2 总线上的,如果使用GPIO 外设,就需要先调用 RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);函数使能APB2时钟,外设时钟使能函数有两个形参,第一个是你所使用的外设所挂接的时钟,第二个是选择你用的外设时钟使能还是失能。比如我们要使能端口GPIOC,那么第一个传递的参数是:RCC_APB2Periph_GPIOC 宏,第二个传递的参数是ENABLE 使能。下面为具体函数:
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
{
assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
RCC->APB2ENR |= RCC_APB2Periph;
}
else
{
RCC->APB2ENR &= ~RCC_APB2Periph;
}
}
首先来看下这个函数assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));这是个断言函数,意思就是如果外设是挂在APB2总线上的,程序就继续执行,如果不是则做其它处理。
再来看下IS_RCC_APB2_PERIPH(RCC_APB2Periph)这个宏,具体如下:
#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFC00002) == 0x00) && ((PERIPH) != 0x00))
其实这个宏的目的就是识别APB2的外设,那为什么是0xFFC00002呢?来看下APB2总线上的所有外设时钟是如何定义的
#define RCC_APB2Periph_AFIO ((uint32_t)0x00000001)
#define RCC_APB2Periph_GPIOA ((uint32_t)0x00000004)
#define RCC_APB2Periph_GPIOB ((uint32_t)0x00000008)
#define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010)
#define RCC_APB2Periph_GPIOD ((uint32_t)0x00000020)
#define RCC_APB2Periph_GPIOE ((uint32_t)0x00000040)
#define RCC_APB2Periph_GPIOF ((uint32_t)0x00000080)
#define RCC_APB2Periph_GPIOG ((uint32_t)0x00000100)
#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000200)
#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000400)
#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000800)
#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000)
#define RCC_APB2Periph_TIM8 ((uint32_t)0x00002000)
#define RCC_APB2Periph_USART1 ((uint32_t)0x00004000)
#define RCC_APB2Periph_ADC3 ((uint32_t)0x00008000)
#define RCC_APB2Periph_TIM15 ((uint32_t)0x00010000)
#define RCC_APB2Periph_TIM16 ((uint32_t)0x00020000)
#define RCC_APB2Periph_TIM17 ((uint32_t)0x00040000)
#define RCC_APB2Periph_TIM9 ((uint32_t)0x00080000)
#define RCC_APB2Periph_TIM10 ((uint32_t)0x00100000)
#define RCC_APB2Periph_TIM11 ((uint32_t)0x00200000)
以RCC_APB2Periph_GPIOC为例,想要使能RCC_APB2Periph_GPIOC的时钟,就要将RCC->APB2ENR 寄存器的相应位置1,即bit4=1,所以RCC_APB2Periph_GPIOC= (uint32_t)0x00000010,其它以此类推,如果使能APB2总线上的所有外设时钟那么 RCC->APB2ENR=0x003FFFFD,取反就是0xFFC00002
最后是,使能外设时钟的具体操作
if (NewState != DISABLE)
{
RCC->APB2ENR |= RCC_APB2Periph;//将APB2ENR寄存器中相应的外设时钟使能位置1
}
else
{
RCC->APB2ENR &= ~RCC_APB2Periph;//APB2ENR寄存器中相应的外设时钟使能位为置0,其它位保持不变
}

史海拾趣
|
大家好啊,在这转悠了好几天,发现大家都是高手!我是一名专升本的学生,专科没有学过单片机本科学校因为大部分人都学过所以也就没开这门课,现在要做有关单片机的毕业设计,想请大家帮帮忙,谢谢了! 昨天问了一下老师那个设计一共 ...… 查看全部问答> |
|
如何将SMDK2440变成多个版本?例如我的产品210,对应的BSP是smdk2440210,产品220对应的是smdk2440220 本人菜鸟,现在碰到一个问题,希望向大家求助一下. 现在我的wince目录中的PLATFORM只有smdk2440一个bsp,这样产生了很多不方便的地方. 第一,目前有3个系列的产品,虽然都是基于2440的,但是在BSP上,还是有些地方是不同的,要维护这三个系列的产品.虽然 ...… 查看全部问答> |
|
ARM D/A转换程序设计 1.编程实现多种波形(正弦波信号、三角波信号、方波信号)的输出,在 DA接口利用示波器观测实验输出。 2.在 LCD上显示信号… 查看全部问答> |
|
请假,利用AVR实现与液晶屏的访问,如果采用直接访问(给液晶屏分配一个地址空间),直接接到对应的地址和数据线上,对应的RD和WR信号分别接到AVR的RD和WR上。但是如果采用间接访问的话,液晶屏幕的RD和WR信号是不是一般不能接在对应AVR的RD和WR信 ...… 查看全部问答> |




