0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于APM32E103的USB Printer实现方案

Geehy极海半导体 ? 来源:21ic论坛极海半导体专区 ? 2025-05-23 10:29 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

来源:转载自21ic论坛极海半导体专区

目前官方SDK的USB设备例程“APM32E10x_EVAL_SDK_v1.0”只有这几个,分别是:

CDC类 虚拟串口 “USB_CDC_VirtualCOMPort”

HID类 鼠标 “USB_HID_Mouse”

MCS类 大容量存储 “USB_MSC_Disk”

上面是没有Printer类的,如果需要打印机类,可以在CDC例程的基础上进行修改,只需要几步就可以实现一个USB的打印机设备。

1、USB打印机类的基础知识

1.1、USB的设备类

常见的USB设备类有以下几种,这里要实现就是07h号打印机类。

a1ba8dc0-354c-11f0-afc8-92fbcf53809c.png

1.2、调试USB的工具软件

USB数据抓包软件 “Bus Hound”

枚举信息查看软件 “USBlyzer”

1.3、推荐几个关于USB的基础知识的网站

https://www.usbzh.com/article/detail-344.html

http://usb.baiheee.com/

1.4、 USB标准组织官网USB-IF上的资料

关于USB 2.0资料:

https://www.usb.org/document-library/usb-20-specification

关于 Printer Device Class 的文档:

https://www.usb.org/document-library/printer-device-class-document-11

2、修改描述符

首先要通过修改描述符,来枚举出“打印支持”设备。

在极海官网下载USB的SDK

https://www.geehy.com/support/apm32?id=305

APM32E10x_EVAL_SDK_v1.0.zip

注释掉不用的代码,例如LCD、KEY、LED,这些跟USB无关。

2.1 描述符的基础知识

描述符分为:

设备描述符 Device Descriptor (g_usbDeviceDescriptor)

配置描述符 Configuration Descriptor (g_usbConfigDescriptor)

端点描述符 Endpoint Descriptor (g_usbConfigDescriptor)

详细信息可以看这里:

http://usb.baiheee.com/usb_article/usb_spec/usb_cmd_desc.html

2.2 修改设备描述符

打开源文件 ....Sourceusbd_descriptor.c ,修改数组 g_usbDeviceDescriptor[] ,

这里只要把设备类从CDC 0x02 改为Printer 0x07。

/** bDeviceClass */

0x07, //0x02,

2.3 修改配置描述符和端点描述符

配置描述符和端点描述符都在数组 g_usbConfigDescriptor[] 中,我们只需要1个配置,该配置下有2个端点,删除多余的端点,修改成下面这样。

const uint8_t g_usbConfigDescriptor[USB_CONFIG_DESCRIPTOR_SIZE] =

{

/** bLength */

0x09,

/** bDescriptorType */

USBD_DESC_CONFIGURATION,

/** wTotalLength */

USB_CONFIG_DESCRIPTOR_SIZE & 0xFF, USB_CONFIG_DESCRIPTOR_SIZE >> 8,

/** bNumInterfaces */

0x01,//0x02,

/** bConfigurationValue */

0x01,

/** iConfiguration */

0x00,

/** bmAttributes */

0xC0,

/** MaxPower */

0x32,

/** bLength */

0x09,

/** bDescriptorType */

USBD_DESC_INTERFACE,

/** bInterfaceNumber */

0x00, //0x01,

/** bAlternateSetting */

0x00,

/** bNumEndpoints */

0x02, //0x01,

/** bInterfaceClass */

0x07,//0x02,

/** bInterfaceSubClass */

0x01, //0x02,

/** bInterfaceProtocol */

0x01, //0x01,

/** iInterface */

0x00,

0x07, /** bLength: Endpoint Descriptor size */

USBD_DESC_ENDPOINT, /** bDescriptorType: Endpoint */

0x01, /** bEndpointAddress */

0x02, /** bmAttributes: Bulk */

0x40,0x00, /** wMaxPacketSize: */

0x00, /** bInterval: */

0x07, /** bLength: Endpoint Descriptor size */

USBD_DESC_ENDPOINT, /** bDescriptorType: Endpoint */

0x81, /** bEndpointAddress */

0x02, /** bmAttributes: Bulk */

0x40,0x00, /** wMaxPacketSize: */

0x00 /** bInterval: */

};

