硬件电路图

在这里插入图片描述

查看电路图可知,当输出高电平时候LED灭,输出低电平时LED亮。
  GPIO输出方式:推挽输出。
  LED0是连接GPIO_B中的第5个引脚。
  LED1是连接GPIO_E中的第5个引脚。

前面设置与前篇一致,主要修改的地方就是main.c、led.c。
led.h与前面一致,程序如下:

#ifndef __LED_H
#define __LED_H
	void LED_Init(void);
#endif


led.c编写

第一步:使能IO口时钟。配置寄存器RCC_APB2ENR。

  打开STM32中文参考手册,先找到第七章中关于RCC寄存器(APB2外设使能寄存器),找到可以发现以下:

在这里插入图片描述
  根据电路图可知,我们需要对IO端口B和E的时钟进行使能,有根据手册可知是第6位置和第3位置置为1表示开启。

在这里插入图片描述
在这里插入图片描述

那么怎么进行这样的设置呢?
打开“Project”菜单栏中的“SYSTEM”文件夹下的“delay.c”中找到“stm32f10x.h”的头文件,找到RCC(利用快捷键Ctrl+F进行查找)可找到以下结构体:

typedef struct
{
  __IO uint32_t CR;
  __IO uint32_t CFGR;
  __IO uint32_t CIR;
  __IO uint32_t APB2RSTR;
  __IO uint32_t APB1RSTR;
  __IO uint32_t AHBENR;
  __IO uint32_t APB2ENR;
  __IO uint32_t APB1ENR;
  __IO uint32_t BDCR;
  __IO uint32_t CSR;

#ifdef STM32F10X_CL  
  __IO uint32_t AHBRSTR;
  __IO uint32_t CFGR2;
#endif /* STM32F10X_CL */ 

#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)   
  uint32_t RESERVED0;
  __IO uint32_t CFGR2;
#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */ 
} RCC_TypeDef;

根据该结构体和参考手册可得以下程序:

#include "led.h"
#include "stm32f10x.h"

void LED_Init()void{
	RCC->APB2ENR|=1<<6;//|= 位或,在不影响其他位的情况下,将第六位置为1(1向左移6位)
	RCC->APB2ENR|=1<<3;//|= 位或,在不影响其他位的情况下,将第三位置为1(1向左移6位)
}

第二步:初始化IO口模式。配置寄存器GPIOx_CRH/CRL
再找到参考手册第八章中关于GPIO寄存器章节,前面学习篇2中已经介绍了关于GPIO寄存器的相关知识,我们从这边知道,我们要点亮的是GPIO中的B组和E组中的第5个引脚(寄存器CRL的范围就是0~7,每4位控制一个IO口)。
在这里插入图片描述

可知引脚5要配置的是20~23位置的,根据下面的数值,我们要选择填写的是:0011,程序变为:

#include "led.h"
#include "stm32f10x.h"

void LED_Init()void{
	RCC->APB2ENR|=1<<6;//|= 位或,在不影响其他位的情况下,将第六位置为1(1向左移6位)
	RCC->APB2ENR|=1<<3;//|= 位或,在不影响其他位的情况下,将第三位置为1(1向左移6位)
	
	GPIOB->CRL&=0xFF0FFFFF;//先对20~23位清空,为不影响其他位置,其他位置1,清空位置0再进行位与,(采用十六进制),
	GPIOB->CRL|=0x00300000;//对20~23位填写0011(十六进制3),其他位置0,不产生影响

	GPIOE->CRL&=0xFF0FFFFF;//先对20~23位清空,为不影响其他位置,其他位置1,清空位置0再进行位与,(采用十六进制),
	GPIOE->CRL|=0x00300000;//对20~23位填写0011(十六进制3),其他位置0,不产生影响	
}

第三步:操作IO口,输出高低电平。配置寄存器GPIOX_ODR或者BSRR/BRR。

到参考手册第八章中关于GPIO寄存器章节,


在这里插入图片描述

观察手册知道,寄存器ODR就是控制对应引脚的高低电平,每组16位,与寄存器ODR的低16位一致,故若想让LED灯刚开始是灭的,需要输出高电平,那么就将对应的位置1即可,程序可修改为:

#include "led.h"
#include "stm32f10x.h"

void LED_Init(void){
	RCC->APB2ENR|=1<<6;//|= 位或,在不影响其他位的情况下,将第六位置为1(1向左移6位)
	RCC->APB2ENR|=1<<3;//|= 位或,在不影响其他位的情况下,将第三位置为1(1向左移6位)
	
	GPIOB->CRL&=0xFF0FFFFF;//先对20~23位清空,为不影响其他位置,其他位置1,清空位置0再进行位与,(采用十六进制),
	GPIOB->CRL|=0x00300000;//对20~23位填写0011(十六进制3),其他位置0,不产生影响
	GPIOB->ODR|=1<<5;//先将1左移5个位置,第6位进行位或变为1,输出高电平
	
	GPIOE->CRL&=0xFF0FFFFF;//先对20~23位清空,为不影响其他位置,其他位置1,清空位置0再进行位与,(采用十六进制),
	GPIOE->CRL|=0x00300000;//对20~23位填写0011(十六进制3),其他位置0,不产生影响	
	GPIOE->ODR|=1<<5;//先将1左移5个位置,第6位进行位或变为1,输出高电平
}
}

main.c编写

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"

int main(void){
	delay_init();
	LED_Init();
	while(1){
		GPIOB->ODR|=1<<5;//先将1左移5个位置,第6位进行位或变为1,输出高电平
		GPIOE->ODR|=1<<5;//先将1左移5个位置,第6位进行位或变为1,输出高电平
		delay_ms(500);
		GPIOB->ODR&=~(1<<5);//先将1左移5个位置变为:00100000,在取反:11011111,在进行位与(就第6位变为0,其他位不变)
		GPIOE->ODR&=~(1<<5);//先将1左移5个位置变为:00100000,在取反:11011111,在进行位与(就第6位变为0,其他位不变)
		delay_ms(500);
	}
}