这个文档用来记录一些STM32的小知识,大都是我觉得有必要记下来,免得久了没接触会忘掉的知识。
配置一个外设常用的步骤
GPIO配置
找到其使用到的GPIO口,按照要使用的模式(可以查中文参考手册)设置GPIO口。
外设初始化的配置
以定时器为例,跟外设相关的初始化配置就是时基配置。
外设中断配置(可选)
如果要用到中断,就必须要把这里配置好。
各种使能函数千万不能忘
GPIO口时钟使能;
外设时钟使能(有重映射和外部中断还要使能复用功能时钟);
上面两个一般是开头就要写的
外设使能、外设中断使能(可选);
感觉这些对象需要使能:
外设的时钟(好给外设提供时钟频率吧)、外设自身、外设的中断等。
可以直接在固件库里面找代码模板
举例说明一下:
我现在想使用PWM输出波形,那么我可以到下面的文件路径去找官方提供的固件库中关于PWM输出的例子:
\STM32F10x_StdPeriph_Lib_V3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\TIM\PWM_Output

用static修饰的变量、函数
static的翻译是“静态的”,它是C语言链接属性的一种。
链接属性有三种static、external、none
全局变量(默认是external链接类型)用它修饰后,变量的作用域就被限制在那个源文件下,
函数也是一样。
一般用这个修饰一下,就是说这个对象只是我这个文件要用的,你其他地方的就别来调用了。
用static修饰变量可以在每次要用到它时,它里面还保留了上一次的值。有的地方是必要的,不然每次进入后都是一个全新的值就会出问题。
对了,变量分为局部变量(存放在堆栈中,函数用完后就销毁),全局变量(存放在内存中,程序使用完后才销毁),寄存器变量。
库函数中的位指示宏与位屏蔽宏
先来看看这两种宏像什么样子:
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
这里有两个寄存器的宏控制,SysTick控制寄存器与SysTick重装载寄存器。两个寄存器的控制信息如下:

从上面的宏定义代码以及下面寄存器位控制的图可知,对某项控制:
xxx_Pos 给出了它在寄存器中所占位段的第一个位置
xxx_Mask 给出了它所占的位数,每一位都是置1的,有多少个1就占多少位
以CLKSOURCE与RELOAD为例
#define SysTick_CTRL_CLKSOURCE_Pos 2
#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos)
#define SysTick_LOAD_RELOAD_Pos 0
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)
从这里就能看出CLKSOURCE是从寄存器的第2位开始的,然后只占了1位;
而RELOAD是从寄存器第0位开始,然后占了24个位。
注:1ul实际上就是1,说明类型是unsigned long,0xFFFFFFul也是这个意思。可能在其他地方还能闻到uc(unsigned char)和us(unsigned short),这种声明的方法好像是叫匈牙利命名法,了解一下吧。