全网首发,大众奥迪领驭帕萨特DIY数码碟盒增加USB和蓝牙播放音乐功能使用原车接口无损改装

全网首发!大众奥迪DIY数码碟盒增加USB和蓝牙播放音乐功能

前言

​ 1、之前写过两篇关于车机增加音频输入的方法,第一种方式:车载音频处理芯片一般和主CPU之间是IIC通信协议,而IIC总线物理层运行在总线上挂载多个设备,通过监听IIC总线发现,只有音频信号发生改变的时候主芯片才会控制音频处理芯片,根据这个原理,卡硬件bug模拟主CPU 的指令,强制控制音频处理器切换输入信号源切换到碟盒音频上,这时主机即可播放碟盒信道的音频了。链接如下:

07宝来经典车机CD收音机(RC668)改装增加蓝牙播放音乐
​ 2、在这之后虽然可以听音乐了,但是当时选择的蓝牙音质一般,而且蓝牙输出带载能力较弱,导致输出声音小。为了解决这问题,所以研究了碟盒的和主机的通信协议,通过抓取之间的数据,分析出了通信格式,进而可以通过单片机模拟碟盒和主机通信,当主机按下按钮时,单片机根据协议解析出内容,就可以知道哪个按钮按下,然后控制蓝牙动作。链接如下

全网首发!老大众奥迪碟盒通信协议破解,可以模拟数码碟盒,外接AUX蓝牙U盘等音频设备
​ 3、我以为我的教程写的和通俗易懂了,但是有一些朋友找到我,让我教他们怎么改装,这时我意识到一个问题,我认为简单的事,对于爱好者来说还是很难,所以综合了一些朋友的意见,觉得做一个可以使用蓝牙和U盘播放音乐的模块。

1、设计指标

​ 和一些朋友聊天,又调查了一番发现,有此需求的人大多是喜欢折腾有一定动手能力的人,但是老车嘛,又不想投入太多的资金改装,毕竟现在也有成熟产品在卖。我个人喜欢用蓝牙听音乐,导航啥的,可是有些朋友又喜欢用U盘听歌,AUX也有一些再用。

​ 因为我很少用AUX听歌所以决定把AUX砍掉,这样就可以减小电路板体积和系统复杂度(喜欢AUX的朋友 不要着急 有时间会出AUX版本的)。高音质高性能意味着高成本,大家都希望功能多成本少,体积还小,但是现实是做不到的,性能和是成本正比的。在结合朋友的意见,最终要实现如下功能。

在这里插入图片描述
模块规格如下:

输入电压11V-14.6V/DC
工作电流200mA
工作温度-40℃~+80℃
信噪比95dB
频率响应20HZ-20KHZ

2、方案设计

2.1、外壳选择

​ 经过几天筛选找到了下面这个外壳 ,长x宽x高 = 6x4x2 CM 还算小巧,上面有一个按键孔和一个5mmLED孔,安排一些功能将这两个孔堵上,侧面是MINIUSB和10PIN牛角座。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

2.2、蓝牙方案

​ 蓝牙选用的是定制款WR201蓝牙双模音频芯片,音频程序深度优化,减少底噪。片内集成USB 2.0主站,可以读取U盘内的音频文件进行播放,真是性能小钢炮,性价比特别高。
在这里插入图片描述

2.3、MCU方案

​ 数码碟盒和主机通信频率并不高,所以IO模拟输出时序,用定时器捕获分析输入的时序,加加上串口,IO口就可以了,根据这个需求,选择了WR32F202,至于为啥选这个呢,因为最近申请了一批样片正好这个芯片符合要求,顺道帮厂家宣传下。

3、原理图设计

根据以上需求,绘制原理图,放个 按钮 放个LED指示灯,把外壳上的窟窿堵上。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

​ 要注意的事,这里面使用78l05线性稳压降压, 由于压差比较大,78l05发热会很严重所以串联一个功率电阻,分担耗散功能,提供系统的稳定性。

4、PCB设计

