硬件电路图
查看电路图可知,当输出高电平时候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);
}
}
评论(0)
您还未登录,请登录后发表或查看评论