利用USB控制器设计的Windows音量控制器
扫描二维码
随时随地手机看文章
本设计的首要目的就是,寻找一种快捷的方法来调整音量或者暂停播放,而不需要移动鼠标来寻找Windows Media Player窗口。该系统插在USB端口上,只有一个旋钮起主要作用。旋转这个按钮可以调节音量。按一次旋钮暂停播放,再按一次开始播放。由于该旋钮掌控主要的Windows音量控制,因此,它可以调节任何当前播放声音的音量,例如,电子邮件提示音或者是游戏声音。该音量控制器即使在Windows播放器不是当前操作窗口的情况下也仍然对其有效。为了省去设计底层驱动程序的工作,把该器件设计成USB人机接口设备(HID)。把HID接入Windows系统,它就可以工作了。
1 低成本的USB系统
系统设计中最重要的一点是,选
这里简单介绍一下MAX3420。它是Maxim公司推出的一种全速USB(12 Mbps)外设控制器,支持USB2.0协议。MAX3420内建全速收发器,支持±15 kV的ESD保护,可以编程控制USB总线的连接和断开;内含的串行接口引擎可以控制底层的USB协议细节,如错误校验和总线重连接。MAX3420通过SPI接口操作其内部寄存器,工作频率为26 MHz,任何支持SPI主模式的CPU只使用3~4根线便可增加USB功能。
图1是本系统的电路原理。U1是USB控制器MAX3420E。U2是MAX6349TL,它可提供3.3 V、150 mA的输出,具有上电复位(POR)电路,可直接与MAX3420E的RES引脚连接。在USB外设这样的热插拔设计中,良好的外部POR电路非常重要。与USB连接头上的 VBUS5 V信号相连接,并且将其调整至MAX3420E和ATtiny13所需的3.3 V。旋转编码器和发光二极管与MAX3420E的通用I/O引脚相连接。连接器J2用于ATtiny的调试和编码输入。电阻R1将编程/输入复位同系统复位隔开。上拉电阻R2确保当编程器或ICE使用调试连接器J2时,MAX3420E的SPI端口不被选中。
ATtiny13在管理MAX3420E的SPI端口时采用半双工模式,只使用一个双向数据引脚。电阻R3可避免在使用这种方式读取MAX3420E寄存器数据时的争用问题。在第8个SCLK信号上升沿到来时,MAX3420E的SPI开始对命令字节的第8位进行采样,并在第1个数据位到来后立即驱动数据引脚。
2 对话式SPI[1]
ATtiny13并不包含有SPI硬件单元。MAX3420E的SPI比较简单,且可以任意速率运行,可以对ATtiny13的I/O引脚进行位响应。
MAX3420E在三线、四线或五线SPI情况下都可以工作。另外还有几个不可省去的信号:串行时钟信号(SCLK)、从器件选择(SS)以及双向数据引脚的主控制器输出从机输入/主控制器输入从机输出 (MOSI/MISO)信号。本设计中用一条4位的引线把ATtiny13的一个输入引脚同MAX3420E的INT引脚连接起来,以便节约码字空间并使得SPI总线通信量最小。
图1 音量控制器的电路原理图
3 HID基础
USB HID规范的主要思想是要定义一个可以和应用程序联合应用的传感器、按钮和LED的广泛的类型范围。“USB器件使用者论坛”的“通用串行总线HID用法表”中详述了数百种用法。HID协议是双方面的协议,HID器件和Windows应用都必须同意使用HID规范中的特定码符。HID文件是概念性的但却有相当复杂的说明。
HID外部设备通过发送报告与Windows进行通信。HID设计的主要任务是要创造出一种可以传达对操作系统控制意图的报告格式。对于此项设计,需要对以下几项进行控制:音量加、音量减、暂停、播放、下一曲目和上一曲目。这几项中的每一项在HID用法表中都有一个描述项。
下面的程序是HID报告描述符。它是用从网站www.USB.org.上得到的HID工具程序构建的。
.DB 0x05,0x0C
;使用页面(用户).DB 0x09,0x01
;远程控制.DB 0xA1,0x01.DB 0x15,0x00
;Logical Minimum = 0.DB 0x25,0x01
;Logical Maximum = 1.DB 0x09,0xE9
;VOL+.DB 0x09,0xEA
;VOL-.DB 0x09,0xB1
;Pause.DB 0x09,0xB0
;Play.DB 0x09,0xB5;检测下一次
.DB 0x09,0xB6;检测前一次
.DB 0x75,0x01;描述符报告大小
.DB 0x95,0x06;描述符报告数量
.DB 0x81,0x02;输入描述符报告
.DB 0x75,0x01;描述符报告大小
.DB 0x95,0x02;描述符报告数量
.DB 0x81,0x01.DB 0xC0
当主机发出“获取描述符报告”要求时,ATtiny13将该表返回给主机。报告描述符的格式是单字节报告,以使用(VOL+)行开头的描述符将二进制数据集合到一个以LSB开头的字节内。控制项只需要6
位,所以该字节内的最后两位被赋予0值。描述符报告格式如下:
当Windows识别并进行USB枚举后,为了得到上述格式的单字节响应,操作系统开始向终端3IN发送周期性IN请求。该部件监控旋转控制的变化情况,并且当有动作(如音量增加)请求时发送通信数据;没有动作请求时,该固件返回0值。
MAX3420E简化了USB修改过程,SPI主控器(即ATtiny13)将报告数据字节写入EP3INFIFO(endpoint 3 IN FIFO)的寄存器。然后SPI主控器将数值1写入EP3INBC(endpoint3IN byte count)寄存器,表示为了响应USB的下一个IN请求,将会传送1个字节。传送发生后,MAX3420E产生中断请求,表明下一个字节的数据可以写入EP3INFIFO了。
下面是完整的传送程序。可以将音量控制器的HID信息传送给PC机。看似非常简单,但是该编码却包含了很多的HID控制页面。剩余的代码实现代码循环。该循环会检测旋转控制器,然后点亮发光二极管。对任意USB外围器件来说,USB样板文件代码需要进行内部处理。这个样板文件代码控制着器件的枚举、悬挂、恢复以及USB总线置零等命令。
Send_byte:
idi MAX_Reg,rEP3INFIFO
mov MAX_Dat,audio_flags
clr audio_flags
rcall wreg
idi MAX_Reg, rEP3INBC
mov MAX_Dat,1
rjmp wreg
4 读取旋转控制
旋转编码器用格雷编码端子A和B分别表示顺时针和逆时针旋转。旋转控制器与MAX3420E上有内置上拉电阻的GPIN引脚相连。图2显示的是左旋和右旋时的开关转接状态。锁定位置状态1和3是控制停止位置。控制器经过1个或3个状态后,可到下一个锁定位置。该固件只需对旋钮旋转进行译码,就可以实现向锁定状态1和3的转换。例如,实现右旋状态转换需要由3到1或由2到3。
图2 旋转编码器的开关连接状态
5 完善代码
ATtiny13有512字长的程序存储空间。编码需要完成以下几项工作: 首先要对设备进行枚举。这一步包括对MAX3420主控制器的各种类型的“获取描述符”请求进行解码,对对应的表数据进行定位以及对终端零值FIFO进行数据写入,以将其传送至固件。
编码时也应该为随时发生的USB总线置0以及USB总线的悬挂和恢复进行测试。必须对旋转控制位置和按钮开关状态进行周期性读取和译码。当主机接受了由EP3IN传来的用于发送HID控制数据的信息包后,该代码还必须为下一次的IN传送进行终端的数据加载,并为下一次的数据传输表明控制端点。
为了减小代码量,设计过程中采用下面的方法: 第一,省去了可选择性USB串描述符。这些描述符是描述诸如供应商、器件类型等的文本串。这些字符串只是信息性质的,对USB外围器件的操作来说,没有任何价值。第二,没有使用可选择性USB遥控唤醒部分。这个部分实现起来并不困难(MAX3420E会承担这项工作的绝大部分),但是却会占用码字空间。第三,没有把HID报告的描述符写入程序闪存器,而是写入EEPROM。ATtiny13有64字节的EEPROM,可以写入该EEPROM的任意表数据,都会保存在程序闪存器中。
6 写入代码
如果只用图符方式进行此项设计,那么可以用6引脚的J2连接AVRISP2在线程序设计器来下载这些程序模块。如果想要研究或修改该代码,也可以把ATJTAGICE2ND(用于AVR系列的完全在线仿真器)连接到J2上。不管使用哪种下载方式,都不要忘记把HEX文件(闪存器代码)和EEP模块(EEPROM数据)都写进去。
7 总结[2]
现在的电子应用中,USB接口几乎已经取代了串行接口成为PC机上接口连接的首选。本设计表明:虽然USB比串行端口更为复杂,但是USB连接却并不需要更多的代码或者昂贵的微处理器。代码的绝大部分是USB样板文件,因此可以在多项设计中重复使用它。另外,USB有巨大的优势:从电缆中获取电源,自动的“握手”和错误检测以及可以进行热插拔。如果想要保留已有的MCU和工具,可以采用诸如MAX3420E那样的基于SPI的USB控制器来搭建USB外围电路。
参考文献
[1] Maxim公司.MAX3420 datasheet,2005-09-26.
[2] 张弘.USB接口设计[M].西安:西安电子科技大学出版社,2002.
[3] 卢珞.罗婷. 基于SPI的USB控制器接口设计[J]. 单片机与嵌入式系统应用,2006(12): 41-45.