在这里插入图片描述
在这里插入图片描述
要想音质好,地分割隔离少不了,再打上多多的过孔,特批是射频部分一定要多打孔。
在这里插入图片描述

放上伪3D效果图。

5、程序设计

​ 1、移植OSAL系统框架到NV32F102上,如图所示。替换timer.c定时器的内容。移植基本工作完成。
在这里插入图片描述

void PIT1_IRQHandler(void)
{
	

	PIT_ChannelClrFlags(PIT_CHANNEL1); 
  osal_update_timers();

}

/**
 * @brief 硬件定时器初始化,设定系统时钟
 */
void OSAL_TIMER_TICKINIT(void)
{
	uint32_t        u32LoadValue0;     
    PIT_ConfigType  sPITConfig;    
    PIT_ConfigType  *pPIT_Config   =&sPITConfig; 

    u32LoadValue0   = 48000 - 1;          //定时器时钟为总线时钟48M,定时1S
  
    pPIT_Config->u32LoadValue      = u32LoadValue0;
    pPIT_Config->bFreeze           = FALSE;    
    pPIT_Config->bModuleDis        = FALSE;    
    pPIT_Config->bInterruptEn      = TRUE;    
    pPIT_Config->bChainMode        = FALSE; 
    pPIT_Config->bETMerEn          = TRUE;     // 打开定时器

    PIT_Init(PIT_CHANNEL1, pPIT_Config);          

}

​ 2、移植底层驱动

根据上一篇博文的时序编写底层驱动程序,使用NV32f102 ETM2模块用来捕获输入脉冲。

初始化

    SIM->SCGC  |= SIM_SCGC_ETM2_MASK;//选通ETM1门控时钟
	ETM2->CONTROLS[5].CnSC |= ETM_CnSC_ELSB_MASK; 								//下降沿沿捕捉
	ETM_ClockSet(ETM2, ETM_CLOCK_SYSTEMCLOCK, 					ETM_CLOCK_PS_DIV16); //ETM1时钟设置-48M	/16 = 3M	
	NVIC_EnableIRQ(ETM2_IRQn);
	ETM2->CONTROLS[5].CnSC |= ETM_CnSC_CHIE_MASK;//使能中断
	  ETM_EnableOverflowInt(ETM2);									//开启TOF溢出中断

捕获脉冲

/*捕捉中断*/
void ETM2_IRQHandler(void)
{
	 if(ETM2->SC & ETM_SC_TOF_MASK)	//清除溢出标志位
    {
         ETM2->SC &= ~ETM_SC_TOF_MASK;
		TIM_ICUserValueStructure.Capture_Period ++;        
    }

	if(ETM2->CONTROLS[5].CnSC & ETM_CnSC_CHF_MASK )//输入信号边沿变化
	{
		ETM2->CONTROLS[5].CnSC &= ~ETM_CnSC_CHF_MASK;
        if ( TIM_ICUserValueStructure.Capture_StartFlag == 0 )         // 第一次捕获下降沿捕获
        {
            // 计数器清0
		ETM2->CNT=0; //清零计数器
            // 自动重装载寄存器更新标志清0
        TIM_ICUserValueStructure.Capture_Period = 0;
      // 存捕获比较寄存器的值的变量的值清0            
        TIM_ICUserValueStructure.Capture_CcrValue = 0;
            // 当第一次捕获到下降沿之后,就把捕获边沿配置为上升沿
		ETM2->CONTROLS[5].CnSC &= ~ETM_CnSC_ELSB_MASK; 								//去除下降沿沿捕捉
		ETM2->CONTROLS[5].CnSC |= ETM_CnSC_ELSA_MASK; 								//上升沿沿捕捉
      // 开始捕获标准置1            
         TIM_ICUserValueStructure.Capture_StartFlag = 1;
        }
        // 上升沿捕获中断
        else // 第二次捕获
        {
      // 获取捕获比较寄存器的值,这个值就是捕获到的低电平的时间的值
														     		TIM_ICUserValueStructure.Capture_CcrValue = ETM2->CONTROLS[5].CnV;
capturedLowPulse(TIM_ICUserValueStructure.Capture_CcrValue/3);  //3M /3 = 1us
            // 当第二次捕获到上升沿之后,就把捕获边沿配置为上升沿,好开启新的一轮捕获
	ETM2->CONTROLS[5].CnSC &= ~ETM_CnSC_ELSA_MASK; 								//去除上升沿捕捉
	ETM2->CONTROLS[5].CnSC |= ETM_CnSC_ELSB_MASK; 								//下降沿沿捕捉
      // 开始捕获标志清0        
    TIM_ICUserValueStructure.Capture_StartFlag = 0;
      // 捕获完成标志置1            
    TIM_ICUserValueStructure.Capture_FinishFlag = 1;        
        }

	}

	if(ETM2->CONTROLS[5].CnSC & ETM_CnSC_CHF_MASK )//输入信号上升沿
	{
		ETM2->CONTROLS[5].CnSC &= ~ETM_CnSC_CHF_MASK;

	}
}

