2242浏览
查看: 2242|回复: 2

[项目] 基于Ch554 制作的USB喇叭

[复制链接]
很早之前使用 Arduino Pro Micro 实现过USB耳机转接器,这次尝试使用 WCH Ch554 来实现(实际上可以使用 更见偏移的 Ch552 来实现,但是因为 Ch552 有烧写次数限制,所以最终是在 Ch554上进行开发)。
无需过多了解 USB Audio的相关知识,所作的工作基本上只有:通过描述符报告自己是一个USBAudio 设备。之后 Windows 就会发送 48Khz 16位双声道的采样数据给设备(如果想了解更多,推荐去USB中文网阅读相关内容)。我们在设备响应的 OUTPUT 端点上即可收到数据。
需要特别注意的是,代码中有一个向HOST汇报当前支持采样率的描述符。这里申明了2个采样率:22,050Hz48000Hz
  1.   0x0E,          //Size of the descriptor, in bytes  
  2.   0x24,          //CS_INTERFACE Descriptor Type  
  3.   0x02,          //FORMAT_TYPE descriptor subtype  
  4.   0x01,          //FORMAT_TYPE_I  
  5.   0x02,          //Indicates the number of physical channels in the audio data stream.  
  6.   0x02,          //The number of bytes occupied by one audio subframe. Can be 1, 2, 3 or 4.  
  7.   0x10,          //The number of effectively used bits from the available bits in an audio subframe.  
  8.   0x02,          //Indicates how the sampling frequency can be programmed:  
  9.   0x22,0x56,0x00, //          Sampling frequency 1 in Hz for this isochronous data endpoint.  
  10.   0x80,0xBB,0x00, //          Sampling frequency 2 in Hz for this isochronous data endpoint.  
复制代码

在工作过程中,Windows会通知当前使用的采样率。
基于Ch554 制作的USB喇叭图1
需要注意的是:
1.     如果你只报告支持 48000的采样率,那么Windows就不会发送 SET_CUR
2.     Windows不支持所有的采样率,我这边实验只支持48000Hz的采样率,换句话,你申明支持 24000或者22050,实际上并不会使用。

具体的数据是下面这样的,可以看到这种同步传输/等时传输的数据和通常的最大区别在于不会有 ACK 信号,相当于HOST直接丢出来不管对错。

基于Ch554 制作的USB喇叭图2

从上面可以看到每个数据之间间隔是1ms,每笔数据 192字节。
对应在代码中会在USBAudioSpeaker.c文件中的Mass_Storage_Out函数进行处理:

  1. void Mass_Storage_Out (void) {
  2.     PWM_CTRL |= bPWM2_OUT_EN;
  3.         for (uint8_t i = 0; i < BOT_EP_Rx_Length; i=i+4){               
  4.                 PWM_DATA2 = BOT_Rx_Buf[i+1];
  5.                 // Delay for 20833ns
  6.                 for (uint16_t j=0;j<51;j++) {
  7.                    __asm__ ("nop\n");
  8.                 }
  9.     }
  10.         PWM_CTRL &= (~bPWM2_OUT_EN);
  11.     //Serial0_println("Ending");
  12.         BOT_EP_Tx_ISO_Valid();
  13. }
复制代码
经过前面的工作,现在能够拿到PC输出的音频数据,接下来的问题就是如何将收到的数据通过喇叭播放出去。这个过程相当于一个 DAC (数字到模拟)的过程。这次选择的方法是:通过 PWM 进行模拟。这是使用的是CH554芯片,它支持PWM2 PWM 输出,PWM1/PWM2 2 8 。在下图可以看到 P1.5/P3.1/P3.0/P3.4都是可以选择的引脚。代码使用了 P3.4这个引脚。

基于Ch554 制作的USB喇叭图3


PWM初始化代码如下,特别注意使用了1分频产生 PWM 信号,我们使用的主频为 24Mhz 5V,因此频率是 24000000/256=93750Hz
  1.   // 打开 PWM2 功能
  2.   PIN_FUNC &= ~(bPWM2_PIN_X);
  3.   // PWM 分频设置
  4.   // 1 分频,这样 PWM 频率为 Fsys/256
  5.   PWM_CK_SE=1;
复制代码

上述设置之后,直接在 PWM_DATA2 寄存器中填写你要生成的高电平比例即可产生对应的 PWM 信号。对应的代码就在前面提到的voidMass_Storage_Out (void) {} 函数中。此外,使用NOP指令制作了一个简单的延时,延时 1/48000=20833ns
  1. // Delay for 20833ns
  2.                 for (uint16_t j=0;j<51;j++) {
  3.                    __asm__ ("nop\n");
  4.                 }
复制代码
在编译时,还需要对项目进行如下设置:
1.     选择 Ch552 Board,前面提到了Ch552和 Ch554 在代码方面是完全兼容的;
2.     设置USB为“U148BUSB Ram”

3.     Clock Source 为 “24Mhz(internal),5V”

基于Ch554 制作的USB喇叭图4

硬件方面非常简单,Ch554最小系统,喇叭接到对应引脚即可:
基于Ch554 制作的USB喇叭图5
这是我设计的用于测试 Ch554 Ch559 最小开发板。Ch554Ch559 最小系统外围只需要2个电容即可,两颗芯片相互独立:
基于Ch554 制作的USB喇叭图6
从上面可以看到,Ch55xduino提供的 USB 框架扩展性不错。Ch554可以方便的通过 Ch55xduino 实现一个USBSpeaker 的功能。目前美中不足的只是音频质量较差(所有看到的人都怀疑这个是一个收音机),后续会持续进行改进。



zoologist  高级技匠
 楼主|

发表于 2024-1-5 09:51:12

电路图和 PCB

下载附件Ch554&amp;9电路图.zip

完整的源代码
下载附件Ch554AudioOutput.zip
回复

使用道具 举报

zoologist  高级技匠
 楼主|

发表于 2024-1-5 17:51:15

工作的测试视频
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail