上接前面关于BSP的博文,在那篇博文里我们搭建起了一个‘麻雀虽小,五脏俱全’的工程框架,现在框架已经搭起来了,这样当你想添加新功能时,方便的一批。闲话少说,直接搞起来!
肯定还是先看电路图,找到你要调用的IO口。(这里就不配图了,makedown编辑器搞起图片来太麻烦。)
在bsp文件夹下直接新建一个beep的文件夹,蜂鸣器驱动文件我们都是要放到里面的。
在上一步建好的beep文件夹中,新建bsp_beep.h、bsp_beep.c。
一定要记好了,.c和.h就是一堆CP,两个都是成对出现的,.c里面构造相关函数,.h文件来提供接口API,以供主函数调用。
bsp_beep.h代码如下:
1 #ifndef __BSP_BEEP_H 2 #define __BSP_BEEP_H 3 4 #include "imx6ul.h" 5 6 /* 函数声明 */ 7 void beep_init(void); 8 void beep_switch(int status); 9 #endif
比较简单,没什么可说的。
bsp_beep.c代码如下:
#include "bsp_beep.h" /*初始化蜂鸣器IO*/ void beep_init(void) { /*IO复用,复用为GPIO5_IO01*/ IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01,0); /*配置IO属性*/ IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01,0x10B0); /*初始化设置为输出*/ GPIO5->GDIR |= (1 << 1); /*输出高带你平,关闭蜂鸣器*/ GPIO5->DR |= (1 << 1); } /*蜂鸣器控制函数*/ void beep_switch(int status) { if(status == ON) GPIO5->DR &= ~(1 << 1);//打开 else if (status == OFF) GPIO5->DR |= (1 << 1);//关闭 }
要说难点的或者不好理解的地方还是这里:
如果猛的一下你看不懂这是啥意思的话,不要着急,要一步一步来,回想一下你学过的结构体,运算符方面的知识,都是不难的。
main.c文件只需要稍微做些更改就好:
#include "bsp_clk.h" #include "bsp_delay.h" #include "bsp_led.h" #include "bsp_beep.h" int main(void) { clk_enable(); /* 使能所有的时钟 */ led_init(); /* 初始化led */ beep_init();//初始化beep while(1) /* 死循环 */ { led_switch(LED0,'ON'); /* 打开LED */ beep_switch(ON); delay(500); /* 延时500ms */ led_switch(LED0,'OFF'); /* 关闭LED */ beep_switch(OFF); delay(500); /* 延时500ms */ } return 0; }
加上头文件bsp_beep.h,还有beep的初始化函数beep_init(),还有直接调用控制beep的函数beep_switch()。
也是简单的修改一下就行了:
CROSS_COMPILE ?= arm-linux-gnueabihf-#这一行针对不同的编译器是可以进行更改的 TARGET ?= beep#这个目标名字也是,针对不同到历程也是要改的 CC := $(CROSS_COMPILE)gcc LD := $(CROSS_COMPILE)ld OBJCOPY := $(CROSS_COMPILE)objcopy OBJDUMP := $(CROSS_COMPILE)objdump #变量 INCDIRS 包含整个工程的.h 头文件目录,文件中的所有头文件目录都要添加到变量INCDIRS中 INCDIRS := imx6ul \ bsp/clk \ bsp/led \ bsp/delay\ bsp/beep #SRCDIRS 包含的是整个工程的所有.c 和.S 文件目录 SRCDIRS := project \ bsp/clk \ bsp/led \ bsp/delay\ bsp/beep #变量 INCLUDE 使用到了函数 patsubst,通过函数 patsubst 给变量 INCDIRS 添加一个“-I”,因为 Makefile 语法要求指明头文件目录的时候需要加上“-I” INCLUDE := $(patsubst %, -I %, $(INCDIRS)) #变量 SFILES 保存工程中所有的.s 汇编文件(包含绝对路径),变量 SRCDIRS 已经存放了工程中所有的.c 和.S 文件,所以我们只需要从里面挑出所有的.S 汇编文件即可 SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S)) #变量 CFILES 和变量 SFILES 一样,只是 CFILES 保存工程中所有的.c 文件(包含绝对路径) CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c)) #使用函数 notdir 将 SFILES 和 CFILES 中的路径去掉 SFILENDIR := $(notdir $(SFILES)) CFILENDIR := $(notdir $(CFILES)) #默认所有的文件编译出来的.o 文件和源文件在同一个目录中 SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o)) COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o)) #变量 OBJS 是变量 SOBJS 和 COBJS 的集合 OBJS := $(SOBJS) $(COBJS) #VPATH 是指定搜索目录的,这里指定的搜素目录就是变量 SRCDIRS 所保存的目录,这样当编译的时候所需的.S 和.c 文件就会在 SRCDIRS 中指定的目录中查找 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)
完整的工程文件,可以去我的码云仓库下载:
https://gitee.com/iron2222/linux-driver-development/tree/master/6_beep
谢谢大家的支持!
祝大家早安,午安,晚安!