【嵌入式】——STM32F401VE寄存器实现流水灯

在这里插入图片描述
main.c文件:

#define rRCCAHB1CLKEN   *((volatile unsigned long *)0x40023830) 
#define rGPIOD_MODER    *((volatile unsigned long *)0x40020C00)
#define rGPIOD_OTYPER  *((volatile unsigned long *)0x40020C04)
#define rGPIOD_OSPEED  *((volatile unsigned long *)0x40020C08)
#define rGPIOD_PUPDR   *((volatile unsigned long *)0x40020C0C)
#define rGPIOD_ODR     *((volatile unsigned long *)0x40020C14)


void led_init()              //初始化;
{
	unsigned long r;

	//使能GPIOD这组的时钟
	//rRCCAHB1CLKEN[4] -> GPIOD	
	//	1 -> enable clk	  0 -> disable clk

	rRCCAHB1CLKEN |= (1 << 3);

	// PD0-3 -> 通用输出模式
	// [07:00] 01010101
	r = rGPIOD_MODER;
	r &= ~(0xff << 0);             //清零
	r |= ((1 << 0) | (1 << 2) | (1 << 4) | (1 << 6));    //把PD0-3设置为01,即设置为输出模式
	rGPIOD_MODER = r;



	// PD0-3 输出类型为: 输出推挽 otyper[3:0]   -> 0000
	r = rGPIOD_OTYPER ;
	r &= ~((1 << 0) | (1 << 2) | (1 << 4) | (1 << 6));  
	rGPIOD_OTYPER = r;

	//PD0-3 输出速率-> 50MHZ 10	 ospeedr[07:00]: 10101010
	r = rGPIOD_OSPEED;
	r &= ~(0xff << 0);          
	r |= (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7);      
	rGPIOD_OSPEED = r;

	//PD0-3 disable pull-up/disable pull-down	 pupdr[07:00] :00000000
	//无上拉无下拉
	r = rGPIOD_PUPDR;
	r &= ~(0xff << 0);      
	rGPIOD_PUPDR = r;

	//设置为低电平,LED灯熄灭
	r = rGPIOD_ODR;
	r &= ~(0x0f << 0);
	rGPIOD_ODR = r;
}


//延时函数;
void delay(unsigned int v)
{
	while (v--);
}


//选择哪一个LED灯亮;
void led_ctrl(int ledN)
{
	unsigned long r;
	switch (ledN)
	{
		//高电平亮,低电平灭
		case 0:                     //LED0亮,其他LED灯灭
		{
			r = rGPIOD_ODR;
			r &= ~(0x0f << 0);		//清零
			r |= 1 << 0;			//亮灯
			rGPIOD_ODR = r;
			break;
		}
		case 1:                           //LED1亮,其他LED灯灭
		{
			r = rGPIOD_ODR;
			r &= ~(0x0f << 0);		//清零
			r |= 1 << 1;			//亮灯
			rGPIOD_ODR = r;
			break;
		}
		case 2:                            //LED2亮,其他LED灯灭
		{
			r = rGPIOD_ODR;
			r &= ~(0x0f << 0);		//清零
			r |= 1 << 2;			//亮灯
			rGPIOD_ODR = r;
			break;
		}
		case 3:                          //LED3亮,其他LED灯灭
		{
			r = rGPIOD_ODR;
			r &= ~(0x0f << 0);		//清零
			r |= 1 << 3;			//亮灯
			rGPIOD_ODR = r;
			break;
		}
		default:
			break;
		}
}

int main()
{
	int led = 0;
	led_init();
	while (1)                          //控制LED灯循环点亮;
	{
		led_ctrl(led++);
		delay(0x66ff33);
		led_ctrl(led++);
		delay(0x66ff33);
		led_ctrl(led++);
		delay(0x66ff33);
		led_ctrl(led++);
		delay(0x66ff33);
		led = 0;
	}
}

start.s文件:

Stack_size EQU  0x200;//定义宏堆栈尺寸
		AREA stack,NOINIT,READWRITE,ALIGN=3
			
Stack_1
	SPACE Stack_size   ;//此处占用x个字节的空间
Stack_2
	PRESERVE8          ;//8字节对齐;
	THUMB             ; //使用thumb类型的指令;	
	IMPORT main
		
	AREA RESET,DATA,READONLY
Vector  ;中断向量表
	DCD Stack_2  ;MSP堆栈栈顶地址
	DCD start     ;复位要执行的函数
	SPACE 0x400     ;为其他中断处理函数预留空间
		
	AREA mCODE,CODE,READONLY
start      PROC
	
	BL main
	B .     ;//死循环while(1)
	ENDP
	END

在这里插入图片描述
在这里插入图片描述

实验现象视频:https://www.bilibili.com/video/BV1Pi4y1x7q1

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Nydia~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值