一、实验目的
使用寄存器编程实现点亮小灯D1、D2、D3、D4。
二、实验仪器
电脑系统:Intel(R) Core(TM) i5-10500 CPU @ 3.10GHz 3.10 GHz
嵌入式开发板:FM-STM32-F407A
三、实验框图(电路图/流程图)
(1)LED灯原理:
LED0给它一个低电平0,灯就可以亮
LED0给它一个高电平1,灯就会灭
D1-PF9 D2-PF10 D3-PE13 D4-PE14
(2)GPIO引脚:
GPIO寄存器包括GPIOx_MODER(模式)、GPIOx_OTYPER(输出类型)、GPIOx_OSPEEDR( 输出速率)和GPIOx_PUPDR(上拉下拉)、GPIOx_IDR(输入数据寄存器)、GPIOx_ODR(输出数据寄存器)、GPIOx_BSRR (复位寄存器)。
将灯的引脚接入到MCU的某个引脚(GPIO)上去,就可以通过控制MCU上的GPIO来控制灯亮。
输出类型:GPIO 引脚从芯片内部引出一根功能复用的线(电线),可以配置成不同的功能,如:输入功能,输出功能,复用功能等。
输出类型:GPIO引脚配置成输出模式时,在推挽方式PP下,CPU可以往该寄存器写0引脚输出低电平,写1引脚输出是高电平。在开漏模式OD下,0 是引脚内部接地,1 是引脚内部悬空,状态由外部电路决定。
四、实验基本原理(原理/源程序)
(1)led_test.h 中定义宏
#ifndef _LED_H_
#define _LED_H_
#define rRCCAHB1CLKEN *((volatile unsigned long *)0x40023830)
#define GPIOE_BASE_ADDR 0x40021000
#define GPIOF_BASE_ADDR 0x40021400
#define MODER_OFFSET_ADDR 0x00
#define OTYPER_OFFSET_ADDR 0x04
#define OSPEEDR_OFFSET_ADDR 0x08
#define PUPDR_OFFSET_ADDR 0x0C
#define ODR_OFFSET_ADDR 0x14
#define BSRR_OFFSET_ADDR 0x18
GPIOF
#define rGPIOF_MODER (*(volatile unsigned long*)(GPIOF_BASE_ADDR+MODER_OFFSET_ADDR))
#define rGPIOF_OTYPER (*(volatile unsigned long*)(GPIOF_BASE_ADDR+OTYPER_OFFSET_ADDR))
#define rGPIOF_OSPEEDR (*(volatile unsigned long*)(GPIOF_BASE_ADDR+OSPEEDR_OFFSET_ADDR))
#define rGPIOF_PUPDR (*(volatile unsigned long*)(GPIOF_BASE_ADDR+PUPDR_OFFSET_ADDR))
#define rGPIOF_ODR (*(volatile unsigned long*)(GPIOF_BASE_ADDR+ODR_OFFSET_ADDR))
#define rGPIOF_BSRR (*(volatile unsigned long*)(GPIOF_BASE_ADDR+BSRR_OFFSET_ADDR))
GPIOE
#define rGPIOE_MODER (*(volatile unsigned long*)(GPIOE_BASE_ADDR+MODER_OFFSET_ADDR))
#define rGPIOE_OTYPER (*(volatile unsigned long*)(GPIOE_BASE_ADDR+OTYPER_OFFSET_ADDR))
#define rGPIOE_OSPEEDR (*(volatile unsigned long*)(GPIOE_BASE_ADDR+OSPEEDR_OFFSET_ADDR))
#define rGPIOE_PUPDR (*(volatile unsigned long*)(GPIOE_BASE_ADDR+PUPDR_OFFSET_ADDR))
#define rGPIOE_ODR (*(volatile unsigned long*)(GPIOE_BASE_ADDR+ODR_OFFSET_ADDR))
#define rGPIOE_BSRR (*(volatile unsigned long*)(GPIOE_BASE_ADDR+BSRR_OFFSET_ADDR))
void led_init(void); //灯的初始化
#endif
(2) led_test.c
#include "led_test.h"
void led_init(void){
// D1-PF9 D2-PF10 D3-PE13 D4-PE14
unsigned long r_value;
// MODER-01 OUTTYPER-PP-0 OSPEEDR-50M-10 NOUPDR-00 ODR-0
// GPIOE GPIOF
// rRCCAHB1CLKEN[4]--GPIOE rRCCAHB1CLKEN[5]--GPIOF
rRCCAHB1CLKEN |= (1<<4)|(1<<5);
模式 输出 01
// PF9 PF10-[21,18]- 0101 -rGPIOF_ MODER
r_value =rGPIOF_MODER;
r_value &=~(0xf<<18);
r_value |=(1<<18)|(1<<20);
rGPIOF_MODER=r_value;
// PE13 PE14-[29,26}-0101-rGPIOE_MODER
r_value =rGPIOE_MODER;
r_value &=~(0xf<<26);
r_value |=(0x1<<26)|(0x1<<28);
rGPIOE_MODER =r_value;
输出类型 PP推挽 0
// PF9 PF10-[10,9]-00-rGPIOF_OTYPER
r_value =rGPIOF_OTYPER;
r_value &=~(0x3<<9);
rGPIOF_OTYPER =r_value;
// PE13 PE14-[14,13]-00-rGPIOF_OTYPER
r_value =rGPIOE_OTYPER;
r_value &=~(0x3<<13);
rGPIOE_OTYPER =r_value;
输出速率 50MHZ 10
// PF9 PF10-[21,18]-1010-rGPIOF_OSPEEDR
r_value =rGPIOF_OSPEEDR;
r_value &=~(0xf<<18);
r_value |=(1<<19)|(1<<21);
rGPIOF_OSPEEDR=r_value;
// PE13 PE14-[2926-1010-rGPIOF_OSPEEDR
r_value =rGPIOE_OSPEEDR;
r_value &=~(0xf<<26);
r_value |=(1<<27)|(1<<29);
rGPIOE_OSPEEDR =r_value;
无上拉下拉 00
// PF9 PF10-[21,18]-0000-rGPIOF_PUPDR
r_value =rGPIOF_PUPDR;
r_value &=~(0xf<<18);
rGPIOF_PUPDR=r_value;
// PE13 PE14-[29,26]-0000-rGPIOF_PUPDR
r_value =rGPIOE_PUPDR;
r_value &=~(0xf<<26);
rGPIOE_PUPDR =r_value;
// PF9 PF10-[10,9]-00-rGPIOF_ODR 低电平0灯亮
r_value =rGPIOF_ODR;
r_value &=~(0x3<<9);
rGPIOF_ODR =r_value;
// PE13 PE14-[14,13]-00-rGPIOF_ODR 低电平0灯亮
r_value =rGPIOE_ODR;
r_value &=~(0x3<<13);
rGPIOE_ODR =r_value;
}
五、实验数据、分析与实验结果
(1)编译结果:
(2)成功加载到开发板:
(3)实验现象:
灯D1、D2、D3、D4分别点亮。