【STM32学习笔记】跑马灯实验

目录

库函数ver.

原理

1.使能IO口时钟

2.初始化IO口模式

3.操作IO口输出高低电平

代码

1. LED.c

2.main.c

寄存器ver.

原理

1.使能IO口时钟

2.初始化IO口模式

3.操作IO口输出高低电平

代码

1.LED.c

2.main.c

位操作ver.

位操作原理

位操作优点

程序原理

代码

1.LED.c

2.main.c

 3. sys.h 节选


库函数ver.

原理

1.使能IO口时钟

        RCC_APB2PeriphClockCmd()

这里需要了解一下时钟的作用:

        首先,寄存器是基于D触发器的(D触发器属于寄存器),想要往触发器里面写东西,前提条件是有时钟输入。换句话说,只有给触发器送来了时钟,触发器才能被改写值,这样寄存器才会工作。

        STM32是低功耗的,即采用了时钟门控的技术。其所有的门都默认设置为disable(不使能),如果要使用,就需要让其enable(使能),也就是说用到什么外设,只要打开对应外设的时钟就可以

2.初始化IO口模式

        调用GPIO_Init()

3.操作IO口输出高低电平

        GPIO_SetBits()  高电平              GPIO_ResetBits()   低电平

代码

1. LED.c

        包括使能IO口时钟,初始化IO口模式

#include "stm32f10x.h"                  // Device header
#include "LED.h"

void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	/*使能时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//使能GPIOE的时钟
	
	/*GPIOB初始化*/
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽模式
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; //GPIOB5
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //最大输出速度
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	/*GPIOE初始化**/
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽模式
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; //GPIOE5
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //最大输出速度
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	
	/*将接LED的引脚置为高电平,使LED不亮*/
	GPIO_SetBits(GPIOB,GPIO_Pin_5);
	GPIO_SetBits(GPIOE,GPIO_Pin_5);
	
}

/* LED.h 

#ifndef _LED_H_
#define _LED_H_

#include "sys.h" //为了引用端口

//LED 端口定义
#define LED0 PBout(5)// DS0
#define LED1 PEout(5)// DS1

void LED_Init(void);

#endif
*/

2.main.c

        包括反复操作IO口输出高低电平,对delay初始化,调用delay函数

#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "delay.h"

int main()
{
	LED_Init(); //LED初始化
	delay_init(); //delay初始化
	
	while(1)
	{
        /* 对IO口置高电平,LED不亮 */
		GPIO_SetBits(GPIOB,GPIO_Pin_5);
		GPIO_SetBits(GPIOE,GPIO_Pin_5);
		
		delay_ms(500);
		
        /* 对IO口置低电平,LED亮 */
		GPIO_ResetBits(GPIOB,GPIO_Pin_5);
		GPIO_ResetBits(GPIOE,GPIO_Pin_5);
		
		delay_ms(500);
	}
	
}

寄存器ver.

原理

1.使能IO口时钟

        配置寄存器RCC_APB2ENR

                RCC寄存器是一个用于控制系统时钟和外设时钟的寄存器,其包括APB2 外设时钟使能          寄存器(RCC_APB2ENR),因为GPIO都挂载到APB2总线上,故使能IO口的时钟也就是配置          寄存器RCC_APB2ENR的对应位,使其为1(ENABLE)

2.初始化IO口模式

        配置寄存器GPIOx_CRH/CRL

3.操作IO口输出高低电平

        配置寄存器GPIOx_ODR或BSRR,BRR

代码

1.LED.c

        包括使能IO口时钟,初始化IO口模式

#include "stm32f10x.h"                  // Device header
#include "LED.h"

void LED_Init()
{
	/*直接配置RCC_APB2ENR对应位,使能IO口的时钟*/
	RCC->APB2ENR |= 1 << 3; //使能GPIOB
	RCC->APB2ENR |= 1 << 6; //使能GPIOE
	
	/*GPIOB5初始化*/
	GPIOB->CRL &= 0xFF0FFFFF; //只对CRL寄存器内控制PB5的位清零
	GPIOB->CRL |= 0x00300000;
	//让CRL寄存器内控制PB5的位表示为推挽输出模式,50MHz
	
	/*GPIOE5初始化*/
	GPIOE->CRL &= 0xFF0FFFFF; //只对CRL寄存器内控制PE5的位清零
	GPIOE->CRL |= 0x00300000;
	//让CRL寄存器内控制PE5的位表示为推挽输出模式,50MHz
	
	/*直接控制ODR寄存器,使IO口输出高电平,LED初始为灭*/
	GPIOB->ODR |= 1 << 5;
	GPIOE->ODR |= 1 << 5;
	
}

/* LED.h
#ifndef _LED_H_
#define _LED_H_

#include "sys.h" //为了引用端口

//LED 端口定义
#define LED0 PBout(5)// DS0
#define LED1 PEout(5)// DS1

void LED_Init(void);

#endif
*/

需要非常注意的是:在声明函数时,如果函数没有形参,应在参数表内写入"void",否则keil会报错!!!

2.main.c

        包括直接操作ODR寄存器改变IO口电平设置系统时钟,对delay函数初始化(寄存器ver.的需要系统时钟作为参数)

#include "stm32f10x.h"                  // Device header
#include "delay.h"
#include "LED.h"

int main()
{
	Stm32_Clock_Init(9);
    //设置系统时钟,配置系统时钟为 9 倍频,即8(外部晶振8Mhz)*9(倍频) == 72MHz
	delay_init(72); //寄存器ver.的delay初始化函数需要系统时钟作为参数
	LED_Init();
	
	while(1)
	{
		GPIOB->ODR |= 1 << 5;
		GPIOE->ODR |= 1 << 5;
		
		delay_ms(500);
		
		GPIOB->ODR &= ~(1 << 5);
		GPIOE->ODR &= ~(1 << 5);
		
		delay_ms(500);
		
	}	
}

位操作ver.

位操作原理

        位带别名区把寄存器的每个位都膨胀为一个32bit的字,当你通过位带别名区去访问这些字,或是说去访问这映射的32个地址时,就可以达到访问原始比特的目的

位操作优点

        1.系统读写数据更方便,效率更高

        2.代码更简洁

程序原理

        使能时钟,初始化IO口可参考库函数ver.的

        唯一的改变就是利用位操作控制IO口输出高低电平

代码

        涉及的位操作函数在 sys.h

1.LED.c

        参考前文库函数ver.

2.main.c

#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "delay.h"

int main()
{
	LED_Init();
	delay_init();
	
	while(1)
	{
		PBout(5) = 1;
		PEout(5) = 1;
		delay_ms(500);
		
		PBout(5) = 0;
		PEout(5) = 0;
		delay_ms(500);
	}
	
}

 3. sys.h 节选

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值