05_I.MX6ULL工程管理与蜂鸣器实验
目录
BSP工程管理
有源蜂鸣器简介
硬件原理分析
实验源码
bsp源码
main.c汇编文件源码
链接文件源码
Makefile源码
BSP工程管理
在实际工作中将所有源码放到工程的根目录下,如果工程文件比较少的话这样做无可厚非,但是如果工程源文件达到几十、甚至数百个的时候,这样一股脑全部放到根目录下就会使工程显得混乱不堪。所以我们必须对工程文件做管理,将不同功能的源码文件放到不同的目录中。另外我们也需要将源码文件中,所有完成同一个功能的代码提取出来放到一个单独的文件中,也就是对程序分功能管理。
第一步:先建立一个项目文件夹
第二步建立相应存放代码的文件夹
01_imx6ul是一些关于芯片的源码
02_bsp是用来专门存放启动的文件夹
03_obj是用来存放编译时候的一些文件
04_project是存放main.c和汇编文件
Imx6ul.lds是链接脚本
Imxdownload是一个烧录sd卡的脚本
load.imx是烧录脚本生成的,里面内容就是头部加bin文件,最终烧到sd卡里的就是这个文件
Makedfile 自动编译脚本
第三步在02_bsp文件夹下创建各个外设的文件夹实现了模块化管理
有源蜂鸣器简介
蜂鸣器常用于计算机、打印机、报警器、电子玩具等电子产品中,常用的蜂鸣器有两种:有源蜂鸣器和无源蜂鸣器,这里的有“源”不是电源,而是震荡源,有源蜂鸣器内部带有震荡源,所以有源蜂鸣器只要通电就会叫。无源蜂鸣器内部不带震荡源,直接用直流电是驱动不起来的,需要 2K-5K 的方波去驱动。这里使用的是有源蜂鸣器,因此只要给其供电就会工作。
有源蜂鸣器只要通电就会叫,可以由一个IO来控制其通断,一般使用三极管来搭建这个电路。
硬件原理分析
通过一个PNP型的三极管8550来驱动蜂鸣器,通过SNVS_TAMPER1这个IO来控制三极管 Q1的导通,当SNVS_TAMPER1输出低电平的时候Q1导通,相当于蜂鸣器的正极连接到DCDC_3V3,蜂鸣器形成一个通路,因此蜂鸣器会鸣叫。同理,当SNVS_TAMPER1输出高电平的时候Q1不导通,那么蜂鸣器就没有形成一个通路,因此蜂鸣器也就不会鸣叫。
实验源码
bsp源码
#ifndef __BSP_CLK_H
#define __BSP_CLK_H#include "imx6ul.h"/* 函数声明 */
void clk_enable(void);#endif
#include "bsp_clk.h"
#include "imx6ul.h"
/** @description : 使能I.MX6U所有外设时钟* @param : 无* @return : 无*/
void clk_enable(void)
{CCM->CCGR0 = 0XFFFFFFFF;CCM->CCGR1 = 0XFFFFFFFF;CCM->CCGR2 = 0XFFFFFFFF;CCM->CCGR3 = 0XFFFFFFFF;CCM->CCGR4 = 0XFFFFFFFF;CCM->CCGR5 = 0XFFFFFFFF;CCM->CCGR6 = 0XFFFFFFFF;
}
#ifndef __BSP_DELAY_H
#define __BSP_DELAY_H
#include "imx6ul.h"/* 函数声明 */
void delay(volatile unsigned int n);#endif
#include "bsp_delay.h"
#include "imx6ul.h"
/** @description : 短时间延时函数* @param - n : 要延时循环次数(空操作循环次数,模式延时)* @return : 无*/
void delay_short(volatile unsigned int n)
{while(n--){}
}/** @description : 延时函数,在396Mhz的主频下* 延时时间大约为1ms* @param - n : 要延时的ms数* @return : 无*/
void delay(volatile unsigned int n)
{while(n--){delay_short(0x7ff);}
}
#ifndef __BSP_LED_H
#define __BSP_LED_H
#include "imx6ul.h"#define LED0 0/* 函数声明 */
void led_init(void);
void led_switch(int led, int status);
#endif
#include "bsp_led.h"
#include "imx6ul.h"/** @description : 初始化LED对应的GPIO* @param : 无* @return : 无*/
void led_init(void)
{/* 1、初始化IO复用 */IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0); /* 复用为GPIO1_IO03 *//* 2、、配置GPIO1_IO03的IO属性 *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 低转换率*/IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0);/* 3、初始化GPIO,GPIO1_IO03设置为输出*/GPIO1->GDIR |= (1 << 3); /* 4、设置GPIO1_IO03输出低电平,打开LED0*/GPIO1->DR &= ~(1 << 3);
}/** @description : LED控制函数,控制LED打开还是关闭* @param - led : 要控制的LED灯编号* @param - status : 0,关闭LED0,1 打开LED0* @return : 无*/
void led_switch(int led, int status)
{ switch(led){case LED0:if(status == ON)GPIO1->DR &= ~(1<<3); /* 打开LED0 */else if(status == OFF)GPIO1->DR |= (1<<3); /* 关闭LED0 */break;}
}
#ifndef __BSP_BEEP_H
#define __BSP_BEEP_H#include "imx6ul.h"/* 函数声明 */
void beep_init(void);
void beep_switch(int status);
#endif
#include "bsp_beep.h"
#include "imx6ul.h"
/** @description : 初始化蜂鸣器对应的IO* @param : 无* @return : 无*/
void beep_init(void)
{/* 1、初始化IO复用,复用为GPIO5_IO01 */IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01,0); /* 2、、配置GPIO1_IO03的IO属性 *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 低转换率*/IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01,0X10B0);/* 3、初始化GPIO,GPIO5_IO01设置为输出 */GPIO5->GDIR |= (1 << 1); /* 4、设置GPIO5_IO01输出高电平,关闭蜂鸣器 */GPIO5->DR |= (1 << 1);
}/** @description : 蜂鸣器控制函数,控制蜂鸣器打开还是关闭* @param - status : 0,关闭蜂鸣器,1 打开蜂鸣器* @return : 无*/
void beep_switch(int status)
{ if(status == ON)GPIO5->DR &= ~(1 << 1); /* 打开蜂鸣器 */else if(status == OFF)GPIO5->DR |= (1 << 1); /* 关闭蜂鸣器 */
}
main.c汇编文件源码
.global _start /* 全局标号 *//** 描述: _start函数,程序从此函数开始执行,此函数主要功能是设置C* 运行环境。*/_start:/* 进入SVC模式 */mrs r0, cpsrbic r0, r0, #0x1f /* 将r0寄存器中的低5位清零,也就是cpsr的M0~M4 */orr r0, r0, #0x13 /* r0或上0x13,表示使用SVC模式 */msr cpsr, r0 /* 将r0 的数据写入到cpsr_c中 *//* 设置栈指针,* 注意:IMX6UL的堆栈是向下增长的!* 堆栈指针地址一定要是4字节地址对齐的!!!* DDR范围:0X80000000~0X9FFFFFFF*/ldr sp,=0X80200000 /* 设置用户模式下的栈首地址为0X80200000,大小为2MB */b main /* 跳转到main函数 */
#include "bsp_clk.h"#include "bsp_delay.h"#include "bsp_led.h"#include "bsp_beep.h"#include "imx6ul.h"/** @description : main函数* @param : 无* @return : 无*/int main(void){clk_enable(); /* 使能所有的时钟 */led_init(); /* 初始化led */beep_init(); /* 初始化beep */while(1) { /* 打开LED0和蜂鸣器 */led_switch(LED0,ON); beep_switch(ON);delay(1000);/* 关闭LED0和蜂鸣器 */led_switch(LED0,OFF); beep_switch(OFF);delay(1000);}return 0;}
链接文件源码
SECTIONS{. = 0X87800000;.text :{03_obj/start.o *(.text)}.rodata ALIGN(4) : {*(.rodata*)} .data ALIGN(4) : { *(.data) } __bss_start = .; .bss ALIGN(4) : { *(.bss) *(COMMON) } __bss_end = .;}
第1行先写了一个关键字“SECTIONS”,后面跟了一个大括号,这个大括号和最后一行的大括号是一对,这是必须的。看起来就跟C语言里面的函数一样。
第2行对一个特殊符号“.”进行赋值“.”在链接脚本里面叫做定位计数器,默认的定位计数器为0。设置定位计数器为0X87800000,因为我们的链接地址就是0X87800000开始。就是用户编写的代码地址也就是这里的汇编文件。
第3行的“.text”是段名,后面的冒号是语法要求,冒号后面的大括号里面可以填上要链接到“.text”这个段里面的所有文件, "*(.text)"中的“*”是通配符,表示所有输入文件的.text段都放到".text”中,设置链接到开始位置的文件为start.o,因为start.o里面包含着第一个要执行的指令,所以一定要链接到最开始的地方。
第4行,只读数据放在紧接代码段(tex段)后面de地方,ALIGN(4)4字节对齐。
第5行放可读可写数据。
第6行记录__bss段存储开始地址_bss段就是存储了一些定义了但是没有被使用的变量。
第7行__bss存放紧跟在可读可写数据后面。
第8行记录__bss段结束地址。
Makefile源码
CROSS_COMPILE ?= arm-linux-gnueabihf-TARGET ?= beepCC := $(CROSS_COMPILE)gccLD := $(CROSS_COMPILE)ldOBJCOPY := $(CROSS_COMPILE)objcopyOBJDUMP := $(CROSS_COMPILE)objdumpINCDIRS := 01_imx6ul \02_bsp/01_clk \02_bsp/03_led \02_bsp/02_delay \02_bsp/04_beepSRCDIRS := 04_project \02_bsp/01_clk \02_bsp/03_led \02_bsp/02_delay \02_bsp/04_beepINCLUDE := $(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 %, 03_obj/%, $(SFILENDIR:.S=.o))COBJS := $(patsubst %, 03_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) : 03_obj/%.o : %.S$(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<$(COBJS) : 03_obj/%.o : %.c$(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<clear:rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)
1~6行都是给变量赋值
7行是给变量赋值所有包含的.h文件路径
8行是给变量赋值所有包含源文件.c.s文件路径
9行给头文件前面加一个-I 并赋值给变量
10行是给查找路径下的所有.s和.c文件赋值给变量(带路径)
11~12行是去掉路径只留下文件名
13~14行生成.o文件的路径
15行所有.o文件路径的集合
16行TARGET.bin依赖于OBJS变量的.o文件
17行链接脚本
18行生成二进制文件
19行生成反汇编文件
20行SOBJS变量依赖03_obj/%.o文件下的.o文件,文件下面的.o文件又依赖于.s文件
21行编译生成.o文件
22~23行和上面2行同理只不过是依赖.c
24行删除编译过程中的文件
05_I.MX6ULL工程管理与蜂鸣器实验相关推荐
- BSP 工程管理实验
BSP 工程管理实验 我们必须对工程文件做管理,将不同功能的源码文件放到不同的目录中.另外我们也需要将源码文件中,所有完成同一个功能的代码提取出来放到一个单独的文件中,也就是对程序分功能管理. 新建名 ...
- 【网络工程管理 第三章】 各类网络设备 交换机 VLAN配置实验
网络工程管理 第三章 各类网络设备 交换机 VLAN配置实验 网络设备的功能层次 OSI层次 地址类型 设备 传输层及以上 应用程序进程地址(端口号) 网关(协议转换器) 网络层 网络地址(IP地址) ...
- OpenHarmony设备的开发环境搭建与工程管理(Ubuntu系统环境)
文章目录 开始前的废话 本篇文章是介绍在**Ubuntu环境**下,如何搭建一套完整的可视化开发环境.笔者经过测试Ubuntu 20.04系统环境下操作都可以实现. 开发环境的搭建 第一步: 修改Ub ...
- 使用gpio输出驱动蜂鸣器出现破音_探索者 STM32F407 开发板资料连载第七章 蜂鸣器实验...
1)实验平台:探索者 STM32F407 开发板 2)摘自<STM32F4 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第七章 蜂鸣器实验 上一章,我们介绍了 ...
- python在工程管理专业的应用_专业篇丨建筑环境与能源应用工程专业和建筑电气与智能化专业...
微信搜索公众号[闻道识荆],获取更多资讯. 今天,我们为大家介绍另外两个与土木工程相关的交叉复合专业--建筑环境与能源应用工程和建筑电气与智能化. 远古时期,我们的祖先在复杂的进化过程中,从树上逐渐移 ...
- 51单片机 | 蜂鸣器实验
文章目录 一. 蜂鸣器介绍 二.硬件设计 三.软件设计 四.实验现象 通过单片机的一个 IO 口控制 板载无源蜂鸣器,实现蜂鸣器控制. 一. 蜂鸣器介绍 蜂鸣器是一种一体化结构的电子讯响器,采 ...
- haribote系统调用 工程管理及应用程序阅读注释
[ 1] haribote ipl09.nas 引导程序阅读注释. [ 2] haribote asmhead.nas 从实模式进入保护模式程序阅读注释. [ 3] haribote dsctbl.c ...
- MEM工程管理硕士的含金量与就业前景?
MEM工程管理硕士的含金量与就业前景?修改 13年7月毕业,工作半年,想知道MEM现在的含金量怎么样,比起普通硕士而言呢?毕业前景如何,社会认可度高不高?我现在就比较想考这个,想在多学习学习,还有没有 ...
- 水利水电工程管理与实务电子版习题_水利水电工程管理与实务复习题集
内容概要 为了帮助全国二级建造师执业资格考试水利水电专业应考人员进一步理解考试大纲和考试用书,加深对考点和知识点的理解和掌握,提高复习效率,巩固复习效果,提高应考人员的解题能力,本书编委会依据< ...
最新文章
- 360金融沈赟:只有适配实践的技术才能实现价值掘金
- ios相机黑边_黑边很碍眼很难看 苹果iPhone6黑边有什么用呢?
- python界面设计-python图形化界面设计tkinter
- 人脸识别翼闸使用规范_人行通道闸如何搭配人脸识别使用
- 2013 2016 年期末考试
- oracle中区间大小,Oracle的逻辑结构(表空间、段、区间、块)——总结
- Ozon Tech Challenge 2020 (Div.1 + Div.2) E.Kuroni and the Score Distribution 构造
- 重构手册阅读笔记:重构的含义
- 百度AI学习-错误类型大全
- 20170521第三讲
- 活动目录中组的类型和可用范围
- 为什么刹车热了会失灵_刹车油只要不缺,没必要更换,真的是这样吗?
- 15. 链表中倒数第k个节点(C++版本)
- python分行政区域汇总_python:编写行政区域三级菜单(day 1)
- Oracle彻底卸载干净教程
- 总结:硬盘随机读写与顺序读写的性能差异
- 10.2项目干系人管理+信息系统项目管理+野马合集
- 1v1微信聊天测试点
- VBA-使用inputbox方法
- 我的个人博客网站是怎么制作的?