一、基础
1、工程结构
USER :代码工程文件。(Project) .uvprojx :是工程文件。 Listings 和 Objects :文件夹是 MDK 自动生成的文件夹,用于存放编译过程产生的中间文件。 CORE : 用来存放核心文件和启动文件。 OBJ :是用来存放编译过程文件以及hex 文件。 STM32F10x_FWLib : 文件夹用来存放 ST 官方提供的库函数源码文件。
组USER 下面存放的主要是用户代码 组HARDWARE 下面存放的是外设驱动代码,他的实现是通过调用 FWLib下面的固件库文件实现的。 组SYSTEM 是 共用代码,包含 Systick 延时函数,IO 口位带操作以及串口相关函数。 组CORE 下面存放的是固件库必须的核心文件和启动文件。 组FWLib 下面存放的是 ST 官方提供的外设驱动固件库文件,这些文件可以根据工程需要来添加和删除。
2、C语言
声明结构体类型:
Struct 结构体名{
成员列表;
}变量名列表;
结构体成员变量的引用方法是:
结构体变量名字.成员名
结构体指针成员变量的引用方法是通过“->”符号实现,
结构体指针成员变量.成员名
3、时钟
APB(Advanced Peripheral Bus),外围总线 Periph ~ Peripheral 外围 当需要使用某模块时,记得一定要先使能对应的时钟。 RCC(Reset Clock Controller) —— 复位与时钟控制
4、中断
NVIC 中断优先级管理 内嵌向量中断控制器:Nested Vectored Interrupt Controller
CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。 STM32 有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级。 STM32F103 系列上面,又只有 60 个可屏蔽中断。
中断寄存器
ISER[8]:Interrupt Set-Enable Registers,中断使能寄存器组。 要 使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、IO 口映射等设置才算是一个完整的中断设置)。
ICER[8]:Interrupt Clear-Enable Registers,是一个中断除能寄存器组。 ISPR[8]:Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。 ICPR[8]:Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。 IABR[8]:Interrupt Active Bit Registers,是一个中断激活标志位寄存器组。 IP[240]:Interrupt Priority Registers,是一个中断优先级控制的寄存器组。
抢占优先级和响应优先级(子优先级) STM32 的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高。 抢占,是指打断其他中断的属性,即因为具有这个属性会出现嵌套中断(在执行中断服务函数A 的过程中被中断B 打断,执行完中断服务函数B 再继续执行中断服务函数A) 而响应属性则应用在抢占属性相同的情况下,当两个中断向量的抢占优先级相同时,如果两个中断同时到达, 则先处理响应优先级高的中断。 configuration 配置 中断优先级设置的步骤: step1: 系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和子优先级的 分配位数。调用函数为 中断优先级分组函数 NVIC_PriorityGroupConfig() ; 函数声明:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
函数调用: 设置整个系统的中断优先级分组值为2,
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
这样就确定了一共为“2 位抢占优先级,2 位响应优先级。
step2: 设置所用到的中断中断优先级别。对每个中断调用函数为 中断初始化函数 NVIC_Init() ;
函数声明:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);s
结构体具体写法见手册126页。
二、GPIO
1、8 种模式
①输入浮空 ②输入上拉 ③输入下拉 ④模拟输入 ⑤开漏输出 ⑥推挽输出 ⑦推挽式复用功能 ⑧开漏复用功能
GPIO_Mode_AIN = 0x0, //模拟输入 GPIO_Mode_IN_FLOATING = 0x04, //浮空输入 GPIO_Mode_IPD = 0x28, //下拉输入 GPIO_Mode_IPU = 0x48, //上拉输入 GPIO_Mode_Out_OD = 0x14, //开漏输出 GPIO_Mode_Out_PP = 0x10, //通用推挽输出 GPIO_Mode_AF_OD = 0x1C, //复用开漏输出 GPIO_Mode_AF_PP = 0x18 //复用推挽
2、操作步骤
step1:使能 IO 口时钟。调用函数为 RCC_APB2PeriphClockCmd()。 ? GPIO 是挂载在APB2总线上的外设,在固件库中对挂载在 APB2 总线上的外设时钟使能是通过函数 RCC_APB2PeriphClockCmd() 来实现的。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);
step2:初始化 IO 参数。调用函数GPIO_Init(); ? 在固件库开发中,通过GPIO初始化函数来配置IO口的模式和速度:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
这个函数有两个参数,第一个参数是用来指定GPIO,取值范围为GPIOA~GPIOG。第二个参数为 初始化参数结构体指针, 通过初始化结构体 来 初始化GPIO 的常用格式是:
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
step3:操作 IO。 ①通过GPIO_ReadInputDataBit 函数操作IDR寄存器 读取IO端口数据:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);
返回值是 1(Bit_SET)或者 0(Bit_RESET);
②通过函数GPIO_SetBits() 和函数GPIO_ResetBits() 来设置GPIO端口输出:
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
GPIO_SetBits(GPIOB, GPIO_Pin_5);
GPIO_ResetBits (GPIOB, GPIO_Pin_5);
3、端口复用
① GPIO 端口时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
②复用的外设时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
③端口模式配置
|