学习笔记四(基于固件库|寄存器的跑马灯实验)

硬件连接

本实验用到的硬件只有 LED(DS0 和 DS1)。其电路在 ALIENTEK 探索者 STM32F4 开发板 上默认是已经连接好了的。DS0 接 PF9,DS1 接 PF10。所以在硬件上不需要动任何东西。
在这里插入图片描述
因为LED的右端接了高电压所以左端引脚输出高电压时LED不亮,输出低电压时LED亮。

基于固件库的跑马灯实验

  1. 在我们的程序源码固件库实验文件夹中复制一个空实验模板,在里面新建一个HARDWARE文件夹,用于存放我们的硬件配置,在HARDWARE下新建一个LED文件夹并在里面新建一个led.c文件和led.h文件,从USER中打开Keil并把我们新建的文件添加到工程中。
  2. 删除main.c中的所有内容;可以删除我们导入工程的FWLIB中的没有用到的文件以提高编译速度,本次实验要用到的有misc.c、stm32f4xx_gpio.c、stm32f4xx_rcc.c、stm32f4xx_usart.c。在这里插入图片描述
  3. 在led.h中写入以下代码
#ifndef LED_H
#define LED_H
void LED_Init(void);
#endif

#ifndef x //先测试x是否被宏定义过
#define x //如果没有宏定义下面就宏定义x并编译下面的语句
#endif //如果已经定义了则编译#endif 后面的语句
4. 接下来我们编写led.c中的代码,先引入头文件并写入初始化函数框架

#include "stm32f4xx.h"
#include "led.h"
void LED_Init(void)
{}

接下来是使能 AHB1 总线上的 GPIOF 时钟
先找到FWLIB下的stm32f4xx_rcc.c下的stm32f4xx_rcc.h中相应的函数如图所示被选中的语句在这里插入图片描述
将函数名复制过来,选中我们的函数点击F12键就可以自动跳转到函数定义的位置如图
在这里插入图片描述
这个函数需要两个参数,把光标放到1529行的IS_RCC_AHB1_CLOCK_PERIPH上点击F12键就跳转到我们可以输入的参数内容范围如图
在这里插入图片描述
我们选择GPIOF那一个宏定义并复制到我们的函数中作为第一个参数,第二个参数的操作和上面类似我们选择ENABLE使能。

  1. 接下来我们初始化GPIO,先引用函数GPIO_Init() 用同样的方法跳转的相应的函数体,这个函数有两个参数其中第二个参数是一个结构体;用和上面相似的方法查询第一个参数并复制GPIOF作为函数的第一个参数,然后我们在GPIOF_Init() 上面建一个结构体,其定义一定要在第一行
 GPIO_InitTypeDef GPIO_InitStructure;
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0 和 LED1 对应 IO 口
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉

具体的参数参照上面的方法进行查找和复制。
然后设置输出的初始值GPIO_SetBits() 函数为输出高电压,GPIO_ResetBits()函数为输出低电压。在此为了让LED灭所以输出高电压

GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);

led.c中的代码如下

#include "stm32f4xx.h"
#include "led.h"
void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_Initer;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
	GPIO_Initer.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_Initer.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;
	GPIO_Initer.GPIO_OType=GPIO_OType_PP;
	GPIO_Initer.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_Initer.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOF,&GPIO_Initer);
	
	GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
}
  1. 接下来编写main.c中的代码,
#include "stm32f4xx.h"
#include "led.h"
#include "delay.h"//为了使用延时函数

int main(void)
{
   delay_init(168);//初始化延时函数
   LED_Init();//初始化LED端口
   while(1)
   {
   	GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);//LED灭
   	delay_ms(500);//延时500ms
   	GPIO_ResetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);//LED亮
   	delay_ms(500);	
   }
}

编译后就可以下载到我们的开发板上并运行,然后就可以看到两个LED灯在闪烁。

基于寄存器的跑马灯实验

