库函数版本
硬件连接
(在开发指南中寻找对应元件的连接原理图)
GPIO库函数
头文件:stm32f10x_gpio.h
源文件:stm32f10x_gpio.c
1个初始化函数:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
作用:初始化一个或者多个IO口(同一组)的工作方式和速度。
该函数主要是操作GPIO_CRL(CRH)寄存器,在上拉或者下拉的时候有设置BSRR或者BRR寄存器
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
(可以一次初始化一个IO组下的多个IO,前提是这些IO口的配置方式一样。)
2个读取输入电平函数:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);//读取GPIOA.5的输入电平
GPIO_ReadInputData(GPIOA);//读取GPIOA组中所有io口输入电平
2个读取输出电平函数:
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_5);//读取GPIOA.5的输出电平
GPIO_ReadOutputData(GPIOA);//读取GPIOA组中所有io口输出电平
4个设置输出电平函数:
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
作用:设置某个IO口输出为高电平(实际操作BSRR寄存器)
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
作用:设置某个IO口输出为低电平(实际操作的BRR寄存器)
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
(不常用,也是用来设置IO口输出电平)
详细步骤
使能IO口时钟。调用函数RCC_APB2PeriphColckCmd(); //相当于打开寄存器开关
(不同的IO组,调用的时钟使能函数不一样。)
初始化IO口模式。调用函数GPIO_Init();
操作IO口,输出高低电平。
GPIO_SetBits();
GPIO_ResetBits();
代码
main.c
#include "delay.h"
#include "led.h"
int main(void)
{
delay_init(); //初始化延时函数
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_5); //LED=0
GPIO_SetBits(GPIOE,GPIO_Pin_5); //LED1=1;
delay_ms(300); //延时300ms
GPIO_SetBits(GPIOB,GPIO_Pin_5); //LED0=1;
GPIO_ResetBits(GPIOE,GPIO_Pin_5); //LED1=0;
delay_ms(300);
}
}
led.h
#ifndef __LED_H
#define __LED_H
void LED_Init(void);
#endif
led.c
#include"led.h"
#include"stm32f10x.h"
//LED IO口初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //创建一个GPIO_InitTypeDef类型的结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB、PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口设置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50HZ
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设置参数 初始化IO口
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5输出高电平
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
}
寄存器版本
步骤
使能IO口时钟。配置寄存器RCC_APB2ENR。
初始化IO口模式。配置寄存器GPIOx_CRH/CRL
操作IO口,输出高低电平。配置寄存器GPIOX_ODR或者BSRR/BRR。
代码
int main(void)
{
delay_init();
LED_Init();
while(1)
{
GPIOB->BRR=GPIO_Pin_5;
GPIOE->BSRR=GPIO_Pin_5;
delay_ms(300);
GPIOB->BSRR=GPIO_Pin_5;
GPIOE->BRR=GPIO_Pin_5;
delay_ms(300);
}
}
位操作
原理
把每个比特膨胀为一个32位的字,当访问这些字的时候就达到了访问比特的目的,比如说BSRR寄存器有32个位,那么可以映射到32个地址上,我们去访问(读-改-写)这32个地址就达到访问32个比特的目的。
支持位操作的区域
其中一个是 SRAM 区的最低 1MB 范围,0x20000000 ‐ 0x200FFFFF(SRAM 区中的最低 1MB)
第二个则是片内外设区的最低 1MB范围,0x40000000 ‐ 0x400FFFFF(片上外设区中最低 1MB
位带操作优点
led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PBout(5) // 端口定义
#define LED1 PEout(5)
void LED_Init(void);
#endif
#include "led.h"
void LED_Init(void)
{
RCC->APB2ENR|=1<<3; //使能PORTB时钟
RCC->APB2ENR|=1<<6; //使能PORTE时钟
GPIOB->CRL&=0XFF0FFFFF;
GPIOB->CRL|=0X00300000;//PB.5 推挽输出
GPIOB->ODR|=1<<5; //PB.5输出高电平
GPIOE->CRL&=0XFF0FFFFF;
GPIOE->CRL|=0X00300000;//PE.5推挽输出
GPIOE->ODR|=1<<5; //PE.5输出高电平
}
main.h
include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
{
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);
}
}