【YC690语音评估板开发指南】

由于作者水平有限,文档和视频中难免有出错和讲得不好的地方,欢迎各位读者和观众善意地提出意见和建议,谢谢!

第一部分、硬件概述

1.1 实物仿真图

图1.1评估板3D仿真图
在这里插入图片描述

如图1.1所示VoiceYC690评估板,该有以下几种特性

1.供电:支持TypeC与XH-2A端子输入5V电源;

  1. 调试接口:引出UART-TTL接口(H4),可以外接串口调试;
  2. 语音更新下载:Type-C接入电脑枚举U盘更新;
  3. 语音输出:内置8002C 3W D类功放,可直推3W 4R扬声器等;

1.2 VoiceYC690原理图

VoiceYC690原理图如图1.2所示,如看不清可打开Doc目录下的PDF文档查阅
图1.2 VoiceYC690原理图
在这里插入图片描述

第二部分、软件工具

2.1 软件概述

在 /Software 目录下是常用的工具软件:

  1. Dt2_4:配置USB设备Report描述符的工具;
  2. USBHID调试助手/呀呀USB: USB调试工具,相当于串口调试助手功能;
  3. BUSHound:总线调试工具;
  4. USBlyzer:一款专业的USB协议分析软件
  5. MDK:常用编译器;
  6. STM32CubeMX:代码生成工具;

第三部分、实战训练

3.1 实例Eg1_Joystick

目标是实现 Joystick:枚举成XY轴的平面坐标和8个按键的USB HID。

3.1.1硬件设计

图1.3 Joystick原理图

image

其中VRX1与VRY1是摇杆的电位器输出的电压信号(ADC检测);SW1则是按键,右侧H1是外接的Joystick口备用;

图1.4 KEY原理图

image

如图1.4是KEY原理图,我们只要配置8个GPIO作为输入去检测按键信号;

3.1.2 软件设计

USB设备开发需要具备一定的USB设备开发知识;关于Usb的学习,这里推荐两个学习视频和一个学习网站:

  1. USB技术应用与开发:

    https://www.bilibili.com/video/BV1sy4y1n7d9/?spm_id_from=333.33.header_right.fav_list.click&vd_source=2bbde87de845d5220b1d8ba075c12fb0

  2. CherryUSB设备协议栈教程:

    https://www.bilibili.com/video/BV1Ef4y1t73d/?spm_id_from=333.33.header_right.fav_list.click&vd_source=2bbde87de845d5220b1d8ba075c12fb0

  3. USB中文网:

    https://www.usbzh.com/

我们主要做USB HID开发,一般我们需要了解一些标准请求,还有HID类的请求;其中标准请求主要是主机获取设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符的过程,如果是HID,还有HID描述符的过程 ,以及报表描述符的过程;

一般的,我们配套的视频都有讲解USB设备枚举过程在代码中的实现,这里主要是基于STM32 HAL库的;

首先是初始化代码,我们通过STM32cubeMX软件去生成代码,具体配置请打开GamePad.ioc查阅,配套视频也有关键部分的讲解,这里不再赘述; 我们的工程使用的是Keil-MDK编译器,生成的工程目录如图1.5

image
图1.5 工程目录
其中

  • Application/MDK-ARM 存放的是启动代码;
  • Application/User/Core: main函数,中断Handler,MSP相关代码;
  • Application/User/USB_DEVICE/App:* USB设备应用代码;
  • Application/User/USB_DEVICE/Target: USB设备配置代码;
  • Drivers/STM32F1xx_HAL_Driver: HAL库驱动代码
  • Drivers/CMSIS: CMSIS相关代码
  • Middlewares/USB_Device_Library/ USB设备库代码,对应cubemx Middleware;
  • Customer: 这是我们自定义的代码;
  • Doc: 存放说明文本文档;

工程目录这里只做一次介绍,后面的样例目录大同小异。

以下USB部分内容请大家务必多看几遍代码, 我们打开工程中的main函数可以看到

int main(void)
{
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_USB_DEVICE_Init();
  MX_USART1_UART_Init();  
  Gp_ADC_Start_DMA();//启动ADC DMA并开启中断
  while (1)
  {
	Gp_SendReport();	
  }
}

其中只有Gp_ADC_Start_DMA和Gp_SendReport是我们自定义的代码;其他均是STM32CUBEMX生成;由于篇幅的原因,我们主要介绍MX_USB_DEVICE_Init;

void MX_USB_DEVICE_Init(void)
{
  /* Init Device Library, add supported class and start the library. */
  if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
  {
    Error_Handler();
  }
  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CUSTOM_HID) != USBD_OK)
  {
    Error_Handler();
  }
  if (USBD_CUSTOM_HID_RegisterInterface(&hUsbDeviceFS, &USBD_CustomHID_fops_FS) != USBD_OK)
  {
    Error_Handler();
  }
  if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
  {
    Error_Handler();
  }
}

其中USBD_Init函数中的FS_Desc数据结构里面是获取UBS设备描述符USBD_FS_DeviceDescriptor,语言ID字符串描述符USBD_FS_LangIDStrDescriptor,厂商字符串描述符USBD_FS_ManufacturerStrDescriptor,产品字符串描述符USBD_FS_ProductStrDescriptor,序列号字符串描述符USBD_FS_SerialStrDescriptor,配置字符串描述符USBD_FS_ConfigStrDescriptor,接口描述符USBD_FS_InterfaceStrDescriptor的函数指针;

上述描述符中,UBS设备描述符是必需的,其他都是字符串描述符,可选的;我们不妨打开usb描述符获取函数与usb描述符报表

/** USB standard device descriptor. */
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
  0x12,                       /*bLength */
  USB_DESC_TYPE_DEVICE,       /*bDescriptorType*/
  0x00,                       /*bcdUSB */
  0x02,
  0x00,                       /*bDeviceClass*/
  0x00,                       /*bDeviceSubClass*/
  0x00,                       /*bDeviceProtocol*/
  USB_MAX_EP0_SIZE,           /*bMaxPacketSize*/
  LOBYTE(USBD_VID),           /*idVendor*/
  HIBYTE(USBD_VID),           /*idVendor*/
  LOBYTE(USBD_PID_FS),        /*idProduct*/
  HIBYTE(USBD_PID_FS),        /*idProduct*/
  0x00,                       /*bcdDevice rel. 2.00*/
  0x02,
  USBD_IDX_MFC_STR,           /*Index of manufacturer  string*/
  USBD_IDX_PRODUCT_STR,       /*Index of product string*/
  USBD_IDX_SERIAL_STR,        /*Index of serial number string*/
  USBD_MAX_NUM_CONFIGURATION  /*bNumConfigurations*/
};

uint8_t * USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
  UNUSED(speed);
  *length = sizeof(USBD_FS_DeviceDesc);
  return USBD_FS_DeviceDesc;
}

关于USB设备描述符的介绍,注释已经非常清楚;不了解的地方可以学习一下前面的推荐两个学习视频和一个学习网站;

设备描述符找到了,我们还需要的配置描述符,接口描述符,HID描述符(如果是HID设备),端点描述符;

我们继续回到MX_USB_DEVICE_Init,可以看到USBD_RegisterClass中的USBD_CUSTOM_HID,其中USBD_CUSTOM_HID_Setup是处理USB主机的一些请求过程,包括标准请求等;而USBD_CUSTOM_HID_GetHSCfgDesc(高速)和USBD_CUSTOM_HID_GetFSCfgDesc(全速)都是配置描述符;

USBD_ClassTypeDef  USBD_CUSTOM_HID =
{
  USBD_CUSTOM_HID_Init,
  USBD_CUSTOM_HID_DeInit,
  USBD_CUSTOM_HID_Setup,
  NULL, /*EP0_TxSent*/
  USBD_CUSTOM_HID_EP0_RxReady, /*EP0_RxReady*/ /* STATUS STAGE IN */
  USBD_CUSTOM_HID_DataIn, /*DataIn*/
  USBD_CUSTOM_HID_DataOut,
  NULL, /*SOF */
  NULL,
  NULL,
  USBD_CUSTOM_HID_GetHSCfgDesc,
  USBD_CUSTOM_HID_GetFSCfgDesc,
  USBD_CUSTOM_HID_GetOtherSpeedCfgDesc,
  USBD_CUSTOM_HID_GetDeviceQualifierDesc,
};

由于我们的MCU是支持全速的,所以这里应该是USBD_CUSTOM_HID_GetFSCfgDesc,