定义结构体 用于保存车机播放音乐相关信息。

/** 
  * @brief U盘发送报文状态结构体定义
  */ 
typedef struct
{
	uint8		currentTruck;	/*!< 	当前曲目*/
	uint8		playMode;		/*!< 	播放模式  循环 随机*/
	uint16		fileNum;		/*!<   	有效音频文件数量*/
	uint16		trickTime;		/*!<   	当期音频总时间*/
	uint16		trickRunTime;	/*!<   	当期音频播放了时间*/

}UDISK_STRUCT; 
	
/** 
  * @brief muxVwcdc发送报文状态结构体定义
  */ 
typedef struct
{
	
	UDISK_STRUCT		musicDisk;
	
	uint8	btCarPower;			/*!< 汽车电源*/
	uint8	btReset;			/*!< bt复位*/
	uint8	btPlay;				/*!< 播放/停止*/
	uint8	btNext;				/*!< 下一曲*/
	uint8	btPre;				/*!< 上一曲*/
	uint8	btMode;				/*!< u盘 蓝牙模式*/
	uint8	fpoweren;			/*!< 电源使能*/
	uint8	frst;				/*!< 复位*/
	uint8	fPlay;				/*!< 播放/停止*/
	uint8	fnext;				/*!< 下一曲*/
	uint8	fpre;				/*!< 下一曲*/
	uint8	fbutton_flag;		/*!<   按键标志*/
	uint8	fbutton_value;		/*!<   当前处理键值*/

}AUDIO_BLE_STRUCT; 

定义按键事件

#define			U_COMMEND_RST	   			0
#define			U_COMMEND_POWER   		1
#define			U_COMMEND_PLAY   			2
#define			U_COMMEND_PUSE   			3
#define			U_COMMEND_NEXT   			4
#define			U_COMMEND_PRE	   			5
#define			U_COMMEND_UDISK	   		6   //U盘模式
#define			U_COMMEND_BLE		   		7   //蓝牙模式
#define			U_COMMEND_REPEAT		  8   //循环播放
#define			U_COMMEND_SHUFFLE		  9   //随机播放

编写接接收到cd按钮事件后向主线程发送按键消息函数

void sendVwcdcMsg( uint8 button)
{
		general_msg_data_t *msg;
								            //向统计任务发送消息
			msg = (general_msg_data_t*)osal_msg_allocate(sizeof(general_msg_data_t) + sizeof(int));
			if(msg != NULL)
			{
						//消息结构体的data数据指针偏移至申请到的内存的数据段
						//msg->data = (unsigned char*)( msg + sizeof(osal_event_hdr_t) );
						msg->data = (unsigned char*)(msg + 1);

						msg->hdr.event = button;
						msg->hdr.status = 0;
						*msg->data = button;

						osal_msg_send(userApp_task_id, (uint8*)msg);
				}

}

按键消息处理函数

