当前位置:   article > 正文

全网首发!大众宝来高尔夫polo领驭迈腾帕萨特奥迪A4A6B6B7等老车机增加带蓝牙控制的AUX解码模块,支持小程序原车按钮控制,支持外接高品质蓝牙模块_蓝牙车机 解码

蓝牙车机 解码

前言

​ 之前写过四篇关于车机增加音频输入的方法。

1、07宝来经典车机CD收音机(RC668)改装增加蓝牙播放音乐

2、全网首发!老大众奥迪碟盒通信协议破解,可以模拟数码碟盒,外接AUX蓝牙U盘等音频设备

3、全网首发!大众奥迪DIY数码碟盒增加USB和蓝牙播放音乐功能使用原车接口无损改装

4、全网首发,克莱斯勒大捷龙jeep道奇DIY数码碟盒增加USB和蓝牙播放音乐功能使用原车接口无损改装

​ 汽车使用寿命很长,而电子设备老化的速度很快,这就导致了10多年的老车还能在开10年,但是汽车上的电子设备基本都不能用了,比如听歌用的CD机,10年基本没有几个CD能正常工作了,为了解决老车不能听音乐,或者听音乐不方便的问题,所以设计了一款数码碟盒AUX解码模块,该模块能激活碟箱接口,通过碟箱接口接入自己喜欢的音源。保证原滋原味,音质的好坏取决于音源。

在这里插入图片描述
在这里插入图片描述

​ VWC-AB01 带蓝牙控制的AUX解码板

碟盒功能

产品型号碟箱解码开关机灯蓝牙指示灯蓝牙BLE原车按钮控制KEYIOOTA升级12V供电5V输出
VWC-AX01
VWC-AB01

1、设计指标

​ 模块规格如下:

输入电压12VDC
工作电流100mA
工作温度-40℃~+80℃
频率响应20HZ-20KHZ
长x宽x高如上图

2、PCB设计

​ AUX解码板碟箱音频接口直接引出,与控制端不共地,并且用模拟地对音频线进行包地处理,增加抗干扰能力。

在这里插入图片描述
带蓝牙控制的AUX解码板,红色部分为ble天线部分。

在这里插入图片描述

3、程序设计

贴上核心程序代码

