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

开发板:华清远见FSMP1A

主板:

 扩展板:

芯片:STM32MP157A

架构:ARMV7

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

串口工具:SecureCRT.exe

分析硬件电路图

(1)分析LED灯工作原理

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

 LED灯原理图:

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

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

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

(2)分析芯片框图

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

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

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

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

(3)分析手册RCC章节

分析RCC_MP_AHB4ENSETR 使AHB4总线使能

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

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


如何确定基地址

 

(4)分析手册GPIO章节

通过这个章节分析可知: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寄存器

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

2) 分析GPIOx_OTYPER寄存器

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寄存器

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

4) 分析GPIOx_PUPDR寄存器

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

 5) 分析GPIOx_ODR寄存器

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工程创建:

 二、配置LED灯

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

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

 

 三、查看配置信息

四、导出工程 

 

 五、代码编写

KEIL配置:

 

代码块: 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ARM Cortex-M3与Cortex-M4权威指南高清版 姚文祥、吴常玉、曹孟娟、王丽红编写的《ARM Cortex-M3与Cortex-M4权威指南(第3版)》经过了全 新修订:增加了ARM CortexM4l处理器的信息;对 ARM cortex一M3处理器的讲解进行了*新;对于ARM Cortex—M3和ARM CortexM4进行了比较,方便其 他多种处理器架构移植到ARMCortex—M3和ARM cortexM4。本版的其他修订细节如下: 新增了论述。DSP特性和CMSIS一DSP软件库的两 章内容,介绍了DSP的基础知识以及如何编写CortexM4 的DSP软件,其中包括使用CMSIS—DsP库的实例 以及cortexM4的DsP陛能方面的知识。   新增了介绍cortexM4浮点单元及其使用的一章 内容。   新增了介绍嵌入式操作系统的使用(基于CMSIs— RTOS)以及支持嵌入式操作系统的处理器特性的一章 内容。   多种调试技术以及疑难解答。   从其他处理器进行软件移植的内容。   此外,本书介绍了ARM架构的背景知识以及指令 集、中断处理等处理器特性,并描述了如何设置并利 用存储器保护单元(MPu)等可用的高级特性。书中论 述Keil MDK、IAR EWARM、gcc以及CooCoxCoIDE工具 入门的章节可以给初学者在编写程序代码方面提供一 些帮助,其中也包括一些重要的软件开发问题,比如 低功耗特性的使用、信息输入/输出的处理、汇编c语言的混合编程及其他高级技术话题。
ARM Cortex-M3与Cortex-M4权威指南》是一本关于ARM Cortex-M3和Cortex-M4处理器的权威性书籍,由Joseph Yiu所著。本书全面介绍了ARM Cortex-M3和Cortex-M4这两种处理器的体系结构、指令集、应用设计实例等内容,是研究这两款处理器的必备手册和高质量参考资料。 本书首先介绍了ARM Cortex-M3和Cortex-M4处理器的体系结构,包括CPU心、内存、外设接口等方面,并深入解析了这两款处理器的指令集,包括基本指令、数据处理指令、浮点运算指令等。此外,本书还详细介绍了由Cortex-M3和Cortex-M4构成的微控制器的设计,为读者提供了一系列典型的应用示例,使读者能够更好地了解这两款处理器的应用场景和实际应用荣誉。 此外,《ARM Cortex-M3与Cortex-M4权威指南》在讲解ARM Cortex-M3和Cortex-M4的过程中,还介绍了具体的编程技巧和调试方法。对于从事嵌入式系统开发的读者而言,这些内容非常有价值。读者不仅能够学习到ARM Cortex-M3和Cortex-M4的基本知识,还能够掌握相关开发技巧和工具的使用方法。 总之,《ARM Cortex-M3与Cortex-M4权威指南》是一本十分优秀的书籍,为读者提供了全面介绍ARM Cortex-M3和Cortex-M4处理器的基础知识,让读者能够更快地了解这两款处理器的特性和应用场景,并使读者能够根据自己的需求来进行开发和应用。该书值得广大嵌入式开发人员的阅读和借鉴。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coding Peasant

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值