STM32F103寄存器方式点亮LED流水灯
1.STM32F103系列芯片的地址映射和寄存器映射原理
2.GPIO端口
3.以 STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED 搭建电路,使用GPIOB、GPIOC、GPIOD这3个端口控制LED灯,轮流闪烁,间隔时长1秒。
4.总结
1.STM32F103系列芯片的地址映射和寄存器映射原理
1.1stm32 从字面意义来看:ST:意法半导体,是一个公司的名字。 M:Microelectronics的缩写,表示微控制器 32:32bit的意思,表示这是一个32bit的微控制器。 STM32 属于一个微控制器,适用于控制类,自带了各种常用通信接口,比如 USART、 I2C、 SPI 等,可接非常多的传感器,可以控制很多的设备。现实生活中,我们接触到的很多电器产品都有 STM32 的身影,比如智能手环,微型四轴飞行器,平衡车、移动POS机,智能电饭锅,3D 打印机等等。 stm32是意法半导体(ST)集团生产的。意法半导体(ST)集团于1988年6月成立,是由意大利的SGS微电子公司和法国Thomson半导体公司合并而成。1998年5月,SGS-THOMSON Microelectronics将公司名称改为意法半导体有限公司,是世界最大的半导体公司之一。推出的STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex?-M0,M0+,M3, M4和M7内核。其实一个芯片是由内核和外设构成的,ST公司是造芯片的,但用的是ARM公司的内核再加上自己的外设构成一个完整的STM芯片,所以用ST命名。 STM32F系列属于中低端的32位ARM微控制器,该系列芯片是意法半导体(ST)公司出品,其内核是Cortex-M3[^1]。 该系列芯片按片内Flash的大小可分为三大类:小容量(16K和32K)、中容量(64K和128K)、大容量(256K、384K和512K)。 芯片集成定时器Timer,CAN,ADC,SPI,I2C,USB,UART等多种外设功能。 1.2寄存器 (1)寄存器:寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。其实寄存器就是一种常用的时序逻辑电路,但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个锁存器或触发器可以构成N位寄存器。寄存器是中央处理器内的组成部分。寄存器是有限存储容量的高速存储部件,它们可用来暂存指令、数据和位址。 (2)寄存器的功能 寄存器最起码具备以下4种功能。 ①清除数码:将寄存器里的原有数码清除。 ②接收数码:在接收脉冲作用下,将外输入数码存入寄存器中。 ③存储数码:在没有新的写入脉冲来之前,寄存器能保存原有数码不变。 ④输出数码:在输出脉冲作用下,才通过电路输出数码。 仅具有以上功能的寄存器称为数码寄存器;有的寄存器还具有移位功能,称为移位寄存器。 1.3地址映射和寄存器映射原理 以STM32为例,操作硬件本质上就是操作寄存器。在存储器片上外设区域,四字节为一个单元,每个单元对应不同的功能。当我们控制这些单元时就可以驱动外设工作,我们可以找到每个单元的起始地址,然后通过C 语言指针的操作方式来访问这些单元。但若每次都是通过这种方式访问地址,不好记忆且易出错。这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名实质上就是寄存器名字。给已分配好地址(通过存储器映射实现)的有特定功能的内存单元取别名的过程就叫寄存器映射。
2.GPIO端口
2.1GPIO的工作模式 (1)GPIO_Mode_AIN 模拟输入 (应用ADC模拟输入,或者低功耗下省电) (2)GPIO_Mode_IN_FLOATING 浮空输入 (浮空就是浮在半空,可以被其他物体拉上或者拉下,可以用于按键输入) (3)GPIO_Mode_IPD 下拉输入 (IO内部下拉电阻输入) (4)GPIO_Mode_IPU 上拉输入 (IO内部上拉电阻输入) (5)GPIO_Mode_Out_OD 开漏输出(开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行) (6)GPIO_Mode_Out_PP 推挽输出 (推挽就是有推有拉电平都是确定的,不需要上拉和下拉,IO输出0-接GND, IO输出1 -接VCC,读输入值是未知的 ) (7)GPIO_Mode_AF_OD 复用开漏输出(片内外设功能(I2C的SCL,SDA)) (8)GPIO_Mode_AF_PP 复用推挽输出 (片内外设功能(TX1,MOSI,MISO.SCK.SS))
2.2GPIO端口初始化 GPIO端口的初始化设置三步骤 (时钟配置、输入输出模式设置、最大速率设置)
对于多个GPIO口的初始化如下: GPIO_InitTypeDef GPIO_InitStructure;
第一步:使能GPIOA,GPIOE的时钟: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); 第二步:设置GPIOA,GPIOE参数:输出OR输入,工作模式,端口翻转速率 第三步:调用GPIOA口初始化函数,进行初始化。 第四步:调用GPIO-SetBits函数,进行相应为的置位。 ?把第二、三、四步合并分别设置GPIOA和GPIOE 先设置GPIOA GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // 第四个口,PA4 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz GPIO_Init(GPIOA,&GPIO-InitST); //根据设定参数初始化GPIOA GPIO_SetBits(GPIOA,GPIO_Pin_4); //输出高
再设置GPIOE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // 第三个口,PE3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz GPIO_Init(GPIOE,&GPIO-InitST); //根据设定参数初始化GPIOE GPIO_SetBits(GPIOE,GPIO_Pin_3); //输出高
3.以 STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED 搭建电路,使用GPIOB、GPIOC、GPIOD这3个端口控制LED灯,轮流闪烁,间隔时长1秒。
3.1创立工程文件,编写代码后编译生成hex文件 3.2代码 led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 BIT_ADDR(GPIOB_ODR_Addr,6)
#define LED1 BIT_ADDR(GPIOC_ODR_Addr,6)
#define LED2 BIT_ADDR(GPIOD_ODR_Addr,2)
void LED_Init(void);
#endif
led.c
#include "sys.h"
#include "led.h"
void LED_Init(void)
{
RCC->APB2ENR|=1<<3;
RCC->APB2ENR|=1<<4;
RCC->APB2ENR|=1<<5;
GPIOB->CRL&=0XF0FFFFFF;
GPIOB->CRL|=0X03000000;
GPIOB->ODR|=1<<6;
GPIOC->CRL&=0XF0FFFFFF;
GPIOC->CRL|=0X03000000;
GPIOC->ODR|=1<<6;
GPIOD->CRL&=0XFFFFF0FF;
GPIOD->CRL|=0X00000300;
GPIOD->ODR|=1<<2;
}
test.c
#include "sys.h"
#include "led.h"
void delay(unsigned int i)
{
unsigned char j;
unsigned char k;
for(;i>0;i--)
for(j=500; j>0; j--)
for(k =200; k>0; k--);
}
int main(void)
{
LED_Init();
while(1)
{
LED0=0;
LED1=1;
LED2=1;
delay(20);
LED0=1;
LED1=0;
LED2=1;
delay(20);
LED0=1;
LED1=1;
LED2=0;
delay(20);
}
}
3.3程序烧制结果 3.4汇编语言
AREA MYDATA, DATA
AREA MYCODE, CODE
ENTRY
EXPORT led
led
;使能A,B,C
ldr r0, =0x40021018
ldr r1, =0x0000001c
str r1, [r0]
;配置端口A4
ldr r0, =0x40010800
ldr r1, [r0]
bic r1, r1, #0x000f0000
orr r1, r1, #0x00010000
str r1, [r0]
;配置端口B5
ldr r0, =0x40010c00
ldr r1, [r0]
bic r1, r1, #0x00f00000
orr r1, r1, #0x00100000
str r1, [r0]
;配置端口C14
ldr r0, =0x40011004
ldr r1, [r0]
bic r1, r1, #0x0f000000
orr r1, r1, #0x01000000
str r1, [r0]
;初始为A4亮灯
ldr r0, =0x4001080c
ldr r1, =0x00000010
str r1, [r0]
ldr r0, =5000000;频率
ldr r1, =0
;循环亮灯
blink
add r1, r1, #1
cmp r1, r0
blt blink
;A4灭
ldr r1, =0x4001080c
ldr r2, [r1]
eor r2, r2, #0x00000010
str r2, [r1]
;B5亮
ldr r1, =0x40010c0c
ldr r2, [r1]
eor r2, r2, #0x00000020
str r2, [r1]
ldr r1, =0
blink1
add r1, r1, #1
cmp r1, r0
blt blink1
;B5灭
ldr r1, =0x40010c0c
ldr r2, [r1]
eor r2, r2, #0x00000020
str r2, [r1]
;C14亮
ldr r1, =0x4001100c
ldr r2, [r1]
eor r2, r2, #0x00004000
str r2, [r1]
ldr r1, =0
blink2
add r1, r1, #1
cmp r1, r0
blt blink2
;C14灭
ldr r1, =0x4001100c
ldr r2, [r1]
eor r2, r2, #0x00004000
str r2, [r1]
;A4亮
ldr r1, =0x4001080c
ldr r2, [r1]
eor r2, r2, #0x00000010
str r2, [r1]
ldr r1, =0
b blink
END
4.总结
这周的作业我花费了许多时间,但是也学到了非常多的知识,对于寄存器有了更为深刻的理解
|