2021.4.13第三次 STM32跑马灯的三种实现方式

STM32 跑马灯实验介绍及三种实现方法

三种方法:

1. 基于库函数h
2. 基于寄存器
3. 位操作
一. 基于库函数h
1.1 硬件连接

用到的硬件只有 LED(DS0 和 DS1)。其电路在 ALIENTEK MiniSTM32 开发板上默认是已经连接好了的。DS0 接 PA8,DS1 接 PD2。所以在硬件上不需要动任何东西。

在这里插入图片描述
在这里插入图片描述
IO口输出高电平,LED灭,IO口输出低电平,LED亮
GPIO的输出方式是推挽输出

库函数:
头文件:stm32f10x_gpio.h
源文件:stm32f10x_gpio.c

1.2 编写流程:

1 使能IO口时钟,调用函数RCC_APB2PeriphColckCmd()
2 初始化IO口模式。调用函数GPIO_Init();
3 操作IO口,输出高低电平。
GPIO_Setbits();
GPIO_ResetBit();

编写led.c

#include "led.h"

//初始化PA8和PD2为输出口.并使能这两个口的时钟		    
//LED IO初始化
void LED_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);	 //使能PA,PD端口时钟
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;				 //LED0-->PA.8 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOA, &GPIO_InitStructure);					 //根据设定参数初始化GPIOA.8
 GPIO_SetBits(GPIOA,GPIO_Pin_8);						 //PA.8 输出高

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;	    		 //LED1-->PD.2 端口配置, 推挽输出
 GPIO_Init(GPIOD, &GPIO_InitStructure);	  				 //推挽输出 ,IO口速度为50MHz
 GPIO_SetBits(GPIOD,GPIO_Pin_2); 						 //PD.2 输出高 
}
 

编写led.h

#ifndef __LED_H
#define __LED_H	 
#include "sys.h"

#define LED0 PAout(8)	// PA8
#define LED1 PDout(2)	// PD2	

void LED_Init(void);//初始化

		 				    
#endif

main函数

#include "led.h"
#include "delay.h"
#include "sys.h"

 int main(void)
 {	
	delay_init();	    	 //延时函数初始化	  
	LED_Init();		  	//初始化与LED连接的硬件接口
	while(1)
	{
		LED0=0;
		LED1=1;
		delay_ms(300);	 //延时300ms
		LED0=1;
		LED1=0;
		delay_ms(300);	//延时300ms
	}
 }


寄存器版本

1.IO介绍

STM32 的 IO 口可以由软件配置成如下 8 种模式:
1、输入浮空
2、输入上拉
3、输入下拉
4、模拟输入
5、开漏输出
6、推挽输出
7、推挽式复用功能
8、开漏复用功能

STM32 的每个 IO 端口都有 7 个寄存器来控制。他们分别是:配置模式的 2 个 32 位的端口
配置寄存器 CRL 和 CRH;2 个 32 位的数据寄存器 IDR 和 ODR;1 个 32 位的置位/复位寄存器
BSRR;一个 16 位的复位寄存器 BRR;1 个 32 位的锁存寄存器 LCKR;这里我们仅介绍常用 的
几个寄存器,我们常用的 IO 端口寄存器只有 4 个:CRL、CRH、IDR ODR。
CRL 和 CRH 控制着每个 IO 口的模式及输出速率。

1.2 编写流程

1 使能IO口时钟。配置寄存器RCC APB2ENR。
2 初始化IO口模式。配置寄存器GPIOx_CRH/CRL
3 操作IO口,输出高低电平。配置寄存器
GPIO_ODR或BSRR/BRR。

编写led.c

#include "sys.h"   
#include "led.h"

//初始化PA8和PD2为输出口.并使能这两个口的时钟		    
//LED IO初始化
void LED_Init(void)
{
	RCC->APB2ENR|=1<<2;    //使能PORTA时钟	   	 
	RCC->APB2ENR|=1<<5;    //使能PORTD时钟	   	 
	GPIOA->CRH&=0XFFFFFFF0; 
	GPIOA->CRH|=0X00000003;//PA8 推挽输出   	 
    GPIOA->ODR|=1<<8;      //PA8 输出高
											  
	GPIOD->CRL&=0XFFFFF0FF;
	GPIOD->CRL|=0X00000300;//PD.2推挽输出
	GPIOD->ODR|=1<<2;      //PD.2输出高 
}

编写led.h

#ifndef __LED_H
#define __LED_H	 
#include "sys.h"

//LED端口定义
#define LED0 PAout(8)	// PA8
#define LED1 PDout(2)	// PD2	

void LED_Init(void);	//初始化		 				    
#endif

编写main.c

#include "sys.h"
#include "usart.h"		
#include "delay.h"	
#include "led.h" 

int main(void)
{		 
	Stm32_Clock_Init(9); 	//系统时钟设置
	delay_init(72);	     	//延时初始化
	LED_Init();		  	 	//初始化与LED连接的硬件接口    
	while(1)
	{
		LED0=0;
		LED1=1;
		delay_ms(300);
		LED0=1;
		LED1=0;
		delay_ms(300);
	}	 
}

位带操作

1.1 位带操作的介绍及基本原理

位操作的本质目的就是操作寄存器

1 位操作比较方便操作IO口

2 位操作原理
把每个比特膨胀为一个32位的字,当访问这些字的时候就达到了访问
比特的目的,比如说BSRR寄存器有32个位,那么可以映射到32个地址
上,我们去访问(读-改-写)这32个地址就达到访问32个比特的目的。

3 哪些区域支持位操作
其中一个是 SRAM 区的最低 1MB 范围,
0x20000000 ‐ 0x200FFFFF(SRAM 区中的最低 1MB)
第二个则是片内外设区的最低 1MB范围,
0x40000000 ‐ 0x400FFFFF(片上外设区中最低 1MB)

4 sys.h里面对GPIO输入输出部分功能实现了位带操作

5 最终输出都操作了ODR寄存器

编写流程

1 使能IO口时钟。调用函数RCC_APB2PeriphphColckCmd();
2 初始化IO口模式。调用函数GPIO_Init();
3 操作IO口,输出高低电平(使用位带操作)

编写led.c

#include "led.h"

//初始化PA8和PD2为输出口.并使能这两个口的时钟		    
//LED IO初始化
void LED_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);	 //使能PA,PD端口时钟
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;				 //LED0-->PA.8 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOA, &GPIO_InitStructure);					 //根据设定参数初始化GPIOA.8
 GPIO_SetBits(GPIOA,GPIO_Pin_8);						 //PA.8 输出高

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;	    		 //LED1-->PD.2 端口配置, 推挽输出
 GPIO_Init(GPIOD, &GPIO_InitStructure);	  				 //推挽输出 ,IO口速度为50MHz
 GPIO_SetBits(GPIOD,GPIO_Pin_2); 						 //PD.2 输出高 
}

编写main.c

#include "led.h"
#include "delay.h"
#include "sys.h"

 int main(void)
 {	
	delay_init();	    	 //延时函数初始化	  
	LED_Init();		  	//初始化与LED连接的硬件接口
	while(1)
	{
		PAout(5)=1;
		PDout(5)=1;
		delay_ms(500);	 //延时500ms
	    PAout(5)=1;
		PDout(5)=1;	
	}
 }
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值