/* USB CUSTOM_HID device FS Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
  0x09, /* bLength: Configuration Descriptor size */
  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
  USB_CUSTOM_HID_CONFIG_DESC_SIZ,
  /* wTotalLength: Bytes returned */
  0x00,
  0x01,         /*bNumInterfaces: 1 interface*/
  0x01,         /*bConfigurationValue: Configuration value*/
  0x00,         /*iConfiguration: Index of string descriptor describing
  the configuration*/
  0xC0,         /*bmAttributes: bus powered */
  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/

  /************** Descriptor of CUSTOM HID interface ****************/
  /* 09 */
  0x09,         /*bLength: Interface Descriptor size*/
  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
  0x00,         /*bInterfaceNumber: Number of Interface*/
  0x00,         /*bAlternateSetting: Alternate setting*/
  0x02,         /*bNumEndpoints*/
  0x03,         /*bInterfaceClass: CUSTOM_HID*/
  0x00,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
  0x00,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
  0,            /*iInterface: Index of string descriptor*/
  /******************** Descriptor of CUSTOM_HID *************************/
  /* 18 */
  0x09,         /*bLength: CUSTOM_HID Descriptor size*/
  CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/
  0x11,         /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
  0x01,
  0x00,         /*bCountryCode: Hardware target country*/
  0x01,         /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
  0x22,         /*bDescriptorType*/
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
  0x00,
  /******************** Descriptor of Custom HID endpoints ********************/
  /* 27 */
  0x07,          /*bLength: Endpoint Descriptor size*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/

  CUSTOM_HID_EPIN_ADDR,     /*bEndpointAddress: Endpoint Address (IN)*/
  0x03,          /*bmAttributes: Interrupt endpoint*/
  CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */
  0x00,
  CUSTOM_HID_FS_BINTERVAL,          /*bInterval: Polling Interval */
  /* 34 */

  0x07,          /* bLength: Endpoint Descriptor size */
  USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
  CUSTOM_HID_EPOUT_ADDR,  /*bEndpointAddress: Endpoint Address (OUT)*/
  0x03, /* bmAttributes: Interrupt endpoint */
  CUSTOM_HID_EPOUT_SIZE,  /* wMaxPacketSize: 2 Bytes max  */
  0x00,
  CUSTOM_HID_FS_BINTERVAL,  /* bInterval: Polling Interval */
  /* 41 */
};
static uint8_t  *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length)
{
  *length = sizeof(USBD_CUSTOM_HID_CfgFSDesc);
  return USBD_CUSTOM_HID_CfgFSDesc;
}

细心的同学可以发现,其实这个函数是获取了配置描述符,接口描述符,HID描述符,端点描述符;不过一般的,主机一般都是先请求配置描述符,然后通过配置描述符就知道了整个描述符集合的大小USB_CUSTOM_HID_CONFIG_DESC_SIZ;

现在配置描述符,接口描述符,HID描述符,端点描述符都有了,因为我们是HID设备,故而还需要报表描述符;还是回到MX_USB_DEVICE_Init,在USBD_CUSTOM_HID_RegisterInterface这个函数中的USBD_CustomHID_fops_FS结构体中的第一个成员,真是众里寻他千百度,蓦然回首,那报表描述符却在灯火阑珊处。

/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x04,                    // USAGE (Joystick)
    0xa1, 0x01,                    // COLLECTION (Application)
    0xa1, 0x02,                    //     COLLECTION (Logical)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //     LOGICAL_MAXIMUM (255)
    0x35, 0x00,                    //     PHYSICAL_MINIMUM (0)
    0x46, 0xff, 0x00,              //     PHYSICAL_MAXIMUM (255)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    0x29, 0x08,                    //     USAGE_MAXIMUM (Button 8)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x95, 0x08,                    //     REPORT_COUNT (8)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //     END_COLLECTION
    0xC0    					   //END_COLLECTION	             */
};
USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_fops_FS =
{
  CUSTOM_HID_ReportDesc_FS,
  CUSTOM_HID_Init_FS,
  CUSTOM_HID_DeInit_FS,
  CUSTOM_HID_OutEvent_FS
};

另外需要注意USBD_CUSTOM_HID_REPORT_DESC_SIZE, 这个宏是报告描述符实际数组大小,大小不对会导致枚举失败;

“#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 46”

以上报表描述符通过生成工具Dt2_4配置生成报告描述符,可以看出X,Y轴定义成无符号8位数,XY的描述占用2个字;按键一共有8个,每个大小描述是bit,8个bit即1个byte;因此XY坐标+8个按键=3个byte;我们需要上报3个byte的数据给主机(HOST)。

