Crotex_A7核点灯实验 c语言实现点灯 流水灯 以及汇编语言实现点灯 流水灯

1、汇编实现流水灯

.text 
.global _start
_start: 
	/**********LED1点灯--->10**************/

	bl RCC_INET
	bl LED1_INET
loop:
	bl LED1_ON
	bl delay_1s
	bl LED1_OFF
	bl LED2_ON
	bl delay_1s
	bl LED2_OFF
	bl LED3_ON
	bl delay_1s
	bl LED3_OFF
	b loop
	/**********RCC章节初始化**************/
RCC_INET:
	@1.使能GPIOE组控制器,通过RCC_MP_AHB$ENSETR寄存器设置GPIOE组使能 0x50000A28[4] = 1

	ldr r0,=0x50000A28
	ldr r1,[r0]
	orr r1,r1,#(0x1 << 4)
	orr r1,r1,#(0x1 << 5)
	str r1,[r0]
	mov pc, lr
	/**********GPIO章节初始化**************/
LED1_INET:
	@LED_1和LED_3的初始化
	@1.通过GPIOE_MODER寄存器,设置PE10引脚为输出模式0x50006000[21:20] = 01
	@1.通过GPIOE_MODER寄存器,设置PE8引脚为输出模式0x50006000[17:16] = 01
		ldr r0,=0x50006000
		ldr r1,[r0]
		orr r1,r1,#(0x1 << 20)
		and r1,r1,#(~(0x1 << 21))
		orr r1,r1,#(0x1 << 16)
		and r1,r1,#(~(0x1 << 17))
		str r1,[r0]
	@2.通过GPIOE_OTYPER寄存器,设置PE10引脚为推晚输出类型0x50006004[10] = 0
	@2.通过GPIOE_OTYPER寄存器,设置PE8引脚为推晚输出类型0x50006004[8] = 0
		ldr r0,=0x50006004
		ldr r1,[r0]
		and r1,r1,#(~(0x1 << 10))
		and r1,r1,#(~(0x1 << 8))
		str r1,[r0]
	@3.通过GPIOE_OSPEEDR寄存器,设置PE10引脚为低速输出0x50006008[21:20] = 00
	@3.通过GPIOE_OSPEEDR寄存器,设置PE8引脚为低速输出0x50006008[17:16] = 00
		ldr r0,=0x50006008
		ldr r1,[r0]
		and r1,r1,#(~(0x3 << 20))
		and r1,r1,#(~(0x3 << 16))
		str r1,[r0]
	@4.通过GPIOE_PUPDR寄存器,设置PE10引脚为输出模式0x50006000C[21:20] = 00
	@4.通过GPIOE_PUPDR寄存器,设置PE8引脚为输出模式0x50006000C[17:16] = 00
		ldr r0,=0x5000600C
		ldr r1,[r0]
		and r1,r1,#(~(0x3 << 20))
		and r1,r1,#(~(0x3 << 16))
		str r1,[r0]

	@LED_2的初始化

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

	@2.通过GPIOF_OTYPER寄存器,设置PF10引脚为推晚输出类型0x50007004[10] = 0
		ldr r0,=0x50007004
		ldr r1,[r0]
		and r1,r1,#(~(0x1 << 10))
		str r1,[r0]

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

	@4.通过GPIOF_PUPDR寄存器,设置PF10引脚为输出模式0x50007000C[21:20] = 00
		ldr r0,=0x5000700C
		ldr r1,[r0]
		and r1,r1,#(~(0x3 << 20))
		str r1,[r0]
		mov pc, lr


	/**********LED1点亮**************/
LED1_ON:
	@1.通过GPIO_ODR寄存器,设置PE10引脚输出高电平 0x50006014[10] = 1
		ldr r0,=0x50006014
		ldr r1,[r0]
		orr r1,r1,#(0x1 << 10)
		str r1,[r0]
		mov pc, lr
	/**********LED1熄灭**************/
LED1_OFF:
	@1.通过GPIO_ODR寄存器,设置PE10引脚输出低电平 0x50006014[10] = 0
		ldr r0,=0x50006014
		ldr r1,[r0]
		and r1,r1,#(~(0x1 << 10))
		str r1,[r0]
		mov pc, lr
LED2_ON:
		ldr r0,=0x50007014
		ldr r1,[r0]
		orr r1,r1,#(0x1 << 10)
		str r1,[r0]
		mov pc, lr

LED2_OFF:
		ldr r0,=0x50007014
		ldr r1,[r0]
		and r1,r1,#(~(0x1 << 10))
		str r1,[r0]
		mov pc, lr
