STM32F103的存储器映射&寄存器映射

存储器映射

存储器空间

Cortex‐M3 支持4GB 存储空间。整块4G存储器开始地址标为0x0000_0000,结束地址为0xFFFF_FFFF,地址的位数是32位,那么2^32=4,294,967,296。

由于一个基本的存储单元是8bits即1Byte(每个地址对应一个存储单元,这样如果只是访问某一bit就要使用位操作,或者使用位带操作),因此4,294,967,296/1024=4,194,304KB,4,194,304/1024=4096MB,4094/1024=4GB。

存储器映射

这4GB的存储空间被划分成8个块,每一块用来与特定功能完成映射。映射关系如图所示。

(个人理解:这4GB的空间指的是地址空间,每个地址对应一个具体的设备。CPU并不知道每个设备是什么,它所关心的只有地址,获取相应的地址,然后找到地址对应的存储单元或者寄存器,进行读取或者写入数据即可。4GB是它最大支持的地址数目,但是实际可能没有使用那么多。)

寄存器映射

每个寄存器都是32bit,占用4个Byte即4个存储单元。可以把寄存器看作一个特殊的单元,一个这样的单元占32bit,只要找到这个单元的起始地址就可以对其进行操作。

其映射地址 = 外设总基地址(块基地址)+ 总线相对于外设总基地址的偏移 + 具体外设基地址相对于总线基地址的偏移 + 寄存器相对于具体外设基地址的偏移。

寄存器操作

直接地址操作访问

以GPIOE_ODR寄存器为例:

查芯片手册知:ODR寄存器地址相对于GPIOE起始地址的偏移为:0Ch

因此:

GPIOE_ODR = GPIOE_BASE+0x0C

GPIOE_BASE = APB2PERIPH_BASE + 0x1800

APB2PERIPH_BASE = PERIPH_BASE + 0x10000

PERIPH_BASE = 0x40000000

所以:

GPIOE_ODR = 0x4001180C(寄存器的起始地址)

/*****直接地址操作,改变寄存器的值****/
*(unsigned int *)(0x4001180C)&= 0x00;    //初始化port5赋值为1,要拉低电平使用&操作
delay_ms(300);
*(unsigned int *)(0x4001180C)|= 0x20;
delay_ms(300);

通过对GPIOE_ODR的操作,用GpioE_port5实现流水灯。

程序中映射访问

在stm32f10x.h中定义了地址映射

外设基地址PERIPH_BASE

#define PERIPH_BASE           ((uint32_t)0x40000000)

总线基地址,在外设基地址上加上偏移:

#define APB1PERIPH_BASE       PERIPH_BASE
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)

GPIO外设基地址,在APB2总线基地址上加上偏移:

#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外设结构体,因为结构体成员在内存中是连续的,这种形式与寄存器组非常类似,所以用结构体能够很好的管理寄存器:

typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef;

 #define     __IO    volatile

这个宏定义将结构体里的变量声明为寄存器变量,保证这些寄存器的值能够在程序运行中随时被读写。

定义GPIOA结构体指针,因为单单定义GPIO外设结构体,并不能确定其内存地址,因此用指针将其绑定到GPIOA外设基地址:

#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
/*****映射访问****/
GPIOE->ODR=0<<5;
delay_ms(300);
GPIOE->ODR=1<<5;

 

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
STM32F103ZET6是STMicroelectronics(意法半导体)推出的一款高性能的32位ARM Cortex-M3内核微控制器。DDS是指直接数字频率合成器(Direct Digital Synthesis),是一种通过数字方式生成高精度、高稳定度的频率信号的技术。 为了驱动STM32F103ZET6实现DDS功能,首先需要了解该芯片的硬件资源和寄存器配置。 在STM32F103ZET6中,主要用到的硬件资源包括定时器(Timers)和数字模拟转换器(DAC)。定时器用于产生时钟信号,DAC用于输出频率合成后的模拟信号。 首先,需要配置定时器,选择合适的时钟源和频率分频系数,以及定时器的工作模式和计数器值。然后,配置DAC,选择合适的引脚和输出模式,设置DAC的数据对齐方式和数据大小等参数。通过设置定时器和DAC的参数,可以实现相应的DDS功能。 接下来,需要编写相应的程序代码,通过控制寄存器设置生成的频率,可以通过修改周期寄存器(Period Register)或比较寄存器(Compare Register)的值来调整频率的输出。 在程序中,还需要根据具体的需求编写相应的控制逻辑,如选择不同的波形类型(正弦、方波、三角波等)、设置幅度和相位等参数。 最后,将程序烧录到STM32F103ZET6的Flash存储器中,通过调试工具或外设进行调试和测试,确保DDS功能正常。 需要注意的是,在编写程序代码时,需要熟悉STM32F103ZET6的寄存器映射和编程接口,可以参考STMicroelectronics提供的官方文档和开发工具。 综上所述,STM32F103ZET6的DDS驱动需要配置定时器和DAC,编写程序代码进行频率设置和控制逻辑编写,并进行调试和测试,以实现DDS功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值