stm32寄存器编程

发布时间 2023-05-26 22:38:06作者: Kael'thas

stm32编程三种方法

  1. 寄存器操作
  2. 标准库
  3. hal库

.1 寄存器操作

为什么要有位操作?因为STM32本身只支持8、16、32位整体操作,而不下支持单独一位操作。但是实际中有对1位单独操作的需求。

一般是这么做的:读取整个的32位,然后对其中一位做操作后,再整体位写回去。

.2位带操作

这么做是可以的,但是效率低。如何改进效率?答案肯定是想一个办法能够直接一次性修改那一位同时还不影响其他位。如果不支持是没办法的,除非硬件给你支持位操作。而ARM又不支持位操作,所以发明位带操作来替代。位带操作的思路是不让你直接单独操作这一位,而是把这一位给你映射到别的某个地方的32位,然后你在别的垃地方操作那个32位就相当是操作这里的这1位。

2.2 时钟

(1)时钟源纯内部、内外部(提供外部晶振)、纯外部(提供外部时钟)

(2)PLL锁相环电路,功能倍频

(3)时钟通道与流向、分频

(4)完全独立的多个时钟

什么是寄存器(control register)?

给具有特殊功能的内存地址起了个名字叫xxx寄存器,这些寄存器可以被过软件编程修改从而控制硬件资源。寄存器起码具备以下功能:输入、输出、存储、清除。

什么是GPIO(general purpose input output )?

GPIO就是芯片的引脚(芯片上的引脚有些不是GPIO,只有一部分是),作为GPIO的这类引脚,他的功能和特点是可以被编程控制它的工作模式,也可以编程控制他的电压高低等。

在开发板上,我们设计电路时就把LED接在了一个GPIO上,这样我们就可以通过编程控制GPIO的模式和输入输出值来操控LED亮还是灭;如果你当时设计电路时把LED接在非GPIO上那就不可能了。

用寄存器编程点亮一颗LED

操作stm32外设使用的一般步骤

第一步、了解该硬件的通用工作原理,再查看具体原理图:

LED硬件通用原理:LED本身有2个接线点,一个是LED的正极,一个是LED的负极。

LED这个硬件的功能:亮或不亮,想要点亮一颗LED只需要给他的正负极上加正电压即可,要熄灭一颗LED只需要去掉电压即可。

image-20230525102732996

第二步、软件件编程:

  1. 使能GPIOB所在时钟:APB2 外设时钟使能寄存器(RCC_APB2ENR)

  2. 设置工作模式设为推挽输出:GPIOx_CRL对应设为0001

  3. 设置GPIOB_ODR点亮LED:GPIOx_ODR给低电平

使能GPIOB所在时钟:

地址:0x40021000+0x18。3号是B时钟。输入1开启时钟。

*(unsigned int*)0x40021018 |=((1)<<3);
image-20230525221134674

image-20230525215715990

image-20230525215813061

设置工作模式设为推挽输出

CRL实际地址为0x40010C00。四位为一组共有八组,PB1指的是CNF1+MODE1,赋值 0001 0000就是给蓝灯设置通用推挽输出。

//设置蓝灯CRL推挽输出,最后一组置0001
*( unsigned int*)0x40010C00|= ((1)<<(4*1));

image-20230525221557885

设置通用

//控制ODR寄存器,配置低电平点亮LED,高电平熄灭LED
*( unsigned int*)0x40010C0C= 0XFFFD;
*( unsigned int*)0x40010C0C= 0XFFFF;

问题1:编译缺少 axf文件,解决:

void SystemInit(){
    //在main.c文件中添加空函数,骗过startup编译器
}

问题2:keil5通过dap仿真烧录到开发板,找不到axf文件

说明编译没通过,否则自动生成axf文件,在Objects文件夹下。

问题3:Flash Download failed - “Cortex-M3“解决方法

image-20230526092744290