/***********用户处理消息函数***********/
void uCommend_ProcessOSALMsg( uint8 task_id,osal_sys_msg_t *msg_pkt )
{
				uint8 *pda;

				static uint8 tap_count = 0;
				static uint8 tap_flag = 0;

	        while(msg_pkt)
        {
            switch(msg_pkt->hdr.event)      //判断该消息事件类型
            {

                case U_COMMEND_RST:
								{
									btReset();
								
								} break;

                case U_COMMEND_PLAY:
								{
									 btPlayPuse();
								
								} break;
                case U_COMMEND_PUSE:
								{
									 
									 btPlayPuse();
								
								} break;
                case U_COMMEND_NEXT:
								{
									printf("next \n");

									 btNext();
								
								} break;
                case U_COMMEND_PRE:
								{
									 
										btPre();								
								} break;
                case U_COMMEND_UDISK:
								{
									 
										btUdiskMode();
										setVwcdcTrack(0x00);  // U盘模式 显示00
										setVwcdcTime(0);        // 时间归零

								} break;	
                case U_COMMEND_BLE:
								{
									 
										btBleMode();		
										setVwcdcTrack(0x88);  // 蓝牙模式 显示88
										setVwcdcTime(0);        // 时间归零

								} break;	
                case U_COMMEND_REPEAT:
								{
									 
										btRepeat();								
								
								} break;
                case U_COMMEND_SHUFFLE:
								{
									 
										btShuffle();								
								
								} break;

								
                default:
                    break;
            }

            osal_msg_deallocate((uint8 *)msg_pkt);                  //释放消息内存
            msg_pkt = (osal_sys_msg_t *)osal_msg_receive(task_id);  //读取下一条消息
        }
}

​ 在系统中起两个任务,一个是用户线程,实现业务逻辑功能,另外一个任务是用来和车机进行通信监听车机按键事件的,有按键按下,就将按键消息发送到住任务里。

    osal_add_Task(vwcd_task_init, vwcd_task_event_process, 4);			//车机任务
    osal_add_Task(userApp_task_init, userApp_task_event_process, 5);    // 用户主任务

启动OSAL系统抽象层

    //添加的任务统一进行初始化
    osal_Task_init();

    osal_mem_kick();

    //允许中断
    HAL_ENABLE_INTERRUPTS();

    //设置初始任务事件,上电就需要自动轮询的任务事件可在此添加

    //启动osal系统,不会再返回
    osal_start_system();

用户任务

/**
 * @brief 当前任务的事件回调处理函数
 * @param task_id       [任务ID]
 * @param task_event    [收到的本任务事件]
 * @return uint16       [未处理的事件]
 */
uint16 userApp_task_event_process(uint8 task_id, uint16 task_event)
{

    if(task_event & SYS_EVENT_MSG)       //判断是否为系统消息事件
    {
       osal_sys_msg_t *msg_pkt;
		msg_pkt = (osal_sys_msg_t *)osal_msg_receive(task_id);      //从消息队列获取一条消息

			uCommend_ProcessOSALMsg(task_id,msg_pkt);

        // return unprocessed events
        return (task_event ^ SYS_EVENT_MSG);
    }
	
    if(task_event & USERAPP_INIT_EVENT)
    {
	
		osal_start_reload_timer(userApp_task_id, USERAPP_EVENT, 20 / TICK_PERIOD_MS);

        return task_event ^ USERAPP_INIT_EVENT; //处理完后需要清除事件位
    }
		
    if(task_event & BLE_UART_RX_EVENT)
    {
        BLE_UART_Rx.lenth = BLE_UART_Rx.u8RxCnt;
        BLE_UART_Rx.flag = 1;
        BLE_UART_Rx.u8RxCnt = 0;

        bleBtReceiveServer(1);
			

        return task_event ^ BLE_UART_RX_EVENT; //处理完后需要清除事件位
    }
	
    if(task_event & USERAPP_EVENT)
    {
			key_function_sever();
			
			#ifndef WDEBUG
				WDOG_Feed();									// 喂狗
			#endif	
			
        return task_event ^ USERAPP_EVENT; //处理完后需要清除事件位
    }
		
    if(task_event & USERAPP_BUTTON_EVENT)
    {
			
        return task_event ^ USERAPP_BUTTON_EVENT; //处理完后需要清除事件位
    }
		

    return 0;
}