/*捕捉中断*/
void ETM2_IRQHandler(void)
{


    uint32_t nextVal;
    uint32_t curVal = ETM2->CNT;
	
		if(ETM2->SC & ETM_SC_TOF_MASK)				//清除溢出标志位
	{
			 ETM2->SC &= ~ETM_SC_TOF_MASK;

	}
	

	if(ETM2->CONTROLS[0].CnSC & ETM_CnSC_CHF_MASK )//输入信号边沿变化
	{
		ETM2->CONTROLS[0].CnSC &= ~ETM_CnSC_CHF_MASK;

		
        if(RxInProgress == (VPW_RxStatus_t)Idle)													// 产生下降沿
        {
            RxInProgress = (VPW_RxStatus_t)SOF;
            VPW_RxBufPtr = 0;
//            ResetRx();
					
						if(VPW_TxBufPtr >1)
						{
							VPW_RxBufPtr = 0;
						}

						ETM2->CONTROLS[0].CnSC |= ETM_CnSC_ELSB_MASK; 								//切换到跳边沿检测

        }
        else if(RxInProgress == 1)
        {
            uint32_t width;
            uint8_t symIdx;
            width = GetPulseWidth(PrevCntrVal, curVal);
					
            if(width > RX_SOF_MIN && width <= RX_SOF_MAX)
            {
                symIdx = SOF_IDX;
            }
            else if(width > RX_LONG_MIN && width <= RX_LONG_MAX)
            {
                symIdx = LONG_IDX;
            }
            else if(width > RX_SHORT_MIN && width <= RX_SHORT_MAX)
            {
                symIdx = SHORT_IDX;
            }
            else
            {
                ResetRx();
                return;
            }
            VPW_RxBuf[VPW_RxBufPtr] = symIdx;
            if(TxInProgress == 1)										//正在发送
            {
                if(VPW_RxBuf[VPW_RxBufPtr] != VPW_TxBuf[VPW_RxBufPtr])
                {
                    FinalizeTx();
                }
            }
            if(VPW_RxBufPtr < sizeof(VPW_RxBuf) - 2)
            {
                VPW_RxBufPtr++;
            }
						SetTimerAlarm(239*48);
        }
        PrevCntrVal = curVal;
		
	}

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

	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

发送程序使用定时器0产生波形

/*****************************************************************************//*!
*
* @brief ETM1 回调函数
*        
* @param  none
*
* @return none
*
*****************************************************************************/
void ETM0_IRQHandler(void)
{
	   uint32_t nextVal;



		ETM_ClrOverFlowFlag(ETM0); 				//清除溢出标志位
	
		ETM_ClockSet(ETM0, ETM_CLOCK_NOCLOCK, ETM_CLOCK_PS_DIV16); 		//停止计数

	    nextVal = VPW_Symbols[VPW_TxBuf[VPW_TxBufPtr]];
	
				
        if((VPW_TxBuf[VPW_TxBufPtr] == EOF_IDX)||(VPW_TxBufPtr>=(TX_BUFLEN*8)))
        {
            FinalizeTx();
        }
        else
        {
					
					  ETM_SetModValue(ETM0,nextVal);
						ETM0->CNT = 0;
						ETM_ClockSet(ETM0, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV16); 		//开始计数

						GPIO_Toggle(GPIOA,J1850_OUT_MASK);
					
        }
        VPW_TxBufPtr++;
	
	
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

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

typedef struct
{

	
	uint8_t rnd;
	uint8_t scan;
	uint8_t playing;
	uint8_t cd_button;
	uint8_t cd_power;
	
	uint8_t cd_status;
	
	uint8_t disc;           
	uint8_t track;          
	uint8_t minute;         
	uint8_t second; 
	
	uint8_t workSta;					// 工作状态0  关机 1 待机 2工作 
	uint8_t BIDIstate;                       // pointer to the current state handler routine
	uint8_t BIDIcount;
	
	uint8_t staCount;
	
	
} CD_CHANFER_STRUCT;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

自定义车机按钮程序

void  bt_exButtonMessage(void)
{

      if(mybtEx.fbutton_flag == 0)
      {
          if(mybtEx.frst == 1)
          {
              mybtEx.fbutton_flag = 1;
              mybtEx.fbutton_value = U_BUTTON_RST;


              tmos_start_task(userApp_task_id,USERAPP_EVENT,20 * TICK_PERIOD_MS);


          }else
          if(mybtEx.fpowerOn == 1)
          {
            mybtEx.fbutton_flag = 1;
            bt_exPowerOn();
            mybtEx.fbutton_value = U_BUTTON_POWER;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT,  btMapPWMCfg.wmPowerOn.delayTime * TICK_PERIOD_MS);

          }else
          if(mybtEx.fpowerOff == 1)
          {
            mybtEx.fbutton_flag = 1;
            bt_exPowerOff();
            mybtEx.fbutton_value = U_BUTTON_POWER;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT,  btMapPWMCfg.wmPowerOff.delayTime * TICK_PERIOD_MS);

          }else
          if(mybtEx.fPlay == 1)
          {
              mybtEx.fbutton_flag = 1;


              mybtEx.fbutton_value = U_BUTTON_PLAY;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, 500 * TICK_PERIOD_MS);

          }else
          if(mybtEx.fnext == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exNext();
              mybtEx.fbutton_value = U_BUTTON_NEXT;
              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmNext.delayTime * TICK_PERIOD_MS);

          }else
          if(mybtEx.fpre == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exPre();
              mybtEx.fbutton_value = U_BUTTON_PRE;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmPrev.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fmix == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exMix();
              mybtEx.fbutton_value = U_BUTTON_MIX;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmMix.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd1 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd1();
              mybtEx.fbutton_value = U_BUTTON_CD1;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd1.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd2 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd2();
              mybtEx.fbutton_value = U_BUTTON_CD2;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd2.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd3 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd3();
              mybtEx.fbutton_value = U_BUTTON_CD3;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd3.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd4 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd4();
              mybtEx.fbutton_value = U_BUTTON_CD4;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd4.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd5 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd5();
              mybtEx.fbutton_value = U_BUTTON_CD5;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd5.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd6 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd6();
              mybtEx.fbutton_value = U_BUTTON_CD6;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd6.delayTime  * TICK_PERIOD_MS);

          }else
            if(mybtEx.btPause == 1)
            {

                #ifdef WDEBUG
                #endif
                mybtEx.fbutton_flag = 1;
                bt_exPlayPuse();
                mybtEx.fbutton_value = U_BUTTON_PAUSE;

                tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmPause.delayTime  * TICK_PERIOD_MS);

            }

      }


}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141

