Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译

Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译

  • 1.有源蜂鸣器简介
  • 2. 硬件原理分析
  • 3.编译下载验证
    • 3.1在写驱动之前要找到对应的寄存器设置好属性
      • 3.1.1初始化SNVS_TAMPER1这个IO复用为GPIO5_IO01
      • 3.1.2设置SNVS_TAMPER1这个IO的电气属性。
      • 3.1.3修改.vscode文件把beep文件夹路径加入到.vscode
    • 3.2 修改main.c文件
  • 4 编写和验证
    • 4.1编写Makefile
    • 4.2编写脚本链接
    • 4.3编译下载

Linux之ARM(MX6U)裸机之c语言蜂鸣器实验–驱动编写、编译

在 I.MX6U-ALPHA 开发板上有一个有源蜂鸣器,通过 IO 输出高低电平即可控制蜂 鸣器的开关,本质上也属于 GPIO 的输出控制。

1.有源蜂鸣器简介

蜂鸣器常用于计算机、打印机、报警器、电子玩具等电子产品中,常用的蜂鸣器有两种: 有源蜂鸣器和无源蜂鸣器,这里的有“源”不是电源,而是震荡源,有源蜂鸣器内部带有震荡 源,所以有源蜂鸣器只要通电就会叫。无源蜂鸣器内部不带震荡源,直接用直流电是驱动不起 来的,需要 2K-5K 的方波去驱动。I.MX6U-ALPHA 开发板使用的是有源蜂鸣器,因此只要给其 供电就会工作,I.MX6U-ALPHA 开发板所使用的有源蜂鸣器如图 :
Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译_第1张图片
有源蜂鸣器只要通电就会叫,所以我们可以做一个供电电路, 这个供电电路可以由一个 IO来控制其通断,一般使用三极管来搭建这个电路。为什么我们不能像控制 LED 灯一样,直接将GPIO 接到蜂鸣器的负极,通过 IO 输出高低来控制蜂鸣器的通断。因为蜂鸣器工作的电流比LED 灯要大,直接将蜂鸣器接到 I.MX6U 的 GPIO 上有可能会烧毁 IO,所以我们需要通过一个三极管来间接的控制蜂鸣器的通断,相当于加了一层隔离。本章我们就驱动 I.MX6U-ALPHA 开发板上的有源蜂鸣器,使其周期性的“滴、滴、滴……”鸣叫

2. 硬件原理分析

Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译_第2张图片
Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译_第3张图片
图中通过一个 PNP 型的三极管 8550 来驱动蜂鸣器,通过 SNVS_TAMPER1 这个 IO 来控制三极管 Q1 的导通,当 SNVS_TAMPER1 输出低电平的时候 Q1 导通,相当于蜂鸣器的正 极连接到 DCDC_3V3,蜂鸣器形成一个通路,因此蜂鸣器会鸣叫。同理,当 SNVS_TAMPER1 输出高电平的时候 Q2 不导通,那么蜂鸣器就没有形成一个通路,因此蜂鸣器也就不会鸣叫。

3.编译下载验证

本实验在上一次(BSP实验)实验的基础上再做修改,把BSP实验的工程文件复制一份,
在这里插入图片描述

3.1在写驱动之前要找到对应的寄存器设置好属性

3.1.1初始化SNVS_TAMPER1这个IO复用为GPIO5_IO01

Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译_第4张图片
找到这个NVS_TAMPER1的宏定义
Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译_第5张图片

3.1.2设置SNVS_TAMPER1这个IO的电气属性。

Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译_第6张图片
Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译_第7张图片
*bit 16:0 HYS 关闭
*bit [15:14]: 00 默认下拉
*bit [13]: 0 kepper 功能
*bit [12]: 1 pull/keeper 使能
*bit [11]: 0 关闭开路输出
*bit [7:6]: 10 速度 100Mhz
*bit [5:3]: 110 R0/6 驱动能力
*bit [0]: 0 低转换率

新建 beep.h 文件,保存到 bsp/beep 文件夹里面,在 beep.h 里面输入如下内容:

#ifndef BSP_BEEP_H
#define BSP_BEEP_H
#include "imx6ul.h"

void beep_init(void);
void bepp_switch(int status);


#endif //  BSP_BEEP_H

beep_c文件

#include "bsp_beep.h"


/* BEEP初始化*/
void beep_init(void)
{
   IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01, 0);
   IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01,0x10b0);