​ 车机任务函数

/**
 * @brief 当前任务的事件回调处理函数
 * @param task_id       [任务ID]
 * @param task_event    [收到的本任务事件]
 * @return uint16       [未处理的事件]
 */
uint16 vwcd_task_event_process(uint8 task_id, uint16 task_event)
{
	static unsigned char led_flag = 0;
	
    if(task_event & VWCD_RECE_EVENT)
    {
			  	flag_50ms = TRUE;
				vwcdSever();
				PTC5_OUT_TOGGLE;
				sendPacketSever(NULL);

        return task_event ^ VWCD_RECE_EVENT; //处理完后需要清除事件位
    }
		
		
    return 0;
}

6、打板焊接调试

测试开关电源不稳定加个680uF电容滤波。
在这里插入图片描述

7、模块引脚及功能

7.1、模块引脚定义

在这里插入图片描述

模块引脚对照表

引脚名称引脚功能
L音频左声道输出
R音频右声道输出
AG音频模拟地
AG音频模拟地
IN模块数据输入
CLK模块时钟输出
HU开关机检测输入
OUT模块数据输出
12V模块电源输入
DG数字地 需要搭铁在车机外壳上

备注:数字地和模拟地不能连接到一起

7.2、模块连接到车机方法

​ 大众系车机常见有两种接头,8针 MINI-ISO接口和12针ISO接口。

8针插座接口定义如图所示。
在这里插入图片描述

7.4、模块与8针车机连接方法

车机与模块引脚连接对应关系表

模块引脚车机引脚模块引脚车机引脚
L19脚 左声道R20脚 右声道
AG18 模拟地AG18脚 模拟地
IN14脚数据输出CLK15脚 时钟
HU17脚开机信号OUT13脚数据输入
12V16脚12V电源DG搭铁到车机壳上

备注: 数字地和模拟地不能连接到一起

12针如图所示。
在这里插入图片描述

7.5、模块与12车机连接方法

车机与模块引脚连接对应关系表

模块引脚车机引脚模块引脚车机引脚
L8脚 左声道R9脚 右声道
AG2 模拟地AG2脚 模拟地
IN6脚数据输出CLK12脚 时钟
HU10脚开机信号OUT11脚数据输入
12V4脚12V电源DG搭铁到车机壳上

备注: 数字地和模拟地不能连接到一起

8、安装方法

1、将汽车停在安全地方熄火,拔下车钥匙;

2、根据实际情况取出汽车CD车机;

3、使用配套的线束或者根据上文接口定义自己DIY线束,通过线束将模块和车机连起来;

4、将数字地与车机外壳牢固搭铁;