最后是应用程序的编写,在main函数中调用Gp_ADC_Start_DMA和Gp_SendReport,其中Gp_ADC_Start_DMA是启动ADC DMA 中断完成采样的,而Gp_SendReport则是解析ADC采样后的数据并上报;

我们是通过Gp_ADC_Start_DMA调用HAL_ADC_Start_DMA启动ADC DMA模式采样,需要传入hadc1句柄,AD_DATA数据缓存,AD_DATA_SIZE缓存大小,其中偶数索引是ADC通道0的采样数据,如AD_DATA[0],AD_DATA[2],反之则是通道2的数据;HAL_ADC_Start_IT是启动ADC1的全局中断,HAL_ADC_ConvCpltCallback是采样完成的中断回调函数,在stm32f1xx_it.c的ADC1_2_IRQHandler里面可遍历找到。

//启动ADC DMA
void Gp_ADC_Start_DMA(void)
{
    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&AD_DATA, AD_DATA_SIZE);
    HAL_ADC_Start_IT(&hadc1);
}
/**	ADC ISR
*		Handles the values from ADC after the conversion finished
*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {

    if( adcValueReady == 0 ) {
        for(i=0; i<AD_DATA_SIZE;)
        {
            AdXSum += AD_DATA[i];
            i++;
            AdYSum += AD_DATA[i];
            i++;
        }
        adcValueReady = 1;
    }

}

再来看我们的数据处理上报函数

//按键扫描
u8 key_scan(void)
{
    key=0;
    if((UPKEY)==0)
    {
        key|=BIT0;
    }else{
		key&=(~BIT0);
	}
    if((LFKEY)==0)
    {
        key|=BIT1;
    }else{
		key&=(~BIT1);
	}
    if((RGKEY)==0)
    {
        key|=BIT2;
    }else{
		key&=(~BIT2);
	}
    if((DNKEY)==0)
    {
        key|=BIT3;
    }else{
		key&=(~BIT3);
	}
    if((TBKEY)==0)
    {
        key|=BIT4;
    }else{
		key&=(~BIT4);
	}
    if((BKKEY)==0)
    {
        key|=BIT5;
    }else{
		key&=(~BIT5);
	}
    if((MDKEY)==0)
    {
        key|=BIT6;
    }else{
		key&=(~BIT6);
	}
    if((STKEY)==0)
    {
        key|=BIT7;
    }else{
		key&=(~BIT7);
	}
    return key;

}


/*	Re-maps a number from one range to another
*
*/
int32_t map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max){
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}


//处理并上报数据
void Gp_SendReport(void)
{
	u8 X=0,Y=0,Ktemp=0;
	if( adcValueReady == 1 )
	{
		Xtemp=AdXSum/10;
		AdXSum=0;
		Ytemp=AdYSum/10;
		AdYSum=0;
		if(Xtemp>Xmax)
			Xtemp=Xmax;
		if(Xtemp<Xmin)
			Xtemp=Xmin;

		if(Ytemp>Ymax)
			Ytemp=Ymax;
		if(Ytemp<Ymin)
			Ytemp=Ymin;		
		adcValueReady=0;
	}

    X=(uint8_t)map( Xtemp, Xmin, Xmax, 0, UINT8_MAX );
    Y=(uint8_t)map( Ytemp, Ymin, Ymax, 0, UINT8_MAX );
	Ktemp=key_scan();
	Joystick_Report[0]=Y;
	Joystick_Report[1]=X;
	Joystick_Report[2]=Ktemp;
	USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS,(u8*)&Joystick_Report, 3);	
					
	HAL_Delay(5);
	
}

key_scan是扫描按键,map是转换数据的范围,因为我们的ADC采样是12bit,取值04095,需要转成8bit,0255;

最后通过USBD_CUSTOM_HID_SendReport上报数据给主机。

3.1.3 下载验证

我们把固件程序下载进去可以,打开“设备与打印机”可以看到USB设备枚举成了一个Gamepad,如下图。
image

图1.5 Gamepad设备
右键打开游戏控制器后,点击属性得到下图所示界面
image
图1.6 游戏控制器
我们可以摇Joystick和按按键可以发现上图游戏控制器界面也跟着响应。

3.1.4入门视频

本期的入门视频如下:

