ARM - LED灯实验(cortex A7核/cortex M4核)

开发板:华清远见FSMP1A

主板:

 扩展板:

芯片:STM32MP157A

架构:ARMV7

内核:Cortex®-A7 650 MHz *2 + Cortex®-M4 MPU

串口工具:SecureCRT.exe

ARM - LED灯实验(cortex A7核/cortex M4核)_第1张图片

分析硬件电路图

(1)分析LED灯工作原理

LED灯电路图及拓展接口电路图:

ARM - LED灯实验(cortex A7核/cortex M4核)_第2张图片

ARM - LED灯实验(cortex A7核/cortex M4核)_第3张图片

 LED灯原理图:

ARM - LED灯实验(cortex A7核/cortex M4核)_第4张图片

通过电路图分析可知LD1\LD2\LD3工作原理 

1.PE10/PF10/PE8引脚写高电平,灯点亮 

2.PE10/PF10/PE8引脚写低电平,灯熄灭

(2)分析芯片框图

ARM - LED灯实验(cortex A7核/cortex M4核)_第5张图片

1.A7核执行程序如何控制GPIO控制器?
    汇编指令:ldr/str
    通过特殊功能寄存器,向特殊功能寄存器中写入指定的值,或者读取里面的内容

2.软件编程控制硬件的思想?
    通过特殊功能寄存器,向特殊功能寄存器中写入指定的值,或者读取里面的内容。控制相应的外设工作

3.什么是特殊功能寄存器?
    特殊功能寄存器是内存一块寻址空间
    芯片厂家出厂的时候,对这块空间做了特殊的用途,不可以作为普通的寄存器使用

4.通过以上框图进行分析,需要分析芯片手册哪几个章节?
    GPIO章节(13章节General-purpose I/Os )
    RCC章节(10章节Reset and clock control)

(3)分析手册RCC章节

ARM - LED灯实验(cortex A7核/cortex M4核)_第6张图片

分析RCC_MP_AHB4ENSETR 使AHB4总线使能

RCC_MP_AHB4ENSETR地址=基地址+偏移地址 = 0x50000000 + 0xA28 = 0x50000A28

RCC_MP_AHB4ENSETR[4] = 1 -------->设置GPIOE控制器使能工作


如何确定基地址

ARM - LED灯实验(cortex A7核/cortex M4核)_第7张图片

 ARM - LED灯实验(cortex A7核/cortex M4核)_第8张图片

(4)分析手册GPIO章节

ARM - LED灯实验(cortex A7核/cortex M4核)_第9张图片

通过这个章节分析可知:GPIOx_MODER,GPIOx_OTYPER, GPIOx_OSPEEDR, GPIOx_PUPDR作用

1) GPIOx_MODER:GPIO模式寄存器----->设置为输出模式
2) GPIOx_OTYPER:GPIO输出类型寄存器----->设置为推挽/开漏输出
3) GPIOx_OSPEEDR:GPIO输出速度寄存器----->设置为输出速率
4) GPIOx_PUPDR:GPIO是否需要上下拉电阻
5) GPIOx_ODR:GPIO输出数据寄存器------>输出高低电平,实现LED灯点亮核熄灭

1) 分析GPIOx_MODER寄存器

ARM - LED灯实验(cortex A7核/cortex M4核)_第10张图片

LED1------>PE10引脚分析
1.如何确定GPIOE_MODER寄存器的地址?
    地址=基地址+偏移地址=0x50006000+0x00=0x50006000    
2.通过GPIOE_MODER设置PE10引脚设置为输出模式?
    GPIOE_MODER[21:20]=01------>输出模式
    向0x50006000地址中的第[21:20]写入01

2) 分析GPIOx_OTYPER寄存器

ARM - LED灯实验(cortex A7核/cortex M4核)_第11张图片

LED1------>PE10引脚分析
1.如何确定GPIOE_OTYPER寄存器的地址?
    地址=基地址+偏移地址=0x50006000+0x04=0x50006004  
2.通过GPIOE_OTYPER设置PE10引脚设置为推挽输出模式?
     GPIOE_OTYPER[10] = 0 ----->设置为推挽输出模式
     向0x50006004地址中的第[0]写入0

推挽输出:
        PMOS管和NMOS管都可以正常工作,可以输出高低电平

开漏输出:
        只有NMOS管可以正常工作,只可以输出低电平,如果想输出高电平,需要外接上拉电阻

3) 分析GPIOx_OSPEEDR寄存器

ARM - LED灯实验(cortex A7核/cortex M4核)_第12张图片

LED1------>PE10引脚分析
1.如何确定GPIOE_OSPEEDR寄存器的地址?
    地址=基地址+偏移地址=0x50006000+0x08=0x50006008 