LED3_ON:
		ldr r0,=0x50006014
		ldr r1,[r0]
		orr r1,r1,#(0x1 << 8)
		str r1,[r0]
		mov pc, lr

LED3_OFF:
		ldr r0,=0x50006014
		ldr r1,[r0]
	
		and r1,r1,#(~(0x1 << 8))
		str r1,[r0]
		mov pc, lr

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

.end

2、c语言实现流水灯

//led.h

#ifndef __LED_H__
#define __LED_H__
typedef struct{
   volatile unsigned int MODER;
   volatile unsigned int OTYPER;
   volatile unsigned int OSPEEDR;
   volatile unsigned int PUPDR;
   volatile unsigned int IDR;
   volatile unsigned int ODR;
}gpio_t;
#define GPIOE ((gpio_t*)0x50006000)
#define GPIOF ((gpio_t*)0x50007000)
#define RCC_MP_AHB4_ENSETR (*(volatile unsigned int*)0x50000A28) 

//LED1--->PE10
//RCC/GPIO章节初始化
void led1_rcc_gpio_init();
//LED1点亮
void led1_on();
//LED1熄灭
void led1_off();

//LED2--->PF10
//RCC/GPIO章节初始化
void led2_rcc_gpio_init();
//LED1点亮
void led2_on();
//LED1熄灭
void led2_off();


//LED3--->PE8
//RCC/GPIO章节初始化
void led3_rcc_gpio_init();
//LED3点亮
void led3_on();
//LED1熄灭
void led3_off();

#endif


//led.c

#include "led.h"
//LED1--->PE10
//RCC/GPIO章节初始化
void led1_rcc_gpio_init()
{
	//1.使能GPIOE组控制器,通过RCC_MP_AHB$ENSETR寄存器设置GPIOE组使能 0x50000A28[4] = 1  
	RCC_MP_AHB4_ENSETR |= (0x1 << 4);
	
	//LED1的初始化
	//1.通过GPIOE_MODER寄存器,设置PE10引脚为输出模式0x50006000[21:20] = 01 
	GPIOE->MODER |= (0x1 << 20);
	GPIOE->MODER &= (~(0x1 << 21));

	//2.通过GPIOE_OTYPER寄存器,设置PE10引脚为推晚输出类型0x50006004[10] = 0  
	GPIOE->OTYPER &= (~(0x1 << 10));

	//3.通过GPIOE_OSPEEDR寄存器,设置PE10引脚为低速输出0x50006008[21:20] = 00
	GPIOE->OSPEEDR &= (~(0x3 << 20));

	//4.通过GPIOE_PUPDR寄存器,设置PE10引脚为输出模式0x50006000C[21:20] = 00
	GPIOE->PUPDR &=(~(0x3 << 20));

	
}
//LED1点亮
void led1_on()
{
	//1.通过GPIO_ODR寄存器,设置PE10引脚输出高电平 0x50006014[10] = 1
	GPIOE->ODR |= (0x1 << 10);
}
//LED1熄灭
void led1_off()
{
	//2.通过GPIO_ODR寄存器,设置PE10引脚输出高电平 0x50006014[10] = 0
	GPIOE->ODR &= (~(0x1 << 10));
}

//LED2--->PF10
void led2_rcc_gpio_init()
{
	
	//1.使能GPIOF组控制器,通过RCC_MP_AHB$ENSETR寄存器设置GPIOE组使能 0x50000A28[5] = 1  
	RCC_MP_AHB4_ENSETR |= (0x1 << 5);
	//LED2的初始化
	//1.通过GPIOF_MODER寄存器,设置PF10引脚为输出模式0x50007000[21:20] = 01
	GPIOF->MODER |= (0x1 << 20);
	GPIOF->MODER &= (~(0x1 << 21));

	//2.通过GPIOF_OTYPER寄存器,设置PF10引脚为推晚输出类型0x50007004[10] = 0
	GPIOF->OTYPER &= (~(0x1 << 10));

	//3.通过GPIOF_OSPEEDR寄存器,设置PF10引脚为低速输出0x50007008[21:20] = 00
	GPIOF->OSPEEDR &= (~(0x3 << 20));

	//4.通过GPIOF_PUPDR寄存器,设置PF10引脚为输出模式0x50007000C[21:20] = 00
	GPIOF->PUPDR &=(~(0x3 << 20));

}
//LED2点亮
void led2_on()
{
	//1.通过GPIO_ODR寄存器,设置PF10引脚输出高电平 0x50006014[10] = 1
	GPIOF->ODR |= (0x1 << 10);
}
//LED2熄灭
void led2_off()
{
	//2.通过GPIO_ODR寄存器,设置PF10引脚输出高电平 0x50006014[10] = 0
	GPIOF->ODR &= (~(0x1 << 10));
}


