其他外部设备的介绍可以看我在51单片机中的介绍,这里就只看一下其他外部设备在STM32上的电路图


目录

一、外部设备电路图

1、LED硬件电路图

2、蜂鸣器硬件电路

二、面包板

三、LED闪烁

1、硬件接线图

2、常用函数

(1)RCC库函数常用函数

(2)GPIO库函数常用函数

3、keilkill工具

4、增加延时函数

5、程序

6、实物展示

 四、LED流水灯

1、硬件接线图

2、程序

3、实物展示

 五、蜂鸣器

1、硬件接线图

2、程序

3、实物展示


一、外部设备电路图

1、LED硬件电路图

        上面图是低电平驱动的电路,LED正极接3.3V,负极通过一个限流电阻接到PA0上,当PA0输出低电平时,LED两端就会产生电压差,就会形成向左导通的电流,这样LED就会被点亮了;当PA0输出高电平时,因为LED两端都是3.3V的电压,不会形成电流,所以LED就是熄灭。

        这里的限流电阻一定要接,一方面它可以防止因为电流过大而烧毁,另一方面它也可以调整LED的亮度,如果觉得LED太亮,可以适当增大限流电阻的阻值,反之,则可以减小限流电阻的阻值。本课程使用面包板插接LED,为了简化电路,就省去了限流电阻,如果是自己设计电路,一定要加上限流电阻。

        下面图是高电平驱动的电路,LED负极接GND,正极通过一个限流电阻接到PA0上,这时就是高电平点亮,低电平熄灭了。

        如何选择上面两种驱动方式,得看IO口高低电平的驱动能力了,GPIO在推挽输出模式下,高低电平均有较强的驱动能力,两种驱动方式均可,但是单片机的电路中,一般倾向于第一种接法,因为很多单片机或者芯片,都是用了高电平弱驱动,低电平的强驱动的规则,这样可以一定程度上避免高低电平打架,所以如果高电平驱动能力弱的话,那就不能使用第二种连接方法了。

 2、蜂鸣器硬件电路

        这里使用了三极管开关的驱动方案,三极管开关是最简单的驱动电路,对于功率稍微大一点的,直接用IO口驱动会导致STM32负担过重,这时就可以用一个三极管驱动电路来完成驱动任务。

        上面图是PNP三极管的驱动电路,三极管的左边是基极,带箭头的是发射极,剩下的是集电极,给左边基极低电平,三极管就会导通,通过3.3V和GND就可以给蜂鸣器提供驱动电流了;基极给高电平,三极管截止,蜂鸣器就没有电流经过

        下面图是NPN三极管的驱动电路,左边是基极,带箭头的是发射极,剩下的是集电极,它的驱动逻辑和上面相反,基极给高电平才导通,低电平断开

        注意,PNP的三极管最好接在蜂鸣器上边,NPN的三级管最好接蜂鸣器下边,这是因为三极管的通断,是需要在发射极和基极之间会直接产生一定的开启电压的,如果把负载接在发射极这边,可能会导致三极管不能开启。


二、面包板

面包板正面


面包板反面

反面竖着一条条的就是面包板内部的金属爪,下图是金属爪的示意图。 

当我们把原件的引脚插到面包板的孔里后,它内部的金属爪就会抓住引脚。

        通过面包板背面可以发现,金属爪的排列规律是,中间的金属爪是竖着放的,上下四排是连在一起的四个整体的金属爪,对应这个面包板的孔的连接关系,竖着的5个孔内部都是连接在一起的,这样元件插在一竖排的不同孔位时,内部的金属爪就实现了线路的连接,而上下四排孔整体是连接在一起的,这四排是用于供电的,上面也有标记,第一排是+,第二排是-,第三排是+,第四排是-,如果我们需要供电,就从上下四排的孔位中,用跳线印出来即可。

举例说明:

        首先,把上面两排的供电引脚接上电源的正负极,然后用跳线将正极引下来到中间的孔位,在纵向下面的孔,横着插一个限流电阻到右边的孔位,接着在右边纵向上面的孔,横着插一个LED到右边的孔,最后再用跳线把右边孔位引到负极。


三、LED闪烁

1、硬件接线图

整个系统的供电是STLINK的3.3V接到最小系统,然后最小系统通过跳线接到上下四排的供电孔,这里使用的是低电平点亮的操作方式,为了方便,就没有接限流电阻。

LED长脚为正极,接到正极供电孔,断脚为负极,接到PA0端口上

2、常用函数

(1)RCC库函数常用函数

1.void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);

RCC AHB外设时钟控制,使能或者失能AHB外设时钟。

第一个参数就是选择哪个外设,STM32互联网型设备可以在下图列表选择:

其他设备在这个下图选择:

第二个参数就是ENABLE or DISABLE。

 2.void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

RCC APB2外设时钟控制,使能或者失能APB2外设时钟。

