一.寄存器配置LED灯的亮灭
1.首先看原理图
(1)对于我们拿到一个板子第一件事首先,可以查看它的电路原理图,看他的引脚有什么功能。比如,我找个32开发板的LED1是B引脚的8口,LED2是B引脚的9口。
(2)其次我要查看中文手册,我之前的博客都写过,可以翻看标准库的配置,其中,GPIO的配置都用APB2来配置。
(3)找到B引脚,因为这是我们需要用到的点亮LED的引脚
(4)看下面的引脚,配置,如果是1开启,如果是0则关闭。
(5)这时候我配置引脚他为1,其他的都为0。
RCC->APB2ENR=0x00000008;
2.寻找APB2外设寄存器
(1)找到端口配置高寄存器
(2)配置其中CNF和MOODE的模式
其中CNF的模式我设置为推挽输出;MOODE的模式设置为50HZ的最大输出。
GPIOB->CRH=0x00000030;
3.寻找端口输出寄存器
(1)首先我们找到了输出寄存器ODR
(2)其次我们找到了我们的引脚为9,我们先设置为高电平为1
GPIOB->ODR=0x00000000;
4.最终的代码
#include "stm32f10x.h" // Device header
#include "delay.h"
int main(void){
RCC->APB2ENR=0x00000008;
GPIOB->CRH=0x00000030;
GPIOB->ODR=0x00000000;
while(1){
}
}
二.标准库配置LED亮灭
1.配置Keil的环境
(1)创建Libaries
(2)使用里面的库函数
(3)内核资源src
(4)内核头文件inc
(5)我们还需在User目录下面继续添加一些文件,比如:头文件包含的文件、中断文件。
(6)我们还需一个宏定义
(7)找到并复制进去
2. 代码配置
(1)外设使能时钟RCC_APB2PeriphClockCmd。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//RCC的APB2是能外设控制
(2)库函数配置不会影响其他位的,因为已经帮我们封装好了。
(3)我们要配置结构体
GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化
(4)选择配置的模式
(5)ctrl+F,找这个配置的参数
(6)FIND NEXT
(7)跳转到相应的位置
(8)以此类推,配置下面的pin和Speed。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开时钟,RCC的APB2是能外设控制GPIO_InitTypeDef GPIO_InitStructure;//配置GPIO结构体
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9 | GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化
(9)配置高低电平
GPIO_ResetBits(GPIOB,GPIO_Pin_9 | GPIO_Pin_8);//配置低电平
GPIO_SetBits(GPIOB,GPIO_Pin_9 | GPIO_Pin_8);//配置高电平
三.了解GPIO
1.看懂GPIO电路图
(1)上面是输入部分、下面是输出部分。VDD是3.3v,下面VSS是0V
(2)输入数据
上拉、下拉是为了给输入电平默认的高低电平的。其中施密特触发器,用来限制高低电平的。用个阈值,来控制高低电平。
(3)输出数据寄存器
如果选择通过输出数据寄存器进行控制,就是普通的IO口输出,写这个数据寄存器的某一位就可以操作对应的某个端口了。
(4)位设置清除寄存器(库函数使用的方法)
可以用来单独操作输出数据寄存器的某一位,而不影响其他位。因为这个输出数据寄存器同时控制16个端回,并且这个寄存器只能整体读写。如果想单独控制其中某一个端口而不影响其他端口的话,需要特殊的方式。
第一种就是像读出这个寄存器,然后用按位与按位或的方式更改某一位。最后将更改后的数据写回去,在C语言中就是&=和|=的操作。这种方法比较麻烦,效率不高,对于IO口的操作而言不太合适。
如果我们对某一位进行置为1的操作,在位设置寄存器的对应位写1即可。剩下不需要操作的位写0,这样它内部会有电路。自动将输出数据寄存器中对应俭置为1。而剩下写0的俭则保持不变。
如果我们对某一位进行置为1的操作,在位清除寄存器的对应位写1即可。这样它内部会有电路。自动将输出数据寄存器中对应俭置为0。
(5)输出控制(推挽输出)
接下来输出控制之后就会接到两个MOS管,P-MOS\N-MOS就是开关。其中有三种模式:推挽、开漏、关闭。其中推挽输出俩个都可以用,如果输出高电平,P-MOS打开,下边关闭。如果输出低电平,P-MOS关闭,下边打开。
(6)输出控制(开漏输出)
开漏输出下,P-MOS无效,如果输出的高电平,则N-MOS断开。如果输出的低电平,则N-MOS导通。这个模式可以避免多机通信的相互干扰,比如:I2C协议。
还可以在I/O引脚接一个上拉电阻5V的电源。当输出高电平时,由外部的上拉电阻拉高至5V。
如果设置位输入模式,输出模式自动断开。
(7)GPIO模式(8种工作模式)
(8)开漏/推挽输出
(9)复用开漏/推挽输出
四.硬件电路图
1.图是使用STM32的GPIO口驱动LED的电路
(1)低电平驱动电路,LED极接3.3V。负极通过一个限流电阻接到PAO上,当PAO输出低电平时。LED两端就会产生电压差,就会导通点亮LED。
如果当PAO输出高电平时。LED两端都是3.3V,不导通不点亮LED。
(2)LD负极接GND。正极通过一企限流电阻接到PAO上,这时候就是高电平点亮,低电平熄灭了。
2.三极管
(1)PNP,需要输出低电平才能导通。三极管的边是基极。带箭头的是发射极。剩下的是集电极
(2) NPN,需要输出高电平才能导通。三极管的边是基极。带箭头的是发射极。剩下的是集电极。这是因为堂极管的通断。是需要在发射极和基极直接产生定的开启电压的。
(3)另外注意一下。这个PNP的极管最好接在上边。NPN的三极管最好接在下边。如果你把负载接在发射极这边。可能会导致三极管必不能能启
3.批处理文件夹
1.它可以把工程中间产生的中间文件删掉,把他放到工程目录下面。因为工程编译产生的文件比较大,有20M,我们需要把它讲解,所以就可以加入批处理文件进行文件清理。主要占空闻的就是Listing和Objects这两个文件卖。这些都是工程的中间文件夹。
4.我们主要用的RCC也就是下面的几个声明函数
5.常用的GPIO函数
6.GPIO的几种工作模式
typedef enum
{ GPIO_Mode_AIN = 0x0,//模拟输入
GPIO_Mode_IN_FLOATING = 0x04,//浮空输入
GPIO_Mode_IPD = 0x28,//下拉输入
GPIO_Mode_IPU = 0x48,//上拉输入
GPIO_Mode_Out_OD = 0x14,//开漏输出
GPIO_Mode_Out_PP = 0x10,//推挽输出
GPIO_Mode_AF_OD = 0x1C,//复用开漏
GPIO_Mode_AF_PP = 0x18//复用推挽
}GPIOMode_TypeDef;
7.三种实现控制LED灯灭的方法
//方式一,置为高低电平
GPIO_ResetBits(GPIOB,GPIO_Pin_9);
Delay_ms(500);
GPIO_SetBits(GPIOB,GPIO_Pin_9);
Delay_ms(300);
GPIO_ResetBits(GPIOB,GPIO_Pin_8);
Delay_ms(500);
GPIO_SetBits(GPIOB,GPIO_Pin_8);
Delay_ms(300);
//方式二,置为高低电平
GPIO_WriteBit(GPIOB,GPIO_Pin_9,Bit_RESET);
Delay_ms(200);
GPIO_WriteBit(GPIOB,GPIO_Pin_9,Bit_SET);
Delay_ms(100);
GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_RESET);
Delay_ms(200);
GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_SET);
Delay_ms(100);
//方式三,置为高低电平
GPIO_WriteBit(GPIOB,GPIO_Pin_9,(BitAction)0);//枚举类型,强制类型转换
Delay_ms(200);
GPIO_WriteBit(GPIOB,GPIO_Pin_9,(BitAction)1);
Delay_ms(100);
GPIO_WriteBit(GPIOB,GPIO_Pin_8,(BitAction)0);
Delay_ms(200);
GPIO_WriteBit(GPIOB,GPIO_Pin_8,(BitAction)1);
Delay_ms(100);
我们用的推挽输出,因为你使用的时候,无论是高还是低电平,他们都有驱动能力,如果你用的是开漏输出,那么就会造成高电平没有驱动能力。
8.按位或可以初始化多个引脚
1.时钟控制也可以用,按位或进行操作,选择多个外设。
GPIO_Write(GPIOB,~0x0100);//高电平
Delay_ms(200);
GPIO_Write(GPIOB,0x0100);//低电平
Delay_ms(200);
GPIO_Write(GPIOB,~0x0200);//高电平
Delay_ms(200);
GPIO_Write(GPIOB,0x0200);//低电平
Delay_ms(200);