2.4 测试是否枚举成功

修改完描述符后,运行程序,拔插USB,设备管理器中会出现“打印支持”,使用“USBlyzer”可以看到详细的枚举信息。

a1deb330-354c-11f0-afc8-92fbcf53809c.png

3 实现类特殊请求

3.1 添加GET_DEVICE_ID请求

DEVICE ID是打印机类特有的类请求,关系到打印机驱动的安装, 官方文档“usbprint11a021811.pdf”中有对这个的详细描述。

a1f44a6a-354c-11f0-afc8-92fbcf53809c.png

通过修改“usbd_class_cdc.c” 文件中的 “void USBD_ClassHandler()”函数来实现。

void USBD_ClassHandler(USBD_DevReqData_T* reqData)

{

uint16_t length = ((uint16_t)reqData->byte.wLength[1] << 8) |

reqData->byte.wLength[0] ;

switch (reqData->byte.bRequest)

{

case 0x00: //GET_DEVICE_ID

USBD_CtrlInData(PRINTER_DEVICE_ID, sizeof(PRINTER_DEVICE_ID));

break;

case 0x01: //GET_PORT_STATUS

USBD_CtrlOutData(&g_port_status, 1);

break;

case 0x02: //SOFT_RESET

USBD_CtrlInData(cmdBuf, length);

break;

}

}

3.2 抓包观察请求是否成功

拔插USB,通过软件“Bus Hound”可以看到USB主机发送了 GET_DEVICE_ID 请求,然后USB设备也返回了对应的字符串。

a212506e-354c-11f0-afc8-92fbcf53809c.png

4、实现数据的接收

4.1 在OUT端点中保存接收到的数据包

在USB OUT端点处理函数进行数据的接收操作,在文件 “usbd_class_cdc.c”中的 “void USBD_VCP_OutEpCallback()” 函数中添加代码。

void USBD_VCP_OutEpCallback(uint8_t ep)

{

uint32_t dataCnt;

if (ep == USBD_EP_1)

{

dataCnt = g_usbDev.outBuf[USBD_EP_1].xferCnt;

PrinterReceiveCount = dataCnt;

memcpy(PrinterReceiveData,dataBuf,dataCnt); //保存接收到的这包数据

USBD_RxData(USBD_EP_1, dataBuf, g_usbDev.outBuf[USBD_EP_1].maxPackSize); //如果想接收下一包,须加这个

//USBD_TxData(USBD_EP_1, dataBuf, dataCnt);

}

}

4.2 测试数据接收功能

为了方便查看接收到的数据,在while(1)中把接收到的数据通过串口发送出去。

int main(void)

{

APM_EVAL_Init();

printf("This is an example of USB Printer ");

while(1)

{

if(PrinterReceiveCount>0)

{

for(unsigned char i=0;i

{

USART_TxData(DEBUG_USART,PrinterReceiveData[i]);

while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);

}

PrinterReceiveCount=0;

}

}

}

通过USB发送数据需要一个上位机,这里使用“条码打印机调试助手”,插上USB后,通讯端口选择USB,然后打开端口,在数据发送框输入想发的数据,然后点右下角“发送数据”,这时可以在串口调试助手上看到MCU刚接收的数据。

如下图所示,每次USB接收到的数据都通过串口发送出来了。

a22c73cc-354c-11f0-afc8-92fbcf53809c.png

注:文章作者在原帖中提供了例程文件,有需要请至原文21ic论坛下载

原文地址:https://bbs.21ic.com/icview-3331288-1-1.html

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • usb
    usb
    +关注

    关注

    60

    文章

    8214

    浏览量

    274037
  • 打印机
    +关注

    关注

    10

    文章

    802

    浏览量

    47342
  • Printer
    +关注

    关注

    0

    文章

    5

    浏览量

    7549
  • SDK
    SDK
    +关注

    关注

    3

    文章

    1079

    浏览量

    49410
  • 虚拟串口
    +关注

    关注

    3

    文章

    63

    浏览量

    14241

原文标题:APM32芯得 EP.55 | 基于APM32E103的USB Printer实现方案

