在keil5中实现STM32f407流水灯点亮

    技术2026-06-10  1

    一、keil5中编写启动文件 在使用keil5时,如果没有提前选择好自带的启动文件,是需要我们自己写启动文件代码的,这里不针对讲解启动文件,只是放出代码供大家参考!

    Stack_size EQU 0x200 AREA my_stack,NOINIT,READWRITE,ALIGN=3 Stack_mem SPACE Stack_size Stack_end PRESERVE8 IMPORT main ;导入我们将写的C代码函数 AREA RESET,DATA,READONLY isr_addr DCD Stack_end DCD __start SPACE 0x400 AREA my_text,CODE,READONLY __start PROC

    二、编写C语言代码 1、在编写C语言代码之前,我们要先了解一下stm32f407开发板的原理图以及参考手册了解各个引脚所表示的含义; 2、既然是点亮我们的LED灯,首先我们得找到LED在开发板上的位置以及了解引脚的走线; 原理图中直接搜索LED,可以看到LED的结构,从图中我们可以的得到的结论是,四个LED灯左边全部连接在一个3.3V的VDD上,所以四个LED灯是共阳极,所以当我们右边的引脚得到低电平的时候,LED将被点亮! 搜索LED0可以看到在CPU上对应的引脚是PF9 依次类推分别可以得到 LED0 -> PF9 LED1 -> PF10 LED2 ->PE13 LED3 ->PE14

    我们人在生活中需要心脏的跳动,机器也是一样的,所以,我们首先需要的是时钟使能 由图片可知,要PF、PE可以使用,我们首先得使RCC寄存器的第四位和第五位置1 偏移地址:0x10

    寄存器地址 = 基址 + 偏移 由图可知,RCC的基址为0x40023800 我们还将使用到的有GPIOE、 GPIOF他们的基址分别为0x40021000、0x40021400 使能代码段:

    volatile unsigned long * pf_rcc = *(0x40023800 + 0x10) ; //定义RCC寄存器的地址 unsigned long m; m = *pf_rcc; m |= 1<<4; //将第四位置1(GPIOE使能) m |= 1<<5; //将第五位置1(GPIOF使能) *pf_rcc = m;

    设置好时钟使能以后,我们在使用引脚的过程中,会选择端口模式 在这个过程中,我们是通过输出高低电平来控制灯的亮灭,所以这里选择的是输出模式; 此时由图可知:[2y][2y+1] = [1][0] 由以上图可以偏移地址为:0x00 选择输出模式代码段

    volatile unsigned long * pf_mode = *(0x40021000 + 0x00) ; //GPIOE_MODER的地址 unsigned long m; m = *pf_mode; m &= ~(1<<27); //2y+1位置0 -> PE13 m |= 1<<26; //2y位置1 -> PE13 m &= ~(1<<29); //2y+1位置0 -> PE14 m |= 1<<28; //2y位置1 -> PE14 *pf_mode = m; volatile unsigned long * pf_mod = *(0x40021400 + 0x00) ; //GPIOF_MODER的地址 m = * pf_mod; m &= ~(1<<19); //2y+1位置0 -> PF9 m |= 1<<18; //2y位置1 -> PF9 m &= ~(1<<21); //2y+1位置0 -> PF10 m |= 1<<20; //2y位置1 -> PF10 * pf_mod = m;

    设置好模式以后,我们需要的是GPIO的输出类型 当我们的GPIO口输出高电平(1)的时候灯是灭的,输出低电平(0)的时候灯是亮的。

    由此我们可以知道: GPIOF_ODR[9] = 0; —> PF9 ->LED0得到是低电平 ->点亮 GPIOF_ODR[10] = 0; —> PF10 ->LED1得到是低电平 ->点亮 GPIOE_ODR[13] = 0; —> PE13 ->LED2得到是低电平 ->点亮 GPIOE_ODR[14] = 0; —> PE14 ->LED3得到是低电平 ->点亮

    GPIOF_ODR[9] = 1; —> PF9 ->LED0得到是低电平 ->熄灭 GPIOF_ODR[10] = 1; —> PF10 ->LED1得到是低电平 ->熄灭 GPIOE_ODR[13] = 1; —> PE13 ->LED2得到是低电平 ->熄灭 GPIOE_ODR[14] = 1; —> PE14 ->LED3得到是低电平 ->熄灭

    相关代码:

    volatile unsigned long * pf_odr = *(0x40021000 + 0x14) ; //GPIOE_ODR的地址 unsigned long r; r = *pf_odr; r |= 1<<13; //设置GPIOE_ODR[13] = 1 ,此时PE13 -> LED2灯灭 r &= ~(1<<13); //设置GPIOE_ODR[13] = 0 ,此时PE13 -> LED2灯亮 *pf_odr = r;

    其他的LED灯配置类似,可以自己先尝试着写一下完整的代码。 在设置过程中,我们还可以设置输出速率,感兴趣的可以自己去看一下相关文档自己写一下代码!

    为了方便观看,就没写头文件,把所有的函数全部直接写在一起了!

    #include<stdio.h> #define adda_base 0x40020000 #define adde_base 0x40021000 #define addf_base 0x40021400 #define addclock_base 0x40023800 #define offset_mode 0x00 #define offset_otype 0x04 #define offset_odr 0x14 #define offset_idr 0x10 #define offset_rcc 0x30 #define addr volatile unsigned long #define pf_rcc (addr *)(addclock_base + offset_rcc) #define pf_modeF (addr *)(addf_base + offset_mode) #define pf_modeE (addr *)(adde_base + offset_mode) #define pf_odrE (addr *)(adde_base + offset_odr) #define pf_odrF (addr *)(addf_base + offset_odr) void delay() //延时函数、延时的时间可以自己改 { int i; for(i=0;i<1000000;i++); } void led_init(void) { unsigned long r ; /* 使能GPIO分组时钟 */ r = *pf_rcc; r |= 1<<5; //使能GPIOF组时钟 r |= 1<<4; //使能GPIOE组时钟 *pf_rcc = r; /* 配置GPIO引脚模式 */ r = *pf_modeF; r &= ~(1<<19); //PF9配置为输出模式 GPIOF_MODER[19:18] = 01 r |= 1<<18; r &= ~(1<<21); //PF10配置为输出模式 GPIOF_MODER[21:20] = 01 r |= 1<<20; *pf_modeF = r; r = *pf_modeE; r &= ~(1<<27); //PF9配置为输出模式 GPIOF_MODER[19:18] = 01 r |= 1<<26; r &= ~(1<<29); //PF10配置为输出模式 GPIOF_MODER[21:20] = 01 r |= 1<<28; *pf_modeE = r; } void LED_UP_E(int x) //控制E组LED灯的亮 { unsigned long r = 0; r = *pf_odrE; r &= ~(1<<x); *pf_odrE = r; } void LED_DOWN_E(int x) //控制E组LED灯的灭 { unsigned long r = 0; r = *pf_odrE; r |= 1<<x; *pf_odrE = r; } void LED_UP_F(int x) //控制F组LED灯的亮 { unsigned long r = 0; r = *pf_odrF; r &= ~(1<<x); *pf_odrF = r; } void LED_DOWN_F(int x) //控制F组LED灯的亮 { unsigned long r = 0; r = *pf_odrF; r |= 1<<x; *pf_odrF = r; } int main() { //使能 led_init(); while(1) { //led0点亮 LED_UP_F(9); //延时 delay(); //led0熄灭 LED_DOWN_F(9); //led1点亮 LED_UP_F(10); //延时 delay(); //led1熄灭 LED_DOWN_F(10); //led2点亮 LED_UP_E(13); //延时 delay(); //led2熄灭 LED_DOWN_E(13); //led3点亮 LED_UP_E(14); //延时 delay(); //led3熄灭 LED_DOWN_E(14); delay(); } }

    代码没有使用头文件,所以看起来有点乱,感兴趣的可以自己封装一下,这是一步一步看原理图学习的一个过程,中间有什么不对或者遗漏的地方还请见谅,学到后面的话我们可以使用STM32的官方库,如果有幸看到此篇文章,感谢你的观看,希望能帮到你!

    Processed: 0.016, SQL: 9