【STM32F103ZET6开发板】第2-3讲:GPIO输出驱动蜂鸣器 GPIO输出驱动蜂鸣器 实验目的 掌握STM32 GPIO输出驱动原理。掌握三极管开关电路的设计:NPN型三极管开关电路和PNP型三极管开关电路。掌握对有源蜂鸣器的驱动设计及程序控制。实验内容编写程序驱动蜂鸣器间隔鸣响。 硬件电路设计 开发板蜂鸣器硬件电路 蜂鸣器是一种把警示电信号转换成人耳能够感知的电声转换装置,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。 根据蜂鸣器自身有没有震荡源可将蜂鸣器分为有源蜂鸣器和无源蜂鸣器。使用有源蜂鸣器,无需外部提供震荡源,只需供电给蜂鸣器,蜂鸣器便可工作。而使用无源蜂鸣器,则需要提供振荡源给蜂鸣器才能保证蜂鸣器正常工作。 艾克姆科技IK-ZET6开发板板载的蜂鸣器是3.3V有源蜂鸣器,通过NPN三极管9013驱动,驱动电路如下图所示。
图1:蜂鸣器驱动电路蜂鸣器电路占用的单片机的引脚如下表:表1:蜂鸣器引脚分配标号名称引脚说明H1有源蜂鸣器PG7独立GPIO注:独立GPIO表示开发板没有其他的电路使用这个GPIO。三极管开关电路三极管,全称为半导体三极管,也称双极型晶体管、晶体三极管,其有3种工作状态,分别是截止状态、放大状态和饱和导通状态。(每种状态的工作条件在此不做介绍)利用三极管可工作于截止状态和饱和导通状态的电气特性,可通过控制三极管的基极电压来控制三极管是导通还是断开,以此便可将三极管作为开关使用,形成三极管开关电路。三极管开关电路的一大优势是可实现小电流控制大电流工作,具体而言是基极电流可以很小(几毫安)便可控制甚至几安培工作电流的负载工作。正是这样的优势,使得驱动能力有限的单片机IO口可以通过三极管开关电路高效控制较大功率的负载,比如蜂鸣器、继电器、液晶屏背光等。三极管是在一块半导体基片上制作两个相距很近的PN结,两个PN结把整块半导体分成三部分,中间部分是基区,两侧部分是发射区和集电区,按两侧部分的发射区和集电区排列方式的不同可以将管分成了PNP型三极管和NPN型三极管。常见NPN型三极管有S9013、S8050等,常见PNP型三极管有S9012、S8550等。无论是NPN型三极管还是PNP型三极管,都有基极、集电极和发射极。基极、集电极和发射极对应着三极管实物的3个引脚。下图分NPN型和PNP型介绍三极管典型开关电路。
图2:三极管典型开关电路从上图可知,NPN型三极管典型开关电路和PNP型三极管典型开关电路都用到了两个电阻,两个电阻的作用如下所述。1、三极管典型开关电路中R1的作用是保护单片机GPIO口和三极管基极。针对NPN型三极管S9013举例,如果没有电阻R1,当单片机GPIO口输出高电平时,三极管基极和发射极之间有有效的压差使三极管处于导通状态,一旦三极管饱和导通,基极和发射极间的电压差是0.7V,发射极接地,那基极电压应是0.7V左右,而单片机GPIO口又输出的是高电平3.3V,那么对无论单片机GPIO口还是三极管基极都会造成不可预知的损坏,故选择在单片机GPIO口和三极管基极之间加一个限流电阻R1,至于R1的阻值如何选择将在接下来的对三极管开关电路的分析中讲解。2、三极管典型开关电路中R2的作用是在单片机GPIO口呈高阻态时使晶体管可靠截止,避免出现误动作。如果没有R2电阻,则单片机GPIO呈高组态时输出的电平是不确定的,那可能会让三极管导通或者截止,三极管截止的话,负载不工作不会有什么后果。而如果三极管导通,控制了负载工作,则会造成不可预知的后果。故加上R2电阻使得三极管基极和发射极电压一致,三极管会在单片机GPIO口呈高阻态时始终处于截止状态。电阻R2还有一个作用是用于泄漏电流,即使三极管处于截止状态,也不能保证三极管基极就没有电压(尤其集成芯片上断电时),而有了R2电阻可以将漏电流通过R2流入到地,保护了三极管和整个电路。分析NPN型三极管典型开关电路如下图所示,以硅半导体NPN型三极管为例介绍单片机GPIO口输出高电平和低电平时如何控制三极管饱和导通和截止,并分析三极管典型开关电路中电阻值的选择。(假设单片机是3.3V的单片机,VCC供电也是3.3V)
图3:三极管典型开关电路1、当单片机GPIO口由软件控制输出逻辑“1”,针对硬件电路GPIO口输出的就是高电平3.3V。这个高电平会使三极管基极电压远大于三极管发射极电压0V(对R2取值有要求),从而使三极管工作在饱和导通状态,而一旦三极管进入饱和导通状态,由三极管工作原理及选择的是硅半导体三极管可知三极管基极和发射极电压差Ube≈0.7V,三极管发射极接地故可知三极管基极电压约0.7V,如上图3标注。R1取值会是一个范围,三极管有个重要的参数是电流放大系数β,β除了和所选择的三极管型号有关,还受温度等影响。在此取值R1为1K,那么可计算出流过R1的电流约是2.6mA,这个驱动电流是单片机GPIO引脚可以提供的。如果单片机是5V供电的,R1是否选择1K,用户可综合考虑计算取值。之前有说过R2的作用,但没有说明R2的阻值是如何取的。R2的取值至少要满足其与基极限流电阻R1分压后能够满足三极管的临界饱和,实际选择时会大大高于这个最小值,通常外接干扰越小、负载越重允许R2的取值就越大,通常采用10K量级的电阻。在此仅分析下R2取值过小为什么不行,假设R2取值100Ω(R1取值按照上面的1K取值),三极管刚开始是截止的,电流全部从R2流到地,那么易算出R2与R1分压后基极端的电压是0.3V,这个电压不能够使三极管进入饱和导通状态。另一个因素,即使三极管处于截止状态,R2阻值过小都会导致可能产生的漏电流过大,所以综合考虑取值R2为10K,当然这个值不是唯一的。2、当单片机GPIO口由软件控制输出逻辑“0”,针对硬件电路GPIO口输出的就是低电平0V。这个低电平毫无疑问不会使三极管基极有超过0.7V的电压,那么三极管会处于截止状态。三极管集电极和发射极之间不会有电流流过,负载端无法形成回路,负载不会工作。上图3中有直观分析NPN型三极管截止时的工作情况。分析PNP型三极管典型开关电路如下图所示,以硅半导体PNP型三极管为例介绍单片机GPIO口输出高电平和低电平时如何控制三极管饱和导通和截止,并分析三极管典型开关电路中电阻值的选择。(假设单片机是3.3V的单片机,VCC供电也是3.3V)
图4:三极管典型开关电路1、当单片机GPIO口由软件控制输出逻辑“0”,针对硬件电路GPIO口输出的就是低电平0V。这个低电平会使三极管基极电压远低于三极管发射极电压3.3V(对R2取值有要求),从而使三极管工作在饱和导通状态,而一旦三极管进入饱和导通状态,由三极管工作原理及选择的是硅半导体三极管可知三极管基极和发射极电压差Ube≈0.7V,三极管发射极接3.3V故可知三极管基极电压约2.6V,如上图4标注。此时负载端形成回路,负载工作。关于R1和R2阻值的取值与NPN型三极管典型开关电路中已有介绍,在此不再赘述。2、当单片机GPIO口由软件控制输出逻辑“1”,针对硬件电路GPIO口输出的就是高电平3.3V。这个高电平不会使得三极管基极和发射极之间有超过0.7V的电压差,那么三极管会处于截止状态。三极管发射极和集电极之间不会有电流流过,负载端无法形成回路,负载不会工作。上图4中有直观分析PNP型三极管截止时的工作情况。对比NPN型典型开关电路和PNP型典型开关电路无论NPN型典型开关电路还是PNP型典型开关电路本质上是一样的,只是选择的三极管型号及单片机GPIO口输出高低信号不同而已。大多数情况下都是可以相互替换的,但这是建立于单片机GPIO口输出的高电平值与负载供电的电平值是一样的。如果负载的供电是5V,而单片机供电是3.3V,那么情况会有所不同。下面将分析NPN型典型开关电路和PNP型典型开关电路在负载是5V供电单片机是3.3V供电下,单片机GPIO能否控制三极管有效进入截止状态和饱和导通状态。1、NPN型三极管开关电路在单片机GPIO输出高低电平时:
图5:三极管典型开关电路由上图分析可知,虽然负载的供电是5V,但单片机GPIO口输出高电平3.3V可以使NPN三极管导通,单片机GPIO口输出低电平0V可以使NPN三极管截止。因为NPN三极管发射极连接的是GND,NPN三极管能否工作取决于三极管基极和发射极的电压差,这样单片机GPIO口输出高低电平均可有效控制NPN三极管导通或截止。2、PNP型三极管开关电路在单片机GPIO输出高低电平时:
图6:三极管典型开关电路由上图分析可知,由于负载的供电是5V,而PNP三极管发射极连接的是5V,这样单片机GPIO口输出高电平3.3V或者低电平0V均可使PNP三极管导通,此种情况,3.3V供电的单片机GPIO口不能控制PNP三极管截止。蜂鸣器硬件电路设计通过对NPN型三极管典型硬件电路和PNP型三极管典型硬件电路的分析,以及单片机供电和负载供电不同时的电路工作原理分析,艾克姆科技使用NPN型三极管典型硬件电路,这样即便选择5V供电的蜂鸣器,则除了对蜂鸣器供电修改成5V供电外,其他硬件电路基本不需改动。NPN三极管的选择,常见NPN三极管有很多种类型,S9013是极为常用的一款三极管。查阅S9013的数据手册,可查找到几个重要参数:VCBO=40V,VCEO=20V,VEBO=5V, ICM=500mA,PCM=625mW。此参数可以满足蜂鸣器驱动电路的设计要求。软件设计GPIO寄存器STM32F103提供了10个用于操作GPIO的寄存器,如下表所示:表2:GPIO相关寄存器序号寄存器名读/写功能描述1GPIOx_CRL读/写端口配置低寄存器。2GPIOx_CRH读/写端口配置高寄存器。3GPIOx_IDR只读端口输入数据寄存器。4GPIOx_ODR读/写端口输出数据寄存器。5GPIOx_BSRR只写端口位设置/清除寄存器。6GPIOx_BRR只写端口位清除寄存器。7GPIOx_LCKR读/写端口配置锁定寄存器。8AFIO_EVCR读/写事件控制寄存器。9AFIO _MAPR读/写复用重映射和调试 I/O 配置寄存器。10AFIO _EXTICRy读/写外部中断线路 0-15 配置寄存器。注:x取值:A、B、C、D、E、F、G , y取值:1、2、3、4。每一种寄存器详细的描述在这里不做具体的介绍,大家可以参考目录:“第1部分:开发板硬件资料”—>“2 – 芯片资料”中“STM32英文参考手册_V15”或“STM32中文参考手册_V10”对应的GPIO章节的寄存器部分认真研读。GPIO库函数官方提供的最终库函数版本是V3.5版本,该版本库函数提供了17个与GPIO操作有关的库函数,如下表所示:表3:GPIO相关库函数汇集序号函数名功能描述1GPIO_DeInit将外设 GPIOx 寄存器重设为缺省值。2GPIO_AFIODeInit将复用功能(重映射事件控制和 EXTI设置)重设为缺省值。3GPIO_Init将GPIO_InitStruct中指定参数初始化外设 GPIOx 寄存器。4GPIO_StructInit把GPIO_InitStruct中的每一个参数按缺省值填入。5GPIO_ReadInputDataBit读取指定端口管脚的输入。6GPIO_ReadInputData读取指定的 GPIO 端口输入。7GPIO_ReadOutputDataBit读取指定端口管脚的输出。8GPIO_ReadOutputData读取指定的 GPIO 端口输出。9GPIO_SetBits设置指定的数据端口位。10GPIO_ResetBits清除指定的数据端口位。11GPIO_WriteBit设置或者清除指定的数据端口位。12GPIO_Write向指定 GPIO 数据端口写入数据。13GPIO_PinLockConfig锁定 GPIO 管脚设置寄存器。14GPIO_EventOutputConfig选择 GPIO 管脚用作事件输出。15GPIO_EventOutputCmd使能或者失能事件输出。16GPIO_PinRemapConfig改变指定管脚的映射。17GPIO_EXTILineConfig选择 GPIO 管脚用作外部中断线路。注:x取值:A、B、C、D、E、F、G 。 每一种寄存器详细的描述在这里不做具体的介绍,大家可以参考目录:“第1部分:开发板硬件资料”—>“2 – 芯片资料”中“STM32固件库使用手册的中文翻译版”对应的GPIO章节的库函数部分认真研读。 蜂鸣器驱动 注:本节对应的实验源码是:“实验3:蜂鸣器驱动”。 工程需要用到的库文件 在使用库函数建“实验3:蜂鸣器驱动”工程时,需要用到的c文件如下表所示。 表4:实验需要用到的C文件序号文件名后缀功能描述1stm32f10x_rcc.c复位与时钟控制器。2stm32f10x_gpio.c通用输入输出。注:所建工程必须添加上面c文件。可按下图所示在新建工程时添加需要的c文件。
图7:在新建工程中添加所需库函数c文件表5:实验需要用到的头文件序号文件名后缀功能描述1stm32f10x_rcc.h复位与时钟控制器。2stm32f10x_gpio.h通用输入输出。注:所建工程必须添加上面h文件所在的目录:..\..\ Lib\ F10x_FWLIB\ inc。 在使用该实验工程时,需要用到的头文件如表5所示。需要在MDK中魔术棒,打开工程配置窗口,按照下图所示添加头文件包含路径。
图8:如何添加头文件包含路径 编写代码 首先完成对控制蜂鸣器电路的PG7引脚的初始化配置,并控制PG7引脚初始电平是低电平,以保证起始时蜂鸣器驱动电路三极管不导通,即蜂鸣器不鸣响。 代码清单:初始化控制蜂鸣器的GPIO引脚PG7,并设置PG7初始状态为低电平/* * 描 述 : 初始化单片机控制蜂鸣器的引脚PG7,并将蜂鸣器的初始状态设置为不鸣响 * 参 数 : 无 * 返回值 : 无 / void beep_init(void) { //定义IO初始化配置结构体 GPIO_InitTypeDef GPIO_InitStructure; //打开PG端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE); //配置的IO是PG7 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //配置为通用推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //IO口速度为50MHz GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //调用库函数GPIO_Init()配置IO GPIO_Init(GPIOG, &GPIO_InitStructure); //设置蜂鸣器的初始状态设置为不鸣响 GPIO_ResetBits(GPIOG,GPIO_Pin_7); } 然后,在主函数中加入用于控制蜂鸣器的GPIO口的初始化操作,之后循环执行:控制蜂鸣器鸣响,延时200ms,再停止蜂鸣器鸣响,再延时200ms的过程,这样可听到蜂鸣器间隔鸣响的现象。 代码清单:主函数int main(void) { //初始化用于控制蜂鸣器的引脚PG7 beep_init(); //主循环 while(1) { //调用库函数GPIO_ResetBits()控制蜂鸣器的引脚PG7输出高电平,即使蜂鸣器鸣响 GPIO_SetBits(GPIOG,GPIO_Pin_7); //软件延时200ms sw_delay_ms(200); //调用库函数GPIO_SetBits()控制蜂鸣器的引脚PG7输出低电平,即不使蜂鸣器鸣响 GPIO_ResetBits(GPIOG,GPIO_Pin_7); //软件延时200ms sw_delay_ms(200); } } 实验步骤 解压“…\第3部分:标准库教程和实验源码\ 1 – 基础实验程序\”目录下的压缩文件“实验3:蜂鸣器驱动”,将解压后得到的文件夹拷贝到合适的目录,如“D\STM32F103ZET6”。启动MDK5.23。在MDK5中执行“Project→Open Project”打开“…\ BEEP\project”目录下的工程“BEEP.uvproj”。编译按钮编译工程。注意查看编译输出栏,观察编译的结果,如果有错误,修改程序,直到编译成功为止。编译后生成的HEX文件“BEEP.hex”位于工程目录下的“Objects”文件夹中。按钮下载程序 。如果需要对程序进行仿真,Debug按钮,即可将程序下载到STM32F103ZET6中进行仿真。程序运行后,可听到蜂鸣器间隔鸣响。
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/49381.html