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