赞
踩
STM32微控制器上集成了多种硬件设备和外设,这些设备和外设可用于各种不同的应用。以下是一些常见的STM32微控制器上可能集成的设备和外设:
以STM32F103VET6举例:
在STM32微控制器中,寄存器是一种特殊的内存单元,用于控制和配置微控制器的各种硬件功能和外设。这些寄存器的值直接影响微控制器的行为和性能。在编程中,开发人员可以通过读取和写入这些寄存器来配置和控制微控制器的各种功能。寄存器定义通常在STM32的设备头文件中,这些头文件由厂家提供,包含了各种寄存器的地址和位字段定义。
STM32芯片从宏观上看主要包括内核(Cortex-M3,ARM公司设计)和总线矩阵(FLASH、SRAM、外设,ST公司设计)两部分。
系统框图可以在《STM32参考手册》 - 《2存储器和总线架构 》- 《2.1 系统架构》中查看。
以下为STM32F10XX系统框图。
假设我们CPU要读取一个变量(在SRAM中),传输到一个内部的外设:
情况1:如果不使用DMA总线,CPU首先要通过Dcode总线把数据从SRAM读取到CPU的通用寄存器中,CPU再把数据传到内部的外设。
情况2:如果使用DMA总线,CPU只需要发送一个命令,将SRAM中的数据通过DMA总线搬到内部的外设。这样CPU就空闲了,可以进行其他的操作。
存储器映射:存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射。
存储器映射图可以在《STM32F103xCDE_数据手册-英文》 - 《4-memory mapping》中查看。
// 现在我们要让GPIOB端口的16个引脚输出高电平
// 方法1:通过决定地址访问内存单元
* (unsigned int*)(0X40010C0C) = 0XFFFF;
// 方法2:通过寄存器别名方式访问内存单元
#define GPIOB_ODR *(unsigned int*)(0X40010C0C)
GPIOB_ODR = 0XFFFF;
1.在《STM32F10X 参考手册》中 找到GPIOB的初始地址0X40010C00(可以在2.3存储器映像中找,也可以在8.2GPIO寄存器描述中找)。
2.寻找ODR的地址偏移量0Ch(8.2.4 端口配置高寄存器(GPIOx_ODR)中找到地址偏移)。
寄存器映射:给已经分配好地址的有特定功能的内存单元取别名的过程。
/* 外设基地址 */ #define PERIPH_BASE ((unsigned int)0x40000000) /* 总线基地址 */ #define APB1PERIPH_BASE PERIPH_BASE #define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000) /* GPIO外设基地址 */ #define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) #define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) #define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) #define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) #define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00) #define GPIOG_BASE (APB2PERIPH_BASE + 0x2000) /* 寄存器基地址,以GPIO为例 */ #define GPIOB_CRL (GPIOB_BASE+0x00) #define GPIOB_CRH (GPIOB_BASE+0x04) #define GPIOB_IDR (GPIOB_BASE+0x08) #define GPIOB_ODR (GPIOB_BASE+0x0C) #define GPIOB_BSRR (GPIOB_BASE+0x10) #define GPIOB_BRR (GPIOB_BASE+0x14) #define GPIOB_LCKR (GPIOB_BASE+0x18)
typedef unsigned int uint32_t; /* 无符号32位变量 */ typedef unsigned short int uint16_t; /* 无符号16位变量 */ /* GPIO寄存器列表 */ typedef struct { uint32_t CRL; /* GPIO端口配置低寄存器 地址偏移:0x00 */ uint32_t ORH; /* GPIO端口配置高寄存器 地址偏移:0x04 */ uint32_t IDR; /* GPIO数据输入寄存器 地址偏移:0x08 */ uint32_t ODR; /* GPIO数据输出寄存器 地址偏移:0x0C */ uint32_t BSRR; /* GPIO位设置/清除寄存器 地址偏移:0x10 */ uint32_t BRR; /* GPIO端口位清除寄存器 地址偏移:0x14 */ uint32_t LCKR; /* GPIO端口配置锁定寄存器 地址偏移:0x18 */ } GPIO_TypeDef; GPIO_TypeDef * GPIOx; // 定义一个GPIO_TypeDef型结构体指针 GPIOx = GPIOB_BASE; // 将指针地址设置为宏GPIO_BASE地址 GPIOx->IDR = 0XFFFF; uint32_t temp = GPIOx->IDR; // 读取GPIOB_IDR寄存器的值到变量temp中
/* 使用GPIO_TypeDef把地址强制转换成指针 */
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
/* 使用定义好的宏直接访问 */
GPIOB->BSRR = 0XFFFF;
uint32_t temp = GPIOB->IDR;
让PB0输出高/低电平
#define PERIPH_BASE ((unsigned int)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOB_ODR *(unsignedint*)(GPIOB_BASE+0x0C)
// PB0输出低电平
GPIOB_ODR &= ~(1<<0); // ~:取反;先 << ,再 ~ ,再 &= 。
// PB0输出高电平
GPIOB_ODR |= (1<<0);
// PB0取反
GPIOB_ODR ^= (1<<0);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。