第一个参数选择外设,下图是可选择的外设。

第二个参数使能或使能。

在STM32中,所有的GPIO都是挂载在APB2外设总线上的,所以要给PA0端口低电平点亮LED,需要给RCC_APB2外设时钟使能,第一个参数就选择RCC_APB2Periph_GPIOA,第二个参数为ENABLE。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);		
//将APB2总线上挂着的外设GPIOA时钟打开

3.void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);

RCC APB1外设时钟控制,使能或者失能APB1外设时钟。

第一个参数选择外设,下图是可选择的外设。

第二个参数使能或使能。

(2)GPIO库函数常用函数

1.void GPIO_DeInit(GPIO_TypeDef* GPIOx);

参数可以写GPIOA、GPIOB等等,调用这个函数后,所指定的GPIO外设就会被复位

2.void GPIO_AFIODeInit(void);
可以复位AFIO外设。

3.void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

这个函数的作用是,用结构体的参数来初始化GPIO口

我们需要先定义一个结构体变量,然后再给结构体赋值,最后调用这个函数,这个函数内部就会自动读取结构体的值,然后自动把外设的各个参数配置好。

第一个参数是要初始化的GPIO口,第二个参数是一个结构体。

	GPIO_InitTypeDef GPIO_InitStructure;                //定义结构体变量
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //GPIO模式选择
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;           //GPIO引脚选择
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //GPIO传输速度选择
	GPIO_Init(GPIOA, &GPIO_InitStructure);              //调用Init函数

这里的结构体就是一个数据打包的过程,首先将参数写到结构体的三个变量里,然后统一打包,将结构体传递到初始化函数里,接着在初始化函数里面,再把这个结构体拆包出来,读取变量,这就是使用结构体的整个过程。

第一行中GPIO_InitTypeDef是结构体的类型,GPIO_InitStructure是结构体的名字,这里结构体实际上也是一种局部变量。

在第二行,复制结构体名字,然后用“.”把结构体的成员都引出来;

通过在GPIO_Mode右键跳转,可以看到参数说明,在参数GPIOMode_TypeDef选中,Ctrl+F搜索一下,就能看到GPIO的8种工作模式,这里我们选择GPIO_Mode_Out_PP推挽输出模式。

  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              //复用推挽

第三行引脚选择,通过在GPIO_Pin右键跳转,在选中GPIO_pins_define 参数处Ctrl+F搜索,就能找到引脚定义,这里我们用的是GPIOA外设的0号引脚,所以选择GPIO_Pin_0。

第四行同理,能找到引脚的输出速度定义,这里我们选则50MHz即可。

第5行就是调用GPIO_Init函数,然后第一个参数写GPIOA,然后GPIO初始化结构体的地址放到GPIO_Init的第二个参数,这样初始化就完成了,GPIO_Init函数执行完,这个GPIOA外设的0号引脚就自动被配置为推挽输出,50MHz的速度了。接下来就可以使用GPIO的这些输入输出函数了。

它内部的主要执行逻辑就是读取结构体的参数,执行一堆判断和运算,最后写入到GPIO配置寄存器。

在GPIO_InitStructure.GPIO_Pin引脚选择中,如果要时控制一个GPIO外设的多个引脚,可以在

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0  |  GPIO_Pin_1  |  GPIO_Pin_2  ...,让要控制的引脚都按位“或”,这样其他引脚也就都被选中了。

这是因为GPIO0的引脚0对应数据为0x0001,换成二进制为0000 0000 0000 0001;
GPIO1的引脚0对应数据为0x0002,换成二进制为0000 0000 0000 0010;
GPIO2的引脚0对应数据为0x0004,换成二进制为0000 0000 0000 0100;
GPIO3的引脚0对应数据为0x0008,换成二进制为0000 0000 0000 1000;

等等以此类推,每个端口都对应一个位,将它们按位“或”了以后,就变成了0000 0000 0000 1111,这样就相当于同时选中了3个端口,这就是按位或的操作逻辑。

当然也可以直接用GPIO_Pin_ALL,它对应数据就是0xFFFF,也就是所有位都为1,这样就相当于选中了所有的引脚。

这里除了GPIO_Pin可以用按位或的操作方式外,

RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
时钟控制(红色字体部分)的这一项,也是可以用按位或的操作方式来选择多个外设的。

GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
GPIO_ReSetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
函数红色字体部分都可以用按位或选择多个引脚。

4.void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);

这个函数可以把结构体变量赋一个默认值。

以下这四个函数是GPIO的写入函数


5.void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

这个函数可以把指定的端口设置为高电平。

第一个参数是GPIOx,第二个参数是GPIO_Pin。

GPIO_SetBits(GPIOA, GPIO_Pin_0);						
//将PA0口设置为高电平

6.void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

这个函数可以把指定的端口设置为低电平。