2.通过GPIOE_OSPEEDR设置PE10引脚设置为低速输出模式?
     GPIOE_OSPEEDR[21:20] = 00 ----->设置为低速输出模式
     向0x50006008地址中的第[21:20]写入00

4) 分析GPIOx_PUPDR寄存器

ARM - LED灯实验(cortex A7核/cortex M4核)_第13张图片

LED1------>PE10引脚分析
1.如何确定GPIOE_PUPDR寄存器的地址?
    地址=基地址+偏移地址=0x50006000+0x0C=0x5000600C
2.通过GPIOE_PUPDR设置PE10引脚设置为禁止上下拉?
     GPIOE_PUPDR[21:20] = 00 ----->设置为禁止上下拉
     向0x5000600C地址中的第[21:20]写入00

 5) 分析GPIOx_ODR寄存器

ARM - LED灯实验(cortex A7核/cortex M4核)_第14张图片

LED1------>PE10引脚分析
1.如何确定GPIOE_ODR寄存器的地址?
    地址=基地址+偏移地址=0x50006000+0x14=0x50006014
2.通过GPIOE_ODR设置PE10引脚输出高低电平?
     GPIOE_ODR[10] = 0 ----->设置PE10引脚输出低电平
     GPIOE_ODR[10] = 1 ----->设置PE10引脚输出高电平
     向0x50006014地址中的第[10]写入0,输出低电平
     向0x50006014地址中的第[10]写入1,输出高电平

CORTEX A7核实现

汇编代码:

.global _start
_start: 

/**********LED1点亮**************/
LED1_INIT:
	@1.通过RCC_AHB4_ENSETR:0x50000A28寄存器设置GPIOE控制器使能 0x50000A28[4] = 1
	ldr r0,=0x50000A28
	ldr r1,[r0] @将r0寄存器地址中的值,读到r1寄存器中
	orr r1,r1,#(0x1 << 4) 
	@将r1寄存器中的第4位置1
	str r1,[r0]

	@2.通过GPIOE_MODER:0x50006000寄存器设置PE10引脚为输出模式 0x50006000[21:20]= 01
	ldr r0,=0x50006000
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	orr r1,r1,#(0x1 << 20)
	str r1,[r0]

	@3.通过GPIOE_OTYPER:0x50006004寄存器设置PE10引脚为推挽输出模式 0x50006004[10]= 0
	ldr r0,=0x50006004
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 10))
	str r1,[r0]

	@4.通过GPIOE_OSPEEDR:0x50006008寄存器设置PE10引脚为低速输出模式0x50006008[21:20]= 00
	ldr r0,=0x50006008
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	str r1,[r0]

	@5.通过GPIOE_PUPDR:0x5000600C寄存器设置PE10引脚为禁止上下拉0x5000600C[21:20]= 00
	ldr r0,=0x5000600C
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	str r1,[r0]

/**********LED2点亮PF10**************/
LED2_INIT:
	@1.通过RCC_AHB4_ENSETR:0x50000A28寄存器设置GPIOF控制器使能 0x50000A28[5] = 1
	ldr r0,=0x50000A28
	ldr r1,[r0] @将r0寄存器地址中的值,读到r1寄存器中
	orr r1,r1,#(0x1 << 5) 
	@将r1寄存器中的第4位置1
	str r1,[r0]

	@2.通过GPIOF_MODER:0x50006000寄存器设置PF10引脚为输出模式 0x50007000[21:20]= 01
	ldr r0,=0x50007000
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	orr r1,r1,#(0x1 << 20)
	str r1,[r0]

	@3.通过GPIOF_OTYPER:0x50006004寄存器设置PF10引脚为推挽输出模式 0x50007004[10]= 0
	ldr r0,=0x50007004
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 10))
	str r1,[r0]

	@4.通过GPIOF_OSPEEDR:0x50006008寄存器设置PE10引脚为低速输出模式0x50007008[21:20]= 00
	ldr r0,=0x50007008
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	str r1,[r0]

	@5.通过GPIOF_PUPDR:0x5000700C寄存器设置PE10引脚为禁止上下拉0x5000700C[21:20]= 00
	ldr r0,=0x5000700C
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	str r1,[r0]

