描述
<div class="document">
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">* 1、项目功能介绍</h3>
<hr class="horizontal-splitline normal-bold-2">
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<p>条形码已经成为当今生活中密不可分的一部分,它因为实现简单价格低廉的原因,广泛用于用于商品销售,工矿企业的物料管理等等方面。</p>
<p>通常人们使用条码枪来进行条码的读取。</p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><img src="//image.lceda.cn/pullimage/NMzPbp2WZZ2KArJKnObkwoRfI2ipahkIGPI8FLrG.jpeg" alt="" width="468" height="312"></p>
<p>这种设备插入电脑后通常会将自身模拟为键盘,这样可以在光标处直接键入扫描到的条码;同样的,它也可以切换为串口设备,这样能够通过应用程序读取到扫描到的条码。但是,目前为止我还没有见过同时模拟为键盘和串口设备的条码枪。而在生产中,我们希望在指定的位置输入条码同时后台也能从串口读取到条码。</p>
<p>这次制作的设备就是一个可以使得USB条码枪同时实现USB键盘和串口设备的设计。将USB条码枪插入这次的设备后,再将设备接入主机后,主机端会出现 USB键盘和 USB串口。当使用条码枪扫描到条码后,一方面会以键盘的形式键入条码,另外一方面,你可以使用应用程序进行串口通讯,从串口获得条码。</p>
<p> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*2、项目属性</h3>
<hr class="horizontal-splitline normal-bold-2">
<p>原创,首次公开。 </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">* 3、开源协议</h3>
<hr class="horizontal-splitline normal-bold-2">
<p><strong>LGPL</strong> </p>
<p style="line-height: 1.8;"> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><strong><span style="color: #0093e6;">请在竞赛阶段填写 ↓</span></strong></p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*4、硬件部分</h3>
<hr class="horizontal-splitline normal-bold-2">
<p>整体设计分为2部分,第一部分是要实现从USB口读取条码枪的输入。这里使用 CH554 来实现。CH554一款兼容MCS51指令集的增强型E8051内核单片机,最高24MHz系统主频,内置16K程序存储器ROM和256字节内部iRAM以及1K 字节片内xRAM,xRAM支持DMA直接内存存取。<br>CH554内置了ADC模数转换、触摸按键电容检测、3组定时器和信号捕捉及PWM、双异步串口、SPI等功能模块,支持USB-Host主机模式和USB-Device设备模式。</p>
<p><img src="//image.lceda.cn/pullimage/IGBdM3DJeamPUMpf3bzLb934fywy62ZSPLozCjb6.jpeg" alt="" width="544" height="258"></p>
<p>我们这次的设计就是使用到了它提供的USB Host 功能。选择Ch554e 这是MSOP10封装,体积非常小。对应电路如下,就是一个最小系统,通过USB 母头连接USB条码枪,对外通过串口进行通讯:</p>
<p><img src="//image.lceda.cn/pullimage/ysHseNIXunNMD7WDYSg4x9C6gH6ZcDPeRWsAhuIf.png" alt="" width="624" height="421"></p>
<p>另外一部分是 ESP32-S3, S3 带有 USB 接口, 能够方便的实现USB设备的模拟。同样电路设计非常简单,外围只是让它能够工作的电容和电阻:</p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt pap-left-indent-1.6em" style="line-height: 1.8;"><img src="//image.lceda.cn/pullimage/ixDN9UANgx1LbXY32mCXaLKFxFlEJlCPz2gq9IxP.png" alt="" width="624" height="397"></p>
<p>最终的 PCB设计如下:</p>
<p><img src="//image.lceda.cn/pullimage/cUoVpqIW3IaGQ4GqG5W44BYxNIMZBjCbdGiihj9S.png" alt="" width="624" height="465"></p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*5、软件部分</h3>
<hr class="horizontal-splitline normal-bold-2">
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<p>基本设计思路是:CH554 作为 USB Host 负责解析USB条码枪的数据,然后通过串口将数据发送给 ESP32-S3。后者负责模拟一个USB键盘一个 USB CDC 设备。每次收到条码数据先从USB键盘发送给主机,然后将条码数据同时存放在内存中等待上位机通过串口进行查询。</p>
<p> </p>
<p>Ch554的关键代码:</p>
<p> </p>
<p> /* 操作HID复合设备 */</p>
<p> loc = SearchTypeDevice( USB_DEV_CLASS_HID ); // 在ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号 </p>
<p> if ( loc != 0xFFFF ){ // 找到了</p>
<p> printf( "Query USB_DEV_CLASS_HID @%04X\n", loc ); </p>
<p> loc = (UINT8)loc; //554只有一个USB,只需低八位即可</p>
<p> </p>
<p> for(k=0;k!=4;k++)</p>
<p> { </p>
<p> //端点是否有效?</p>
<p> endp = loc ? DevOnHubPort[loc-1].GpVar[k] : ThisUsbDev.GpVar[k]; // 中断端点的地址,位7用于同步标志位 </p>
<p> if ( (endp & USB_ENDP_ADDR_MASK) == 0 ) break;</p>
<p> </p>
<p> printf("endp: %02X\n",(UINT16)endp);</p>
<p> SelectHubPort( loc ); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址</p>
<p> s = USBHostTransact( USB_PID_IN INTERVALPERCODE)) {</p>
<p> if (DEBUGMODE) {</p>
<p> Serial0.print("Barcode:");</p>
<p> Serial0.println(OneInput);</p>
<p> Serial0.print("Lenth:");</p>
<p> Serial0.println(strlen(OneInput));</p>
<p> }</p>
<p> // 给字符串赋予一个结尾 0</p>
<p> OneInput[OneLength] = 0;</p>
<p> </p>
<p> for (int i=0;i</p></div>
评论(0)