零死角玩转STM32---阅读摘记一

一、时钟相关

从时钟树的分析,看到经过一系列的倍频、分频后得到了几个与我们开发密切相关的时钟。

SYSCLK:系统时钟,STM32大部分器件的时钟来源。主要由AHB预分频器分配到各个部件。

HCLK:由AHB预分频器直接输出得到,它是高速总线AHB的时钟信号,提供给存储器,DMA及cortex内核,是cortex内核运行的时钟,cpu主频就是这个信号,它的大小与STM32运算速度,数据存取速度密切相关。

FCLK:同样由AHB预分频器输出得到,是内核的“自由运行时钟”。“自由”表现在它不来自时钟 HCLK,因此在HCLK时钟停止时 FCLK 也继续运行。它的存在,可以保证在处理器休眠时,也能够采样和到中断和跟踪休眠事件 ,它与HCLK互相同步。

PCLK1:外设时钟,由APB1预分频器输出得到,最大频率为36MHz,提供给挂载在APB1总线上的外设。

PCLK2:外设时钟,由APB2预分频器输出得到,最大频率可为72MHz,提供给挂载在APB2总线上的外设。

为什么STM32的时钟系统如此复杂,有倍频、分频及一系列的外设时钟的开关。需要倍频是考虑到电磁兼容性,如外部直接提供一个72MHz的晶振,太高的振荡频率可能会给制作电路板带来一定的难度。分频是因为STM32既有高速外设又有低速外设,各种外设的工作频率不尽相同,如同pc机上的南北桥,把高速的和低速的设备分开来管理。最后,每个外设都配备了外设时钟的开关,当我们不使用某个外设时,可以把这个外设时钟关闭,从而降低STM32的整体功耗。所以,当我们使用外设时,一定要记得开启外设的时钟啊,亲。


注意:3.5版本的库在启动文件中调用了SystemInit(),所以不必在main()函数中再次调用。但如果使用的是3.0版本的库则必须在main函数中调用SystemInit(),以设置系统时钟,因为在3.0版本的启动代码中并没有调用SystemInit()函数。(具体可以参考启动代码)


如果我们用到了I/O的引脚复用功能,还要开启其复用功能时钟。

如GPIOC的Pin4还可以作为ADC1的输入引脚,现在我们把它作为ADC1来使用,除了开启GPIOC时钟外,还要开启ADC1的时钟:

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);

RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE);

/*

LED.H

*/

#ifndef __LED_H

#define __LED_H

#include "stm32f10x.h"

/* the macro definition to trigger the led on or off

* 1 - off

- 0 - on

*/

#define ON  0

#define OFF 1

//带参宏,可以像内联函数一样使用

#define LED1(a) if (a)  \

GPIO_SetBits(GPIOC,GPIO_Pin_3);\

else        \

GPIO_ResetBits(GPIOC,GPIO_Pin_3)

#define LED2(a) if (a)  \

GPIO_SetBits(GPIOC,GPIO_Pin_4);\

else        \

GPIO_ResetBits(GPIOC,GPIO_Pin_4)

#define LED3(a) if (a)  \

GPIO_SetBits(GPIOC,GPIO_Pin_5);\

else        \

GPIO_ResetBits(GPIOC,GPIO_Pin_5)

void LED_GPIO_Config(void);

#endif /* __LED_H */


这个头文件(led.h)的内容不多,但也把它独立成一个头文件,方便以后扩展或移植使用。希望读者养成良好的工程习惯,在写头文件的时候,加上类似以下这样的条件编译。

#ifndef __LED_H

#define __LED_H

……

#endif

这样可以防止头文件重复包含,使得工程的兼容性更好。读者问为什么要加两个下划线”__” ?在这里加两个下划线可以避免这个宏标识符与其它定义重名,因为在其它部分代码定义的宏或变量,一般都不会出现这样有下划线的名字。


规范的位操作方法

由于库函数的实现涉及到不少位操作,首先为读者介绍一下几个常用的位操作方法,排除阅读代码的障碍。

1、将char型变量a的第七位(bit6)清0,其它位不变。

a &= ~(1<<6);   //括号内1左移6位,得二进制数:0100 0000

//按位取反,得1011 1111 ,所得的数与a作”位与&”运算,

// a的第7位(bit6)被置零,而其它位不变。

2、同理,将变量a的第七位(bit6)置1,其它位不变的方法如下。

a |= (1<<6);        //把第七位(bit6)置1,其它为不变

3、将变量a的第七位(bit6)取反,其它位不变。

a ^=(1<<6);   //把第七位(bit6)取反,其它位不变  (  ^ 为抑或符号)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值