/**********LED3点亮PE8**************/
LED3_INIT:
	@1.通过RCC_AHB4_ENSETR:0x50000A28寄存器设置GPIOE控制器使能 0x50000A28[4] = 1
	ldr r0,=0x50000A28
	ldr r1,[r0] @将r0寄存器地址中的值,读到r1寄存器中
	orr r1,r1,#(0x1 << 4) 
	@将r1寄存器中的第4位置1
	str r1,[r0]

	@2.通过GPIOE_MODER:0x50006000寄存器设置PE8引脚为输出模式 0x50006000[17:16]= 01
	ldr r0,=0x50006000
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 16))
	orr r1,r1,#(0x1 << 16)
	str r1,[r0]

	@3.通过GPIOE_OTYPER:0x50006004寄存器设置PE8引脚为推挽输出模式 0x50006004[8]= 0
	ldr r0,=0x50006004
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 8))
	str r1,[r0]

	@4.通过GPIOE_OSPEEDR:0x50006008寄存器设置PE8引脚为低速输出模式0x50006008[17:16]= 00
	ldr r0,=0x50006008
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 16))
	str r1,[r0]

	@5.通过GPIOE_PUPDR:0x5000600C寄存器设置PE8引脚为禁止上下拉0x5000600C[17:16]= 00
	ldr r0,=0x5000600C
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 16))
	str r1,[r0]

loop:
	bl LED1_ON
	bl delay_1s
	bl LED1_OFF
	bl delay_1s

	bl LED2_ON
	bl delay_1s
	bl LED2_OFF
	bl delay_1s

	bl LED3_ON
	bl delay_1s
	bl LED3_OFF
	bl delay_1s
	b loop

LED1_ON:
	@1.通过GPIOE_ODR:0x50006014寄存器设置PE10引脚为输出高电平 0x50006014[10]= 1
	ldr r0,=0x50006014
	ldr r1,[r0]
	orr r1,r1,#(0x1 << 10)
	str r1,[r0]
	mov pc,lr

LED2_ON:
	@1.通过GPIOF_ODR:0x50007014寄存器设置PF10引脚为输出高电平 0x50007014[10]= 1
	ldr r0,=0x50007014
	ldr r1,[r0]
	orr r1,r1,#(0x1 << 10)
	str r1,[r0]
	mov pc,lr
LED3_ON:
	@1.通过GPIOE_ODR:0x50006014寄存器设置PE8引脚为输出高电平 0x50006014[8]= 1
	ldr r0,=0x50006014
	ldr r1,[r0]
	orr r1,r1,#(0x1 << 8)
	str r1,[r0]
	mov pc,lr

LED1_OFF:
	@1.通过GPIOE_ODR:0x50006014寄存器设置PE10引脚为输出低电平 0x50006014[10]= 0
	ldr r0,=0x50006014
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 10))
	str r1,[r0]
	mov pc,lr
LED2_OFF:
	@1.通过GPIOE_ODR:0x50007014寄存器设置PE10引脚为输出低电平 0x50007014[10]= 0
	ldr r0,=0x50007014
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 10))
	str r1,[r0]
	mov pc,lr

LED3_OFF:
	@1.通过GPIOE_ODR:0x50006014寄存器设置PE10引脚为输出低电平 0x50006014[8]= 0
	ldr r0,=0x50006014
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 8))
	str r1,[r0]
	mov pc,lr

@ 大概1s的延时函数
delay_1s:
	mov r3, #0x10000000
	mm:
	cmp r3, #0
	subne r3, r3, #1
	bne mm
	mov pc, lr

.end

C语言实现:

头文件编写:

#ifndef __GPIO_H__
#define __GPIO_H__

//1.RCC寄存器封装,用宏定义进行封装
#define RCC_AHB4_ENSETR (*(unsigned int *)0x50000A28)
//2.GPIO寄存器进行封装,用结构体封装
typedef struct{
	volatile unsigned int MODER; //00
	volatile unsigned int OTYPER; //04
	volatile unsigned int OSPEEDR; //08
	volatile unsigned int PUPDR; //0C
	volatile unsigned int IDR; //10
	volatile unsigned int ODR; //14
}gpio_t;
#define GPIOE ((gpio_t*)0x50006000)
#define GPIOF ((gpio_t*)0x50007000)

//引脚封装
#define GPIO_PIN_0 0
#define GPIO_PIN_1 1
#define GPIO_PIN_2 2
#define GPIO_PIN_3 3
#define GPIO_PIN_4 4
#define GPIO_PIN_5 5
#define GPIO_PIN_6 6
#define GPIO_PIN_7 7
#define GPIO_PIN_8 8
#define GPIO_PIN_9 9
#define GPIO_PIN_10 10
#define GPIO_PIN_11 11
#define GPIO_PIN_12 12
#define GPIO_PIN_13 13
#define GPIO_PIN_14 14
#define GPIO_PIN_15 15

//封装模式寄存器
typedef enum{
	INPUT,
	OUTPUT,
	ALT,
	ANALOG,
}gpio_mode_t;

//封装输出类型寄存器
typedef enum{
	PP,
	OD,
}gpio_otyper_t;

//封装输出速度寄存器
typedef enum{
	LOW,
	MED,
	HIGH,
	VERY_HIGH,
}gpio_ospeedr_t;

//封装是否需要上下拉电阻
typedef enum{
	NO_PUPD,
	PU,
	PD,
}gpio_pupdr_t;

