第二章 STM32资源介绍
2.1 芯片选型
STM32-F1系列(如图2-1):
基础型,主频为72M(内核为cortex-M3),CPU位数=32。
我们所用的芯片是STM32F103vet6
STM32表示产品的类型,以STM32F103VET6为例
F表示通用系列的子系列
103代表增强型系列
V代表的引脚数100引脚
E代表内嵌flash数6代表32K字节Flash,8代表64K字节Flash,B代表128K字节Flash,C代表256K字节Flash,D代表384K字节Flash,E代表512K字节Flash。
T代表封装其中H代表BGA封装,T代表LQFP封装,U代表VFQFPN封装。
6这一项代表工作温度范围,其中6代表-40——85℃,7代表-40——105℃。
图2-1
APB1总线挂载的外设有:DAC、PWR、BKP、bxCAN、USB、I2C2、I2C1、UART5、UART4、USART3、USART2、SPI3/I2S、SPI2/I2S、IWDG、WWDG、RTC、TIM7、TIM6、TIM5、TIM4、TIM3、TIM2等。
APB2总线挂载的外设有:ADC1、ADC2、ADC3、USART1、SPI1、TIM1、TIM8、GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF、GPIOG、EXT、IAFIO等。
APB1:
DAC:数模转化
PWR:电源功耗控制
BKP:备份数据
BxCAN:CAN总线是一种通信方式。STM32主要负责程序的运行,而CAN总线只是一种通信协议。STM32之间的通信可以通过CAN总线进行数据交换
USB 虚拟接口
I2C 串行通信协议,i2c接口
UART 调试串口
USART通用同步/异步接收器
SPI串行外设接口
IWDG独立看门狗
WWDG 窗口看门狗
RTC实时时钟
TIM 定时器
APB2:
ADC模数转换
GPIO(abcdef)
EXT 外部中断事件控制器
2.2 STM32存储映射
存储器映射是指把芯片中或芯片外的FLASH,RAM,外设,BOOTBLOCK等进行统一编址。即用地址来表示对象。这个地址绝大多数是由厂家规定好的,用户只能用而不能改。用户只能在挂外部RAM或FLASH的情况下可进行自定义。
图2-2
存储器Block0内部区域功能划分
①选项字节:用于配置读写保护、BOR级别、软件/硬件看门狗以及器件处于待机或停止模式下的复位。当芯片不小心被锁住之后,我们可以从RAM 里面启动来修改这部分相应的寄存器位。地址范围为:0x1FFF F800 - 0x1FFF F80F。
②系统存储器:里面存的是ST出厂时烧写好的isp自举程序(即Bootloader),用户无法改动。串口下载的时候需要用到这部分程序。地址范围为:0x1FFF F000- 0x1FFF F7FF。
③FLASH:我们的程序就放在这里。地址范围为:0x0800 0000 ~ 0x0807 FFFF (512KB)。
④取决于BOOT引脚,为FLASH、系统存储器、SRAM的别名。地址范围为:0x0000 0000 ~ 0x0007 FFFF。
⑤其他为预留。
储存器Block1内部区域功能划分
Block1用于设计片内的SRAM。我们使用的STM32F103VET6芯片的 SRAM是64KB,Block1内部区域的功能划分SRAM(64KB)地址范围为:0x2000 0000 ~0x2000 FFFF,其他预留。
内部 SRAM 区的大小是 512MB,用于让芯片制造商连接片上的SRAM,这个区通过系统总线来访问。在这个区的下部,有一个1MB的区间,被称为“位带区”。该位带区还有一个对应的、32MB的“位带别名(alias)区”,容纳了8M个“位变量”(对比8051的只有128个位变量)。位带区对应的是最低的1MB地址范围,而位带别名区里面的每个字对应位带区的一个比特。位带操作只适用于数据访问,不适用于取指。通过位带的功能,可以把多个布尔型数据打包在单一的字中,却依然可以从位带别名区中,像访问普通内存一样地使用它们。
储存器Block2内部区域功能划分:
Block2用于设计片内的外设,根据外设的总线速度不同,Block被分成了 APB(APB1和APB2)和AHB两部分,Block2内部区域功能划分:
①APB1总线外设,地址范围为:0x4000 0000 ~ 0x4000 77FF;
②APB2总线外设,地址范围为:0x4001 0000 ~ 0x4001 3FFF;
③AHB总线外设,地址范围为:0x4001 8000 ~ 0x5003 FFFF;
存储器Block2是片上外设区域,它们以四个字节为一个单元,共32bit,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。
如果直接驱动地址的话会非常麻烦并且不具有通用性。
比如GPIOB端口的输出数据寄存器ODR的地址是0x4001 0C0C,寄存器是32bit,低16bit有效,对应着16个外部 IO,写0/1对应的的IO则输出低/高电平。
2.3 STM32外设地址映射
片上外设区分为三条总线,根据外设速度的不同,不同总线挂载着不同的外设,APB1挂载低速外设,APB2和AHB挂载高速外设。
图2-3
图2-4
图2-5
图2-6
图2-7
寄存器地址 = 基地址 + 偏移地址
GPIOB_CRL = 0x4001 0C 00UL
GPIOB_CRH = 0x4001 0C 04UL
GPIOB_IDR = 0x4001 0C 08UL
GPIOB_ODR = 0x4001 0C 0CUL
GPIOB_BSRR = 0x4001 0C 10UL
GPIOB_BRR = 0x4001 0C 14UL
GPIOB_LCKR = 0x4001 0C 18UL
由此推出
GPIOA_CRL =0x4001 08 00UL
GPIOC_CRL =0x4001 10 00UL
…
c语言最小类型:字节类型,位bit,32bit=4字节
连续存储节省空间
定义的结构体和寄存器大小一一对应,将基地址与结构体绑定,操作结构体相当于操作寄存器
结构体指针用‘->’赋值,普通变量用‘.’赋值,在程序中多用指针寻址,需认真学习
HES外部高速时钟,HSI内部高速时钟
2.4 STM32第一个例程
2.4.1 Cube MX建立工程
图2-8
图2-9
图2-10
图2-11
图2-12
图2-13 配置内部时钟
图2-14
点击右上角:GENERATE CODE生成项目文件
2.4.2程序编写
源码(点亮LED灯,LED1闪烁):
//主程序部分
/* USER CODE BEGIN WHILE */
while (1)
{
Scan_keys();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_4,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_5,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_RESET);
HAL_Delay(500);
}
/* USER CODE END 3 */
注:需要注意代码规范,将代码写在/* USER CODE BEGIN 1 */
/* USER CODE END1 */ 里,否则更改CubeMX时注释块之外的内容会被删除
代码释义:
两个GPIO输出的HAL库函数
1、GPIO电平输出HAL库函数
void HAL_GPIO_WritePin(GPIO_TypeDefGPIOx,unit16_tGPIO_Pin,GPIO_PinState PinState);
三个参数:
GPIOx:目标引脚端口号
GPIO_pin:目标引脚引脚号
PinState:高电平—GPIO_PIN_SET;
低电平—GPIO_PIN_RESET;
2、GPIO电平翻转HAL库函数
void HAL_GPIO_TogglePin(GPIO_TypeDefGPIOx,unit16_tGPIO_Pin);