文章出处:【微信号:geehysemi,微信公众号:Geehy极海半导体】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于极海APM32E103 MCU的CoreMark测试方法

    CoreMark跑分可以了解到MCU的算力。下面以APM32E103芯片和Keil为例,介绍一下如何在APM32上面运行CoraMark测试。CoreMark需要定时器用于计时,还需要用串口来打印输出测试结果。
    的头像 发表于 06-12 09:42 ?603次阅读
    基于极海<b class='flag-5'>APM32E103</b> MCU的CoreMark测试方法

    stm32f103&gd32的usb虚拟串口,打印类printer组合设备

    stm32f103&gd32的usb虚拟串口+打印类printer组合设备@TOCstm32f103&gd32的usb虚拟串
    发表于 12-02 16:06 ?57次下载
    stm32f<b class='flag-5'>103</b>&gd32的<b class='flag-5'>usb</b>虚拟串口,打印类<b class='flag-5'>printer</b>组合设备

    极海半导体APM32E103/F072系列MCU顺利通过IEC 60730功能安全认证

    近日,极海半导体APM32E103/APM32F072系列MCU,顺利通过IEC 60730功能安全认证,并提供符合B类标准的软件安全库,有效保证了面向家用电器领域的嵌入式控制设备的软硬件安全运行,同时降低了终端产品在认证过程中投入的时间与成本。
    发表于 09-29 14:17 ?1534次阅读

    APM32E103xCxE用户手册

    APM32E103xCxE用户手册
    发表于 11-09 21:03 ?6次下载
    <b class='flag-5'>APM32E103</b>xCxE用户手册

    APM32E103xCxE数据手册

    APM32E103xCxE数据手册
    发表于 11-09 21:03 ?2次下载
    <b class='flag-5'>APM32E103</b>xCxE数据手册

    APM32E103VET6S数据手册

    APM32E103VET6S数据手册
    发表于 11-09 21:03 ?13次下载
    <b class='flag-5'>APM32E103</b>VET6S数据手册

    APM32E103VCS MINI开发板原理图

    APM32E103VCS MINI开发板原理图
    发表于 11-09 21:03 ?2次下载
    <b class='flag-5'>APM32E103</b>VCS MINI开发板原理图

    APM32E103VET6_LSE_RTC不走时

    APM32E103VET6_LSE_RTC不走时
    发表于 11-09 21:03 ?2次下载
    <b class='flag-5'>APM32E103</b>VET6_LSE_RTC不走时

    APM32E103RET6_电源_概率性出现电流噪音

    APM32E103RET6_电源_概率性出现电流噪音
    发表于 11-09 21:03 ?0次下载
    <b class='flag-5'>APM32E103</b>RET6_电源_概率性出现电流噪音

    APM32E103VET6S_SDRAM模块_SDRAM与IO口冲突问题

    APM32E103VET6S_SDRAM模块_SDRAM与IO口冲突问题
    发表于 11-09 21:03 ?1次下载
    <b class='flag-5'>APM32E103</b>VET6S_SDRAM模块_SDRAM与IO口冲突问题

    APM32F103VCT6S_USB_MAC电脑无法识别USB设备

    APM32F103VCT6S_USB_MAC电脑无法识别USB设备
    发表于 11-09 21:04 ?0次下载
    <b class='flag-5'>APM32F103VCT6S_USB</b>_MAC电脑无法识别<b class='flag-5'>USB</b>设备

    APM32E103RET6_输出端口需求_要求OCx通道输出高电平

    APM32E103RET6_输出端口需求_要求OCx通道输出高电平
    发表于 11-09 21:04 ?0次下载
    <b class='flag-5'>APM32E103</b>RET6_输出端口需求_要求OCx通道输出高电平

    APM32E103VET6_SMC_SMC驱动8080并口屏时屏幕无法点亮

    APM32E103VET6_SMC_SMC驱动8080并口屏时屏幕无法点亮
    发表于 11-09 21:04 ?2次下载
    <b class='flag-5'>APM32E103</b>VET6_SMC_SMC驱动8080并口屏时屏幕无法点亮

    APM32E103VET6_硬件问题_低功耗电流偏高

    APM32E103VET6_硬件问题_低功耗电流偏高
    发表于 11-09 21:04 ?1次下载
    <b class='flag-5'>APM32E103</b>VET6_硬件问题_低功耗电流偏高

    APM32E103ZE EVAL 原理图

    APM32E103ZE EVAL 原理图
    发表于 11-09 21:04 ?0次下载
    <b class='flag-5'>APM32E103</b>ZE EVAL 原理图