0 前言
🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
🚩 基于单片机的智能音响设计与实现
🥇学长这里给一个题目综合评分(每项满分5分)
🧿 选题指导, 项目分享:
https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md
1 简介
本项目是基于STM32单片机设计的智能音响系统,可用手机客户端控制音频文件的播报以及灯光的变化,并在OLED显示屏显示信息,JQ8900语音模块播报音乐,同时可识别用户的手势控制音频的播放和灯光的变化。
2 主要器件
- STM32F103C8T6主控芯片
- JQ8900语音模块
- HC-05蓝牙模块
- 手势识别模块
3 实现效果
手势识别模块,右滑控制音频文件,左滑控制灯光
4 设计原理
4.1 PAJ7620U2模块
简介 项目手势识别检测模块选择基于PixArt公司PAJ7620U2传感器开发的一块PAJ7620手势识别模块。网上很多店铺卖的这种 PAJ7620手势识别模块,但其实都是基于传感器设计的,只不过外围电路设计和形状外观不太一样而已,整体功能特性基本都一样。 工作原理 从上图中,我们可以看到PAJ7620U2传感器内部自带 LED 驱动器(可发射红外线信号),内置有传感器感应阵列、目标信息提取阵列和手势识别阵列。另外,PAJ7620U2作为一种光学数组式传感器,其内置LED驱动器集成了环境光和光源抑制滤波器,模块基本不受环境光干扰。 红外LED手势识别原理:
传感器工作时通过内部 LED 驱动器,驱动红外 LED 向外发射红外线信号,当传感器阵列在有效的距离中探测到物体时,目标信息提取阵列会对探测目标进行特征原始数据的获取,采集到的数据被保存在寄存器中,同时手势识别阵列会对原始数据进行识别处理,最后将手势结果存到寄存器中。
根据 PAJ7620U2传感器数据手册,用户可通过I2C接口总线采集信号并迅速识别出UP、Down、Right、Left等9种常用手势。另外PAJ7620U2还提供内置的接近检测功能,用于检测物体的接近或离开。
4.2 HC-05蓝牙模块
简介 它是汇承公司出品的一个蓝牙主从机一体可用作无线串口透传通讯的模块。
原理图 相关参数讲解
6根引脚,名称与功能如下;
- VCC 接电源的正极,电压的范围为3.3v到5.0v
- vdd 为外接供电电源输入端
- GND 地线
- TXD:模块串口发送引脚(TTL电平,不能直接接RS232电平),可直接接单片机的RXD引脚
- RXD:模块串口接收引脚(TTL电平,不能直接接RS232电平),可直接接单片机的TXD引脚
- KEY:用于进入AT状态:
- LED:这个引脚是用来检测蓝牙模块是否已经连接上了其他蓝牙设备
通讯方式(tx、rx)
HC-05通过TX和RX引脚,支持使用标准AT命令。为此,用户必须在设备启动时进入特殊命令模式。启动进入数据模式,这样它就可以与其他设备进行无线通信
常见的AT指令
AT指令不区分大小写,但是都要以回车符结尾,下面是常用的AT指令
4.3 JQ8900语音模块
JQ8900模块选用的是 SOC 方案,集成了一个 16 位的 MCU,以及一个专门针对音频解码的ADSP,采用硬解码的方式,更加保证了系统的稳定性和音质。小巧尺寸更加满足嵌入其它产品的需求。
特点
-
支持 MP3 WAV 硬件解码 -
支持采样率(KHz):8/11.025/12/16/22.05/24/32/44.1/48 -
多种控制模式:两线串口模式、一线串口控制、按键模式 -
支持上一曲,下一曲,播放、暂停、停止、选曲、等常用功能控制 -
支持播放曲目序号获取,总曲目及目录总曲目等信息获取 -
支持各种信息查询,轻松获取语音芯片的当前状态 -
支持指定曲目插播,即可以暂停当前播放的音乐,播放插播的曲目,播放完后返回原来曲目断点处播放 -
支持系统深度睡眠,睡眠后电流低至 600 微安,可以通过一线串和指令 IO 唤醒
管脚说明
通讯命令 它是支持异步串口通信,波特率9600,8位数据位,没有校验位,没有流控制,这里也要注意,在利用串口调试的时候,这些参数都要设置好,一旦有偏差都通信不了。调试的时候利用串口调试助手就可以,尤其注意一点,发送数据的时候,要勾选上以十六进制发送数据。
![在这里插入图片描述](https://img-blog.csdnimg.cn/71e5dd03cfbf429685545361cbe3252f.png#pic_center =)
5 部分核心代码
#include "paj7620u2.h"
#include "paj7620u2_cfg.h"
static void paj7620u2_selectBank(bank_e bank);
static u8 paj7620u2_wakeup(void);
u8 paj7620u2_init()
{
u8 i;
u8 status;
GS_i2c_init();
status = paj7620u2_wakeup();
if(!status)
return 0;
paj7620u2_selectBank(BANK0);
for(i=0;i<INIT_SIZE;i++)
{
GS_Write_Byte(init_Array[i][0], init_Array[i][1]);
}
paj7620u2_selectBank(BANK0);
return 1;
}
GestureData *gesture;
void Gesture_Init(void)
{
u8 i;
paj7620u2_selectBank(BANK0);
for(i=0;i<GESTURE_SIZE;i++)
{
GS_Write_Byte(gesture_arry[i][0],gesture_arry[i][1]);
}
paj7620u2_selectBank(BANK0);
gesture = (GestureData *)malloc(sizeof(GestureData));
if(NULL == gesture){
printf("Error: struct \"GESTURE_DATA\" malloc failed\r\n");
}
memset(gesture, 0, sizeof(GestureData));
}
void paj7620u2_selectBank(bank_e bank)
{
switch(bank)
{
case BANK0: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK0);break;
case BANK1: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK1);break;
}
}
u8 paj7620u2_wakeup()
{
u8 data=0x0a;
GS_WakeUp();
delay_ms(5);
GS_WakeUp();
delay_ms(5);
paj7620u2_selectBank(BANK0);
data = GS_Read_Byte(0x00);
if(data!=0x20) return 0;
return 1;
}
void uart3_init(u32 bound){
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
}
void Play(u16 cmd)
{
USART_SendData(USART3,0x7E);
delay_ms(1);
USART_SendData(USART3,0x04);
delay_ms(1);
USART_SendData(USART3,0x03);
delay_ms(1);
USART_SendData(USART3,0x00);
delay_ms(1);
USART_SendData(USART3,cmd);
delay_ms(1);
USART_SendData(USART3,0xEF);
delay_ms(1);
}
6 最后
|