//LED3--->PE8
//RCC/GPIO章节初始化
void led3_rcc_gpio_init()
{
	//1.使能GPIOE组控制器,通过RCC_MP_AHB$ENSETR寄存器设置GPIOE组使能 0x50000A28[4] = 1  
	RCC_MP_AHB4_ENSETR |= (0x1 << 4);
	
	//LED1的初始化
	//1.通过GPIOE_MODER寄存器,设置PE10引脚为输出模式0x50006000[17:16] = 01 
	GPIOE->MODER |= (0x1 << 16);
	GPIOE->MODER &= (~(0x1 << 17));

	//2.通过GPIOE_OTYPER寄存器,设置PE10引脚为推晚输出类型0x50006004[8] = 0  
	GPIOE->OTYPER &= (~(0x1 << 8));

	//3.通过GPIOE_OSPEEDR寄存器,设置PE10引脚为低速输出0x50006008[17:16] = 00
	GPIOE->OSPEEDR &= (~(0x3 << 16));

	//4.通过GPIOE_PUPDR寄存器,设置PE10引脚为输出模式0x50006000C[17:16] = 00
	GPIOE->PUPDR &=(~(0x3 << 16));
}
//LED3点亮
void led3_on()
{
	//1.通过GPIO_ODR寄存器,设置PE8引脚输出高电平 0x50006014[10] = 1
	GPIOE->ODR |= (0x1 << 8);
}
//LED1熄灭
void led3_off()
{
	//2.通过GPIO_ODR寄存器,设置PE8引脚输出高电平 0x50006014[10] = 0
	GPIOE->ODR &= (~(0x1 << 8));
}


//main.c


#include "led.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++);
}


int main()
{
	led1_rcc_gpio_init(); // LED1灯初始化
	led2_rcc_gpio_init();//LED2初始化
	led3_rcc_gpio_init();//LED3初始化
	while(1)
	{
		//流水灯
		led1_on();
		delay_ms(200);
		led1_off();
		led2_on();
		delay_ms(200);
		led2_off();
		led3_on();
		delay_ms(200);
		led3_off();

	}
	return 0;
}

3、拓展作业:

使用枚举封装函数,实现流水灯

尝试封装函数:初始化函数 写函数(开关操作)===>函数参数、函数实现

1、led.h:

//led.h

#ifndef __LED_H__
#define __LED_H__
typedef enum led 
{
	LED_1=1,
	LED_2,
	LED_3,
}LED;
typedef enum led_c
{
	LED_OFF,
	LED_ON,
}LED_CON;
typedef struct{
   volatile unsigned int MODER;
   volatile unsigned int OTYPER;
   volatile unsigned int OSPEEDR;
   volatile unsigned int PUPDR;
   volatile unsigned int IDR;
   volatile unsigned int ODR;
}gpio_t;
#define GPIOE ((gpio_t*)0x50006000)
#define GPIOF ((gpio_t*)0x50007000)
#define RCC_MP_AHB4_ENSETR (*(volatile unsigned int*)0x50000A28) 

void led_init();
void led_con();


#endif

2、led.c

//led.c

