手机与设备音频接口通信原理及案例分析Word文件下载.docx
《手机与设备音频接口通信原理及案例分析Word文件下载.docx》由会员分享,可在线阅读,更多相关《手机与设备音频接口通信原理及案例分析Word文件下载.docx(33页珍藏版)》请在冰豆网上搜索。
方波:
方波通常使用的是曼彻斯特编码方式(什么是曼彻斯特编码自己去查),它的好处是可以用单片机直接输出方波,经过衰减后即可使用,方便简单。
缺点是兼容性不好,因为手机音频部分有这样一个特性,它只识别变化的电平信号,当麦克输入的信号长时间保持在某一非零电平时,手机会将其视为零,而强行拉回零电位。
这就是采用方波通讯方式的兼容性不好的最大原因了,并且方波也容易受干扰。
正弦波:
正弦波不会出现上面所说的方波的问题,故正弦波的兼容性和稳定性更好一些。
通常采用方案有FSK、DTMF、信号发生器、或方波转正弦波等。
(后面会对以上方案逐一分析)
通信信道分析
我们知道音频接口有4根线,MIC、地、左、右声道。
设备→手机用MIC,手机→设备用地、左、右声道中的任意一个。
这里说一下,实际产品中,有一些厂家会更换地线,即将原本左、有声道中的一根改为地线来用,其实道理是一样的。
因为音频通信的信号时交流信号,而地其实也是悬浮地,即便地线换了,最终的波形还是一样的,因为最终手机解析信号时需要的是频率和幅值。
这样还剩下一个声道,通常被用来帮助设备进行上电识别,因为音频通信的设备通常都是电池供电的。
另外还要在MIC和地之间并联一个4.99K的电阻,因为手机是通过检测MIC和地之间的阻抗是否为4.99K(也有其他阻值的)来判断是否有设备(耳机)插入,这一点要谨记。
四、各个通信方案对比分析
曼彻斯特编码:
在诸多通信方式中,曼彻斯特编码是最灵活简便的一种方法,编码信号可由单片机直接产生,经衰减电路衰减后便可直接使用。
注意事项:
曼彻斯特编码信号的生成有两种方式,一种是用PWM生成,一种是用定时器中断翻转IO,我个人比较倾向于定时器中断方式。
因为我们知道曼彻斯特编码中有宽沿河窄沿之分,且宽沿和窄沿可能会灵活变化,而用PWM方式不容易精确控制宽沿、窄沿输出的变化,而定时器中断方式则非常灵活且容易控制。
(后面会送上我自己写的曼彻斯特编码、解码函数)
FSK、DTMF方式:
FSK和DTMF两种方式大同小异,使用时通常都是用集成的芯片来生成的,而这些芯片通常都是遵守固定的通信协议的的要求(FSK为Bell202或V.23协议,DTMF记不清名字了)。
这两种通信方式的优点是采用正弦波通信、稳定性好且使用简便。
但由于固定通信协议的限制导致通信速率、比特率也受到限制而缺乏灵活性。
在这里跟他家推荐一款英国的通信芯片CMX系列,这个系列的芯片融合的FSK、DTMF的编码、解码,还是很不错的,大家有兴趣可以试试。
(相关手册在附件里)
信号发生器、锁相环方式:
这种方式用信号发生器或者锁相环来产生方波或正玄波,由单片机来控制波形的输出,也可以实现音频通信,且十分灵活。
但缺点是电路较复杂,且不同频率信号之间衔接不好掌握,用不好反而是麻烦。
d)
在这里送上一种我个人认为比较好的方案:
就是曼彻斯特编码加低通滤波器,由单片机输出曼彻斯特编码,再经由低通滤波器将方波滤成正弦波后输出。
既解决了FSK、DTMF灵活性的问题,又解决了曼彻斯特编码方波稳定性、通用性的问题。
在低通滤波器方面我个人采用的是“集成低通开关电容滤波器”,它成本虽然高一些,但好处也是明显的,电路简单,使用方便,且占用的空间亦很小。
放大电路方式:
将手机输出信号经放大电路放大到合适的幅值,然后有锁相环或者结成FSK、DTMF芯片进行解析。
该中方式难度最大,需要非常强的模拟电路功底,我个人水平有限,故采用的另一种方式。
电压比较器方式:
将手机输出的交流信号经电路强行拉到Vcc/2级别,然后加到电压比较器一端,另一段接比较电压Vcc/2,这样交流信号即被转化为TTL方波信号,此时再进行解析就变得很简单了。
五、研发注意事项(通讯方案分析部分由于过长,放到最后来讲)
一个好手机录音软件是必须的,最好能在手机上直接看到波形的。
建议用笔记本电脑进行开发,而非台式机。
因为音频信号很小,容易受干扰,而台式机干扰较大,笔记本还有一个好处是必要时可将外接电源拔掉,用电池供电。
一个好录音笔必不可少,有时需要得到纯净的音频信号,方便更加准确的分析。
4、
做一个转接板,一边接音频母座,一边接音频公头,将MIC、地、左、右声道4跟线用排阵引出,方便录音。
5、
做一个信号衰减电路,可将设备电路产生的信号衰减至音频接口能承受的范围内。
前期调试时,我们可以用该电路将信号录进电脑进行信号分析。
(推荐一个电脑音频信号分析软件:
Goldwave)
6、
录音用的音频线切记不要太长,不然会给你带来不少麻烦。
最好自己做,用音频裸头、杜邦线、排阵即可制作,方便好用。
曼彻斯特编码的编码解码函数如下:
1./**********************************************************************
2.注释:
编码函数都是采用定时器中断的形式,以曼彻斯特编码的窄沿作为定时器周期。
3.发送的数据包括1个起始位、8个数据位、1个奇偶校验位、3个停止位。
4.***********************************************************************/
5.staticvoidVIC_VECT_Fucton_00(void)//发送编码数据中断函数
6.{
7.
TIMER0IS=0x0;
8.
if((send_time%2==0)&
&
(send_start==1))
9.
{
10.
switch(FSK_txState)
11.
{
12.
caseSTARTBIT:
13.
if((GPIODATA&
0x00000002)==0x00000000)//如果检测到数据发送管脚为零
14.
send_time++;
15.
else
16.
17.
currentSym=0;
18.
FSK_txState=BYTE;
19.
}
20.
break;
21.
caseBYTE:
22.
if(txBit<
8)
23.
24.
currentSym=(send_byte>
>
txBit)&
0x01;
25.
txBit++;
26.
txParity+=currentSym;
//奇偶校验位
27.
}
28.
elseif(txBit==8)
29.
30.
currentSym=txParity&
//发送奇偶校验位
31.
32.
33.
elseif(txBit>
8&
txBit<
12)
34.
35.
//nextbitisthestopbit
36.
currentSym=1;
//发送停止位
37.
38.
}
39.
elseif(txBit==12)
40.
FSK_txState=STOPBIT;
41.
break;
42.
caseSTOPBIT:
43.
txBit=0;
44.
FSK_txState=IDLE;
45.
send_start=0;
46.
txParity=0;
47.
send_byte=0;
48.
49.
50.
if(lastSym!
=currentSym)
51.
52.
timer1_num++;
53.
lastSym=currentSym;
54.
55.
56.
if(timer1_num%2==0)
57.
GPIODATA&
=0xFFFFFFFD;
//输出管脚复位
58.
59.
GPIODATA|=0x00000002;
//输出管脚置位
60.
61.
//用来控制IO口的电平翻转
62.
//用来控制发送的字节的每一位
63.
Delay++;
//Delay就是延时函数
64.}
65./**********************************************************************
66.注释:
解码函数采用外部IO中断形式(上升沿或下降沿中断,即电平电平跳变中断),
67.用一个定时器作为时钟,每次产生中断时便从定时器见时间值取出,并和上一次的
68.记录做差求出时间间隔,以此来判断当前为宽沿还是窄沿。
69.***********************************************************************/
70.staticvoidVIC_VECT_Fucton_04(void)//接受解码数据中断函数
71.{
72.
GPIOIC|=0x00000001;
//清楚上一次中断内容
73.
RX_time=TIMER1VALUE;
74.
if(RX_lasttime>
=RX_time)
75.
RX_diff=RX_lasttime-RX_time;
//lasttime初始值为0
76.
77.
RX_diff=65535-RX_time+RX_lasttime;
78.
RX_lasttime=RX_time;
79.
switch(RX_state)
//启动代码时state已经被配置为STARTBIT
80.
81.
caseSTARTBIT_FALL:
82.
if((SHORTINTERVAL<
RX_diff)&
(RX_diff<
LONGINTERVAL))
83.
84.
if(RX_ones<
5)
//ones初始值为0
85.
86.
RX_ones=0;
87.
88.
else
89.
90.
RX_state=DECODE;
//将状态配置为解码
91.
92.
93.
elseif(RX_diff<
SHORTINTERVAL)
94.
RX_ones++;
95.
96.
RX_ones=0;
97.
98.
caseDECODE:
99.
/**************通过间隔长短来判定数据**************/
100.
LONGINTERVAL))//若间距在范围内则当前数据位值和前一个相反
101.
{
102.
currentbit=(currentbit+1)&
0x01;
103.
RX_times+=2;
104.
105.
elseif(RX_diff<
SHORTINTERVAL)
106.
107.
currentbit=currentbit;
108.
RX_times++;
109.
110.
else
111.
RX_state=DATAINIT;
112.
113.
/****************接受数据位,从低位接起****************/
114.
if(RX_times%2==0)
115.
116.
if(RX_bitcounter<
8)
117.
118.
if(currentbit==1)
119.
120.
uartByteRx=(uartByteRx>
1)+(1<
<
7);
121.
rxParity++;
//奇偶校验位
122.
RX_bitcounter++;
//接受数据位数
123.
124.
125.
126.
1);
127.
128.
129.
130.
131.
132.
rxParity&
=0x01;
//进行奇偶校验
133.
if(rxParity==currentbit)
134.
135.
136.
RX_finish=1;
137.
RX_state=DATAINIT;
138.
139.
140.
//若奇偶校验错误则,重新检测
141.
142.
143.
144.
caseDATAINIT:
//初始化参数状态
145.
RX_bitcounter=0;
146.
147.
rxParity=0;
148.
currentbit=0;
149.
RX_state=STARTBIT_FALL;
150.
RX_times=0;
151.
152.
default:
153.
154.
155.}
android音频口通信——2FSK信号调制
发布时间:
2013-5-16
一、前言
今天要和大家分享一个本人最近研发的完全具有自主知识产权的项目——android音频口通信,并寻求有兴趣的同行和友人一起合作!
大家都知道拉卡拉,但它具体的技术实现我相信很少有人能说出来个一二,本人也正是抱着遇见问题勇往直前的技术男的精神,花了一两个月的时间,完全摸透并已初步实现了用android手机的音频口(耳机输出输入)来实现全双工的通信,一但通信协议建立了,下面好玩的东西就多了!
!
你可以完全不再用担心你家的电视或者空调等此类用红外遥控的电器一时找不到遥控器而烦恼了,加上我现在研发的音频口扩展头,将其插入你的android手机的耳机口,装上特制的APP,你将可以用它来遥控你家的任何带红外遥控功能的电器!
你也可以抛开目前那种单调的耳机口防尘塞,加上相应的扩展头,你将可以实时知道你周围环境的温度、湿度等等指标……
诸如此类的运用,数不胜数,在这里我就不一一列举了,下面转入我们的正题吧(^_^不好意思,闲话说多