第一个参数是GPIOx,第二个参数是GPIO_Pin。

GPIO_ResetBits(GPIOA, GPIO_Pin_0);			
//将PA0口设置为低电平

7.void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

前两个参数都是指定端口,第三个参数是BitVal,根据第三个参数的值来设置指定端口。

第三个参数:

Bit_RESET:清除端口值,也就是置低电平;

Bit_SET:设置端口值,也就是置高电平。

GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);		
//给GPIOA中的0号引脚写入低电平(点亮LED)

8.void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

第一个参数是GPIOx,第二个参数是PortVal,这个函数可以同时对16个端口进行写入操作,它可以直接写到GPIO的ODR寄存器里。

GPIO_Write(GPIOA, ~0x0001);
//对应二进制0000 0000 0000 0001
//这16个二进制分别对应PA0口导PA15总共16个端口
//最低位对应PA0,然后往上依次是PA1、PA2,一直到PA15
//因为是低电平点亮,所以前面加一个按位取反符号~
//这样就是第一个LED点亮,其他都熄灭。

9.void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

这个函数是用来锁定GPIO配置的,调用这个函数,参数指定某个引脚,那这个引脚的配置就会被锁定,防止意外更改。

3、keilkill工具

将固件库/程序源码中的keilkill.bat文件复制到工程文件中,这个工具是一个批处理文件,它可以把工程编译产生的中间文件都删除,因为工程编译产生的文件比较大,如下图,左边是处理前,右边是处理后。

 4、增加延时函数

在工程文件夹中,添加System文件夹,然后在Keil软件中和头文件中,都添加这个文件,再将程序源码中的延时函数,复制到这个文件中,这个文件就可以专门用来存放库函数以外的函数。

然后在Keil中添加这个函数的.c和.h文件,并在程序开始出声明Delay函数。

5、程序

主函数

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

int main(void)													//int型返回值,void参数的函数
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);		//使能时钟
	GPIO_InitTypeDef GPIO_InitStructure;                		//定义结构体变量
																//GPIO_InitTypeDef结构体类型,
																//GPIO_InitStructure名字
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   			//GPIO模式选择
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;           		//GPIO引脚选择
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   		//GPIO传输速度选择
	GPIO_Init(GPIOA, &GPIO_InitStructure);              		//调用Init函数
	
	while(1)
	{
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);				//给GPIOA中的0号引脚写入低电平(点亮LED)
		Delay_ms(100);
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);				//给GPIOA中的0号引脚写入高电平(熄灭LED)
		Delay_ms(100);
		
//		GPIO_SetBits(GPIOA, GPIO_Pin_0);						//将PA0口设置为高电平
//		Delay_ms(100);
//		GPIO_ResetBits(GPIOA, GPIO_Pin_0);						//将PA0口设置为低电平
//		Delay_ms(100);
	}
}

6、实物展示

LED闪烁


 四、LED流水灯

1、硬件接线图

2、程序

主函数

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

int main(void)													//int型返回值,void参数的函数
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);		//使能时钟
	GPIO_InitTypeDef GPIO_InitStructure;                		//定义结构体变量
																//GPIO_InitTypeDef结构体类型,
																//GPIO_InitStructure名字
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   			//GPIO模式选择
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;           		//GPIO引脚选择全部16个引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   		//GPIO传输速度选择
	GPIO_Init(GPIOA, &GPIO_InitStructure);              		//调用Init函数
	
	while(1)
	{
		GPIO_Write(GPIOA, ~0x0001);								//0000 0000 0000 0001
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0002);								//0000 0000 0000 0010
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0004);								//0000 0000 0000 0100
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0008);								//0000 0000 0000 1000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0010);								//0000 0000 0001 0000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0020);								//0000 0000 0010 0000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0040);								//0000 0000 0100 0000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0080);								//0000 0000 1000 0000
		Delay_ms(100);

	}
}

3、实物展示

LED流水灯


 五、蜂鸣器

1、硬件接线图

2、程序

主函数

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

int main(void)													//int型返回值,void参数的函数
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);		//使能时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;                		//定义结构体变量
																//GPIO_InitTypeDef结构体类型,
																//GPIO_InitStructure名字
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   			//GPIO模式选择
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;           		//GPIO引脚选择
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   		//GPIO传输速度选择
	GPIO_Init(GPIOB, &GPIO_InitStructure);              		//调用Init函数
	
	while(1)
	{
		GPIO_ResetBits(GPIOB, GPIO_Pin_12);						//将PB12设置低电平
		Delay_ms(100);
		GPIO_SetBits(GPIOB, GPIO_Pin_12);
		Delay_ms(100);
		GPIO_ResetBits(GPIOB, GPIO_Pin_12);
		Delay_ms(100);
		GPIO_SetBits(GPIOB, GPIO_Pin_12);
		Delay_ms(700);
	}
}

3、实物展示

蜂鸣器


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