#include "led.h"
void led_init(LED led)
{
	switch(led)
	{
	case LED_1:   //直接使用枚举项对枚举变量判断
		//1.使能GPIOE组控制器,通过RCC_MP_AHB$ENSETR寄存器设置GPIOE组使能 0x50000A28[4] = 1  
		RCC_MP_AHB4_ENSETR |= (0x1 << 4);

		//LED1的初始化
		//1.通过GPIOE_MODER寄存器,设置PE10引脚为输出模式0x50006000[21:20] = 01 
		GPIOE->MODER |= (0x1 << 20);
		GPIOE->MODER &= (~(0x1 << 21));

		//2.通过GPIOE_OTYPER寄存器,设置PE10引脚为推晚输出类型0x50006004[10] = 0  
		GPIOE->OTYPER &= (~(0x1 << 10));

		//3.通过GPIOE_OSPEEDR寄存器,设置PE10引脚为低速输出0x50006008[21:20] = 00
		GPIOE->OSPEEDR &= (~(0x3 << 20));

		//4.通过GPIOE_PUPDR寄存器,设置PE10引脚为输出模式0x50006000C[21:20] = 00
		GPIOE->PUPDR &=(~(0x3 << 20));

		//printf("初始化了LED_1灯\n");
        break;
    case LED_2:

		//1.使能GPIOF组控制器,通过RCC_MP_AHB$ENSETR寄存器设置GPIOE组使能 0x50000A28[5] = 1
		RCC_MP_AHB4_ENSETR |= (0x1 << 5);
		//LED2的初始化
		//1.通过GPIOF_MODER寄存器,设置PF10引脚为输出模式0x50007000[21:20] = 01
		GPIOF->MODER |= (0x1 << 20);
		GPIOF->MODER &= (~(0x1 << 21));

		//2.通过GPIOF_OTYPER寄存器,设置PF10引脚为推晚输出类型0x50007004[10] = 0
		GPIOF->OTYPER &= (~(0x1 << 10));

		//3.通过GPIOF_OSPEEDR寄存器,设置PF10引脚为低速输出0x50007008[21:20] = 00
		GPIOF->OSPEEDR &= (~(0x3 << 20));

		//4.通过GPIOF_PUPDR寄存器,设置PF10引脚为输出模式0x50007000C[21:20] = 00
		GPIOF->PUPDR &=(~(0x3 << 20));

		//printf("初始化了LED_2灯\n");
		break;
	case LED_3:

		//1.使能GPIOE组控制器,通过RCC_MP_AHB$ENSETR寄存器设置GPIOE组使能 0x50000A28[4] = 1
		RCC_MP_AHB4_ENSETR |= (0x1 << 4);

		//LED1的初始化
		//1.通过GPIOE_MODER寄存器,设置PE10引脚为输出模式0x50006000[17:16] = 01
		GPIOE->MODER |= (0x1 << 16);
		GPIOE->MODER &= (~(0x1 << 17));

		//2.通过GPIOE_OTYPER寄存器,设置PE10引脚为推晚输出类型0x50006004[8] = 0
		GPIOE->OTYPER &= (~(0x1 << 8));

		//3.通过GPIOE_OSPEEDR寄存器,设置PE10引脚为低速输出0x50006008[17:16] = 00
		GPIOE->OSPEEDR &= (~(0x3 << 16));

		//4.通过GPIOE_PUPDR寄存器,设置PE10引脚为输出模式0x50006000C[17:16] = 00
		GPIOE->PUPDR &=(~(0x3 << 16));

		//printf("初始化了LED_3灯\n");
		break;
	}
}

void led_con(LED led,LED_CON c)
{
	switch(led)
	{

	case LED_1:   //直接使用枚举项对枚举变量判断
		switch(c)
		{
		case LED_ON:

			//1.通过GPIO_ODR寄存器,设置PE10引脚输出高电平 0x50006014[10] = 1
			GPIOE->ODR |= (0x1 << 10);

			//printf("打开了LED_1灯\n");
			break;

		case LED_OFF:

			//2.通过GPIO_ODR寄存器,设置PE10引脚输出高电平 0x50006014[10] = 0
			GPIOE->ODR &= (~(0x1 << 10));

			//printf("关闭了LED_1灯\n");
			break;
		}
		break;

	case LED_2:
		switch(c)
		{
		case LED_ON:

			//1.通过GPIO_ODR寄存器,设置PF10引脚输出高电平 0x50006014[10] = 1
			GPIOF->ODR |= (0x1 << 10);

			//printf("打开了LED_2灯\n");
			break;
		case LED_OFF:

			//2.通过GPIO_ODR寄存器,设置PF10引脚输出高电平 0x50006014[10] = 0
			GPIOF->ODR &= (~(0x1 << 10));

			//printf("关闭了LED_2灯\n");
			break;

		}
		break;

	case LED_3:
		switch(c)
		{
		case LED_ON:

			//1.通过GPIO_ODR寄存器,设置PE8引脚输出高电平 0x50006014[10] = 1
			GPIOE->ODR |= (0x1 << 8);

			//printf("打开了LED_3灯\n");
			break;
		case LED_OFF:

			//2.通过GPIO_ODR寄存器,设置PE8引脚输出高电平 0x50006014[10] = 0
			GPIOE->ODR &= (~(0x1 << 8));

			//printf("关闭了LED_3灯\n");
			break;

        }    
    }
}

3、main.c

//main.c

#include "led.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++);
}


int main()
{
	LED led1 = LED_1;
	LED led2 = LED_2;
	LED led3 = LED_3;

	led_init(led1);//初始化LED1
	led_init(led2);//初始化LED2
	led_init(led3);//初始化LED3

	while(1)
	{
		//流水灯
		led_con(led1,LED_ON);
		delay_ms(200);
		led_con(led1,LED_OFF);
		led_con(led2,LED_ON);
		delay_ms(200);
		led_con(led2,LED_OFF);
		led_con(led3,LED_ON);
		delay_ms(200);
		led_con(led3,LED_OFF);

	}
	return 0;
}

你可能感兴趣的:(c语言,单片机,开发语言,嵌入式硬件)