//封装输出高低电平
typedef enum{
	GPIO_RESET,
	GPIO_SET,
}gpio_status_t;

//结构体初始化
typedef struct{
	gpio_mode_t moder;
	gpio_otyper_t otyper;
	gpio_ospeedr_t speedr;
	gpio_pupdr_t pupdr;
}gpio_init_t;

//初始化函数
void hal_gpio_init(gpio_t* gpiox,gpio_init_t* init,unsigned int pin);

//写操作函数
void hal_gpio_write(gpio_t* gpiox,unsigned int pin,gpio_status_t state);

#endif

函数封装:

#include "gpio.h"
//初始化函数
void hal_gpio_init(gpio_t* gpiox,gpio_init_t* init,unsigned int pin)
{
	//1.设置输出模式
	gpiox->MODER &= (~(0x3 << (pin * 2)));
	gpiox->MODER |= (init->moder << (pin *2));

	//2.设置输出类型
	gpiox->OTYPER &= (~(0x1 << pin));
	gpiox->OTYPER |= (init->otyper << pin);

	//3.设置输出速度
	gpiox->OSPEEDR &= (~(0x3 << (pin *2)));
	gpiox->OSPEEDR |= (init->speedr << (pin * 2));

	//4.设置是否需要上下拉
	gpiox->PUPDR &= (~(0x3 << (pin * 2)));
	gpiox->PUPDR |= (init->pupdr << (pin * 2));
}

//写操作函数
void hal_gpio_write(gpio_t* gpiox,unsigned int pin,gpio_status_t state)
{
	if(state == GPIO_RESET)
	{
		gpiox->ODR &= (~(0x1 << pin));
	}
	else
	{
		gpiox->ODR |=(0x1 << pin);
	}
}

主函数:

#include "gpio.h"

extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
	int i,j;
	for(i = 0; i < ms;i++)
		for (j = 0; j < 1800; j++);
}

void led_init()
{
	//1.时钟使能
	RCC_AHB4_ENSETR |= (0x3 << 4);
	//2.led灯结构体初始化
	gpio_init_t init = {OUTPUT,PP,LOW,NO_PUPD};

	hal_gpio_init(GPIOE,&init,GPIO_PIN_10);
	hal_gpio_init(GPIOF,&init,GPIO_PIN_10);
	hal_gpio_init(GPIOE,&init,GPIO_PIN_8);
}

int main()
{
	led_init();
	while(1)
	{
		hal_gpio_write(GPIOE,GPIO_PIN_10,GPIO_SET);
		delay_ms(500);
		hal_gpio_write(GPIOE,GPIO_PIN_10,GPIO_RESET);
		delay_ms(500);

		hal_gpio_write(GPIOF,GPIO_PIN_10,GPIO_SET);
		delay_ms(500);
		hal_gpio_write(GPIOF,GPIO_PIN_10,GPIO_RESET);
		delay_ms(500);

		hal_gpio_write(GPIOE,GPIO_PIN_8,GPIO_SET);
		delay_ms(500);
		hal_gpio_write(GPIOE,GPIO_PIN_8,GPIO_RESET);
		delay_ms(500);
	}
	return 0;
}

 CORTEX M4核实现

一、CubMX工程创建:

ARM - LED灯实验(cortex A7核/cortex M4核)_第15张图片

ARM - LED灯实验(cortex A7核/cortex M4核)_第16张图片

 二、配置LED灯

1.配置PE10/PF10/PE8,鼠标左键,设置位输出模式

2.鼠标右键,配置为M4核

ARM - LED灯实验(cortex A7核/cortex M4核)_第17张图片

 ARM - LED灯实验(cortex A7核/cortex M4核)_第18张图片

 三、查看配置信息

ARM - LED灯实验(cortex A7核/cortex M4核)_第19张图片

四、导出工程 

ARM - LED灯实验(cortex A7核/cortex M4核)_第20张图片

 ARM - LED灯实验(cortex A7核/cortex M4核)_第21张图片

ARM - LED灯实验(cortex A7核/cortex M4核)_第22张图片

 五、代码编写

ARM - LED灯实验(cortex A7核/cortex M4核)_第23张图片

KEIL配置:

 ARM - LED灯实验(cortex A7核/cortex M4核)_第24张图片

ARM - LED灯实验(cortex A7核/cortex M4核)_第25张图片

ARM - LED灯实验(cortex A7核/cortex M4核)_第26张图片

ARM - LED灯实验(cortex A7核/cortex M4核)_第27张图片

ARM - LED灯实验(cortex A7核/cortex M4核)_第28张图片

代码块: ARM - LED灯实验(cortex A7核/cortex M4核)_第29张图片

你可能感兴趣的:(ARM,arm,嵌入式硬件,stm32,c语言,汇编)