前几个步骤和上面一样,不一样的是led.c、main.c 中的代码不一样;
我们要参考STM32F4xx中文参考手册。

  1. 首先在led.c的函数体中输入RCC->这时我们选择第一个AHB1ENR,然后我们查阅手册,找到RCC寄存器下的RCC AHB1 外设时钟使能寄存器 (RCC_AHB1ENR) 发现GPIOF位于第6个位在这里插入图片描述然后找到下面的位5 在这里插入图片描述所以我们应该应该让第6位为1其他位不变,将其写入我们的代码。
  2. 然后开始初始化LED
    GPIOF->MODER&=~(3<<(9*2));
	GPIOF->MODER|=1<<(9*2);
	
	GPIOF->OSPEEDR&=~(3<<(9*2));
	GPIOF->OSPEEDR|=2<<(9*2);
	
	GPIOF->OTYPER&=~(1<<9);
	
	GPIOF->PUPDR&=~(3<<(9*2));
	GPIOF->PUPDR|=1<<(9*2);

相应的原因应该查询手册,同理我们初始化PF10。
3. 设置LED的初始状态为下面的代码

 GPIOF->ODR|=1<<9;//输出高电压
 GPIOF->ODR|=1<<10;//输出高电压

led.c中的代码如下

#include "stm32f4xx.h"
#include "led.h"
void LED_Init(void)
{
RCC->AHB1ENR|=1<<5;
//PF9
   GPIOF->MODER&=~(3<<(9*2));
   GPIOF->MODER|=1<<(9*2);
   
   GPIOF->OSPEEDR&=~(3<<(9*2));
   GPIOF->OSPEEDR|=2<<(9*2);
   
   GPIOF->OTYPER&=~(1<<9);
   
   GPIOF->PUPDR&=~(3<<(9*2));
   GPIOF->PUPDR|=1<<(9*2);
   
   GPIOF->ODR|=1<<9;
   
   //PF10
   GPIOF->MODER&=~(3<<(10*2));
   GPIOF->MODER|=1<<(10*2);
   
   GPIOF->OSPEEDR&=~(3<<(10*2));
   GPIOF->OSPEEDR|=2<<(10*2);
   
   GPIOF->OTYPER&=~(1<<10);
   
   GPIOF->PUPDR&=~(3<<(10*2));
   GPIOF->PUPDR|=1<<(10*2);
   
   GPIOF->ODR|=1<<10;
}
  1. main.c中只需要将while下面的库函数操作改为寄存器操作即可。代码如下
#include "stm32f4xx.h"
#include "led.h"
#include "delay.h"
int main(void)
{
   delay_init(168);
   LED_Init();
   while(1)
   {
   	GPIOF->ODR|=1<<9;
   	GPIOF->ODR|=1<<10;
   	delay_ms(500);
   	GPIOF->ODR&=~(1<<9);
   	GPIOF->ODR&=~(1<<10);
   	delay_ms(500);
   }
}

编译后就可以下载到我们的开发板上并运行,然后就可以看到两个LED灯在闪烁。

位操作

是将32个位膨胀为32个地址,我们通过操作相应的地址来达到操作位的目的比较方便。
支持位操作的区域:
其中一个是 SRAM 区的最低 1MB 范围,0x20000000 ‐ 0x200FFFFF(SRAM 区中的最低 1MB)
第二个则是片内外设区的最低 1MB范围,0x40000000 ‐ 0x400FFFFF(片上外设区中最低 1MB)
在SYSTEM下的sys.h 中有位操作的映射,对于我们的跑马灯实验想要控制PF9的输出就需要用到PFout(9)=1,来输出高电压;PFout(9)=0,来输出低电压;因此main.c中的代码可以修改为

#include "stm32f4xx.h"
#include "led.h"
#include "delay.h"
int main(void)
{
	delay_init(168);
	LED_Init();
	while(1)
	{
		PFout(9)=1;
		PFout(10)=1;
		delay_ms(500);
		PFout(9)=0;
		PFout(10)=0;
		delay_ms(500);
	}
}

运行结果

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值