5、插入钥匙打开钥匙 按车上(CD、CDC、DISC、SOURCE、SRC、MODE等按钮进入碟盒模式开始播放音乐;

6、调试没有问题后,如果不使用蓝牙,可以将模块放在车机的后方放回去,或者将模块放到手套箱中,自己喜欢放到哪都行。然后将车机放回即可安装完成;

注意:改装有风险,下手需谨慎,因车型的不同,难易程度不同,当你选择下手的时候,强烈建议找个老司机带你。

9、 使用方法

9.1 CD车机按钮功能定义

​ 由于有些大众车型车机没有mix按钮,而车机都有CD-Cd6这六个按钮,为了保证通用性,将按钮功能做了如下映射。

车机按钮映射表

车机按钮模块功能
CD1空置
CD2播放/停止
CD3随机播放/顺序播放
CD4U盘模式
CD5蓝牙模式
CD6复位
上一曲上一曲
下一曲下一曲
MIX随机播放/顺序播放(不是所有车型都有)

​ 注意事项:大众系车机上的CD1-CD6按钮,是相互锁定和自锁的关系,比如默认是CD1模式,此时按CD1按钮是不好使的,因为在当前模式下CD1被自己锁定状态不能被改变,再次按下CD1按钮CD车机不会有动作。比如我想停止播放,那么按下CD2按钮,此时停止播放,如果想要继续播放,就有先跳入别的CD模式 由于CD2-CD6都被分配了功能,而CD1按钮没有功能,所以如果想重复进入一直CD模式,可以按下CD1在按对应的按钮就可以了。比如 停止 CD2 播放 CD+CD2 其他按钮功能类似。

9.2 模块指示灯定义

​ 红灯为U盘蓝牙状态指示灯,蓝灯为模块运行状态指示灯。

指示灯状态表

灯闪烁方式模块状态
蓝灯熄灭不可以和车机通信
蓝灯快闪可以和车机通信
红灯快闪进入蓝牙
红灯常亮连接成功
红灯慢闪正在播放
红灯关闭进入关机模式

9.3 模块工作原理

​ 模块上电后会优先检查是否插入U盘,插入则屏幕会显示TRACK77如果有音乐文件则开始播放音乐,屏幕显示当前正在播放的音乐序号。否则自动进入蓝牙模式等待连接。第一次进入蓝牙模式屏幕会显示TRACK88.总得来说蓝牙模式的优先级高于U盘模式。

状态改变说明表

条件动作
正在播放音乐,此时连接蓝牙音乐停止播放,进入蓝牙模式等待播放音乐
蓝牙模式,按下U盘模式按钮开始播放音乐
蓝牙连接上,正在播放U盘音乐蓝牙发出声音自动切换到蓝牙模式

9.4 示例演示

以迈腾CD300为例进行升级改造。

第一步 准备好改装套件。
在这里插入图片描述
第二步 关闭车机电源,将插头插入对应的接口中,并将负极搭铁到车机外壳上,然后通过排线将车机和模块连接起来。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

第三步 检测连接没有问题后,打开电源,按下CD切换按钮,如果是开机状态(不建议开机安装)安装,需要按电源按钮关机5s以上,重新打开电源,按下CD切换按钮即可进入CD模式。TRACK 77 显示当前进入了U盘模式,播放音乐后TRACK XX 即为当前正在播放音乐的序号。模式切换后显示TRACK 88则是进入了蓝牙模式。在使用车机按钮控制手机播放音乐前,要通过手机先播放音乐,否则车机不能控制。在蓝牙模式播放音乐,TRACK XX和播放的音乐序号无关。
在这里插入图片描述
在这里插入图片描述

第四步 之后既可正常操作车机了,按钮CD1-CD6功能可以参考5.1按钮功能定义。

支持的一些车机照片

在这里插入图片描述奥迪A4 C5卡带机
在这里插入图片描述在这里插入图片描述大众帕萨特领驭车机,支持方向盘控制
在这里插入图片描述奥迪森林里车机
在这里插入图片描述大众领驭帕萨特NV2428支持方向盘控制

在这里插入图片描述宝来高尔夫亮线CD
在这里插入图片描述
进口领驭帕萨特德尔塔6

10、常见问题集锦

1. 问题 为什么按CD切换按钮,显示“NO DISC”,不能进入CD播放模式?

​ 答疑:1、请尝试关闭电源5s以上重新打开电源,在按CD切换按钮

​ 2、请检查状态指示灯是否正确

​ 3、请检查线缆是否损坏

2. 问题 为什么车机上一曲、下一曲、停止/播放按钮,不能控制手机播放音乐?

​ 答疑:1、重新连接蓝牙车机是没有控制权,这是蓝牙协议规定的,必须用在手机端操作播放,之后才能用车机面板控制
3. 问题 是否支持接挂电话?

增加接挂电话方法
在这里插入图片描述

11、 联系我

下面准备好了DIY套件,感觉动手吃力的朋友可以下单购买。
在这里插入图片描述
模块链接: 数码碟盒专用大众奥迪斯柯达蓝牙改装DIY U盘无损FLAC音乐播放

升级服务

​ 产品定制升级

​ 商务合作

​ 汽车电子开发

​ 电子产品开发

联系方式
在这里插入图片描述
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值