/*GPIO初始化*/
GPIO5->GDIR |= (1 << 1); /*设置为输出*/
GPIO5->DR   |= (1 << 1); /*默认关闭*/

}
/*蜂鸣器控制函数*/
void bepp_switch(int status)
{
  if(status==ON)
      GPIO5->DR &=~(1 << 1);  /*低电平响*/
  else if(status==OFF)
      GPIO5->DR |= (1 << 1);   /*高电平不响*/
  
    

}

beep.c 文件一共有两个函数: beep_init 和 beep_switch,其中 beep_init 用来初始化 BEEP 所使用的 GPIO,也就是 SNVS_TAMPER1,将其复用为 GPIO5_IO01,和上一章的 LED 灯初始化函数一样。 beep_switch 函数用来控制 BEEP 的开关,也就是设置 GPIO5_IO01 的高低电平,很简单。

把头文件包含进main.h中

3.1.3修改.vscode文件把beep文件夹路径加入到.vscode

Linux之ARM(MX6U)裸机之c语言蜂鸣器实验--驱动编写、编译_第8张图片

3.2 修改main.c文件

#include "mian.h"
#include "bsp_clk.h"
#include "bsp_led.h"
#include "bsp_delay.h"
#include "bsp_beep.h"








int main(void)
{
    clk_enable();     /* 使能所有的时钟     */ 
    led_init();        /* 初始化 led          */ 
    beep_init();      /* BEEP初始化*/

    while (1)
    {
        led_off();    /* 关闭 LED            */ 
        bepp_switch(OFF);
       
        delay(1000);
 
        led_on();     /* 打开 LED            */ 
         bepp_switch(ON);
        delay(1000);
    }
    
    return 0;
}

4 编写和验证

4.1编写Makefile

主要修改目标文件和头文件路径和源码路径

CROSS_COMPILE 	?= arm-linux-gnueabihf-
TARGET		  	?= beep

CC 				:= $(CROSS_COMPILE)gcc
LD				:= $(CROSS_COMPILE)ld
OBJCOPY 		:= $(CROSS_COMPILE)objcopy
OBJDUMP 		:= $(CROSS_COMPILE)objdump

INCDIRS 		:= imx6ul \
				   bsp/clk \
				   bsp/led \
				   bsp/delay \
				   bsp/beep
				   			   
SRCDIRS			:= project \
				   bsp/clk \
				   bsp/led \
				   bsp/delay \
				   bsp/beep
				   
				   
INCLUDE			:= $(patsubst %, -I %, $(INCDIRS))

SFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

SFILENDIR		:= $(notdir  $(SFILES))
CFILENDIR		:= $(notdir  $(CFILES))

SOBJS			:= $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS			:= $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS			:= $(SOBJS) $(COBJS)

VPATH			:= $(SRCDIRS)

.PHONY: clean
	
$(TARGET).bin : $(OBJS)
	$(LD) -Timx6ul.lds -o $(TARGET).elf $^
	$(OBJCOPY) -O binary -S $(TARGET).elf $@
	$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis

$(SOBJS) : obj/%.o : %.S
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<

$(COBJS) : obj/%.o : %.c
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<
	
clean:
	rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)

4.2编写脚本链接

这个脚本链接和上一篇文章用的一样

SECTIONS{
    . = 0x87800000;
    .text :
    {
        obj/start.o
        *(.text)

    }
    .rodata ALIGN(4) : {*(.rodata*)}
    .data ALIGN(4)  : {*(.data)}
    __bss_start = .;
    .bss ALIGN(4) : {*(.bss) *(COMMON)}
    __bss_end = .;
    

}

4.3编译下载

使用 Make 命令编译代码,编译成功以后使用软件 imxdownload 将编译完成的 beep.bin 文 件下载到 SD 卡中,命令如下:

  chmod 777 imxdownload   //给予 imxdownload 可执行权限,一次即可 
  ./imxdownload beep.bin /dev/sdd  //烧写到 SD 卡中  

烧写成功以后将 SD 卡插到开发板的 SD 卡槽中,然后复位开发板。如果代码运行正常的 话 LED 灯亮的时候蜂鸣器鸣叫,当 LED 灯灭的时候蜂鸣器不鸣叫,周期大概为 1000ms 。

你可能感兴趣的:(IMX6ULL)