微信小程序程序

在这里插入图片描述

4、调试

​ AUX解码板插碟机上,搭铁开机,即可工作,这里不做详细论述。视频演示

带蓝牙控制的大众奥迪老车机AUX解码模块

下面主要讲解下,蓝牙控制AUX解码板。

4.1蓝牙控制AUX解码板

​ 现有AUX解码板只能解码不能用原车按钮控制,这样在开车的时候想要换歌曲,就需要操作手机或者其他设备,很不安全。为了解决这个问题,将解码板的主控换成带蓝牙5.3的单片机,既可以实现解码车机,又能实现原车按钮控制手机等数码产品上下一曲。

​ VWC-AB01 模组连接到车机上默认模式是AUX解码功能,当手机或其他电子设备连接蓝牙名称为:

VWCDC-SP-BLE蓝牙设备,如下图所示,手机端这时播放音乐,既可以通过车机原车按钮控制手机上下一曲播放蓝牙音乐了。
在这里插入图片描述

4.2自定义车机按钮控制其他高品质蓝牙音频模块

​ 市面上的公版蓝牙模组控制方式,大体上分为两类控制,一类是IO高低电平时间控制,另外一类是ADC按键控制。这里以ADC按键为控制方式的蓝牙模组为例,讲解如何自定义车机按键功能,控制蓝牙音频模块。
在这里插入图片描述
在这里插入图片描述

​ ADC按键原理如下图所示,核心原理就是电阻串联分压,不同按键按下,就是不同电阻与固定值的22k上拉电阻串联分压,因为每个按键对应的电阻值不同,所以可以区分不同按键按下。
在这里插入图片描述

蓝牙音频模块和解码板连接图
在这里插入图片描述

​ 根据上面原理,只要解码模块产生和按键按下相同的电压,和持续时间,就可以模拟对应按键功能了。比如下一曲对应的是0.96V,那么只要控制模块产生0.96v电压即可。那么怎么控制模块产生不同的电压呢?这里面要用到对应的微信小程序配置工具了。

4.3小程序使用

微信小程序搜索悦享行或者私聊博主发小程序
在这里插入图片描述

​ 搜索连接VWCDC-SP-BLE,连接成功后显示如下界面,默认参数为输出3.3V 持续0.5s
在这里插入图片描述
​ 根据上图可知上一曲、下一曲、暂停对应的电压值,根据实际情况设置即可,如下图所示,设置好按设置按钮,然后在读取设置参数,如果读回来的数据和写入的数据一致,那么设置成功。按对应的车机按键,模块就会输出设置的电压值和持续时间。

在这里插入图片描述

视频演示

支持小程序自定义大众奥迪车机按键功能的蓝牙控制AUX解码模块

5、模块与车机连接方法

AUX解码板连接方法
在这里插入图片描述
在这里插入图片描述

带蓝牙控制的AUX解码板连接方法
在这里插入图片描述

6、结语

有朋友反馈,找不到我,今打油诗一首

加流一壶真千金
微云澹日映寒流
信意麾毫无点误
KING_SONGING
唱奇腾怪可删修
歌咏康衢了此生
的然民仰如父母
国家涵养自建隆
王俭归来幕府非

有朋自远发来,不亦说乎!

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号