https://www.bilibili.com/video/BV1X84y1v7u9/?vd_source=2bbde87de845d5220b1d8ba075c12fb0

  • 19
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: yc1021是一款蓝牙芯片开发,它可以用于开发蓝牙相关的应用和产品。蓝牙技术是一种无线通信技术,能够实现不同设备之间的数据传输和通信。yc1021芯片提供了丰富的硬件和软件功能,使得开发蓝牙应用变得更加简便和高效。 yc1021芯片具备先进的蓝牙功能,支持各种蓝牙协议和配置。可以通过yc1021芯片开发开发人员可以轻松地实现蓝牙设备的连接、数据传输、音频播放等功能。同时,yc1021芯片还具备低功耗特性,能够为蓝牙设备提供良好的电池续航性能。 yc1021芯片开发包含了完整的开发环境和工具,开发人员可以使用这些工具进行蓝牙应用开发和测试。yc1021开发还支持多种接口和传感器,可以与其他硬件设备进行连接和交互。开发人员可以根据自己的需求,灵活地设计和实现各种应用场景。 总之,yc1021蓝牙芯片开发是一款功能强大、易于使用的开发工具,适用于各种蓝牙应用的开发和调试。它提供了丰富的功能和接口,方便开发人员进行蓝牙相关产品的开发。如果您对蓝牙技术感兴趣,可以考虑选择yc1021芯片开发进行开发工作。 ### 回答2: yc1021是一种蓝牙芯片,主要用于开发各种蓝牙应用。该芯片具有较小的尺寸和低功耗的特点,适用于各种蓝牙设备,例如智能手表、智能家居、蓝牙音箱等。 使用yc1021芯片进行蓝牙开发具有许多优势。首先,它具有稳定可靠的蓝牙连接性能,能够快速连接并保持稳定的数据传输。其次,该芯片支持低功耗蓝牙技术,能够有效节省设备电量,延长续航时间。此外,yc1021还具备较高的数据传输速率,能够实现快速且稳定的数据交互。 在yc1021蓝牙芯片开发过程中,需要进行一些基本步骤。首先,需要了解该芯片的规格和功能,以便正确使用。接下来,可以使用开发开发工具进行测试和调试。编写应用程序时,需要使用适当的编程语言和开发工具,例如C语言或Java,并根据需求进行相应的功能开发,例如传输数据、收发文件、控制外部设备等。 在yc1021芯片开发过程中,需要注意一些问题。首先,要确保代码质量,避免出现bug和逻辑错误。其次,要注意数据安全性,采取相应的安全措施,以防止数据泄露或攻击。此外,还应遵守相关的法律法规,确保产品的合法性和合规性。 综上所述,yc1021蓝牙芯片开发是一种有着广泛应用前景的技术。通过掌握该芯片的规格和功能,并正确使用开发工具和编程语言,可以实现各种蓝牙应用的开发。在开发过程中,需要注意代码质量、数据安全性和合规性等问题,以确保产品的稳定性和安全性。 ### 回答3: YC1021是一款基于蓝牙技术的芯片,主要用于开发和制造蓝牙设备。蓝牙技术是一种无线通信技术,能够在短距离范围内实现设备之间的数据传输和通信。YC1021芯片具有高度集成、低功耗、稳定可靠等特点,适用于各种蓝牙设备应用,如智能家居、智能穿戴、智能健康等。 YC1021蓝牙芯片开发具有以下几个方面的优势和特点。首先,这款芯片支持最新的蓝牙协议标准,能够兼容各种蓝牙设备和平台。其次,该芯片采用了先进的射频芯片设计和制造工艺,能够提供稳定的信号传输和连接性能。同时,该芯片在功耗管理方面也有突出表现,可延长设备的电池寿命,提供更持久的使用体验。 在开发过程中,YC1021蓝牙芯片提供了全面的软硬件开发工具,方便开发者进行应用程序的编写和调试。此外,该芯片还提供了丰富的接口和功能,包括GPIO、UART、SPI等,支持外设的接入和交互,从而满足不同设备的需求。 另外,YC1021蓝牙芯片开发还具有良好的市场前景和商业价值。随着智能设备市场的快速发展,对于蓝牙技术的需求也越来越大。通过使用该芯片进行产品开发,可以帮助厂商快速推出高品质和高性能的蓝牙设备,满足消费者对于智能化产品的需求。 总之,YC1021蓝牙芯片开发是一项具备先进技术和广阔市场前景的工作。通过充分利用该芯片的优势和特点,开发者能够打造出多样化的蓝牙设备,并在竞争激烈的市场中获得成功。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值