【联盛德W806上手笔记】九、DMA

Windows 10 20H2
HLK-W806-V1.0-KIT
WM_SDK_W806_v0.6.0


       摘自《W806 MCU 芯片规格书 V2.0》、《WM_W800_寄存器手册 V2.1》

DMA 控制器

       最多支持 8 通道,16 个 DMA 请求源,支持链表结构与寄存器控制。

Amba2.0 标准总线接口,8 路 DMA 通道
支持基于存储器链表结构的 DMA 操作
软件配置 16 个硬件请求源
支持 1,4-burst 操作模式
支持 byte、half-word,word 操作
源、目的地址不变或顺序递增可配置或在预定义地址范围内循环操作
同步 DMA 请求和 DMA 响应硬件接口时序

功能概述

       DMA 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源,不影响 CPU 进行其他指令的操作。
       DMA 挂载在 AHB 总线上,最多支持 8 通道,16 个硬件外设请求源,支持链表结构与寄存器控制。

功能描述

DMA 通道

       W800 共支持 8 路 DMA 通道,DMA 通道互相不干涉,可以同时运行。请求不同的数据流可以选择不同的 DMA 通道。
       每个 DMA 通道分配在不同的寄存器地址偏移段,可以直接选择相应通道的地址段进行配置使用即可。不同通道的寄存器配置方式完全一致。
在这里插入图片描述

DMA 数据流

       8 路 DMA 通道能够实现源和目的之间单向数据传输链路。
       DMA 的源和目的地址可以设置为每次 DMA 操作完成之后不变、递增或循环三种模式:

DMA_CTRL[2:1]控制源地址每次 DMA 操作后变化方式;
DMA_CTRL[4:3]控制目的地址每次 DMA 操作后变化方式。

       DMA 可以设置 byte、half-word、word 的搬运单位,最终搬运数据的数量是搬运单位的整数倍,通过DMA_CTRL[6:5]来设置。
       DMA 可以通过 burst 设置每次搬运多少个单位的数据,通过 DMA_CTRL[7]来选择一次搬运 1 或 4 个单位的数据,如果 DMA_CTRL[6:5]设置为 word,burst 设置为 4,则每次搬运 4 个 word 的数据。
       DMA 可以设置每次启动 DMA 传输的 Byte 个数,最大 65535 Byte,通过 DMA_CTRL[23:8]来设置。

DMA 循环模式

       DMA 循环地址模式是指设置 DMA 的源和目的地址之后,数据搬运达到设定的循环边界之后,会跳转到循环起始地址,如此循环执行,直到到达设定的传输字节。
       循环地址模式的源和目的地址需要用 SRC_WRAP_ADDR 和 DEST_WRAP_ADDR 寄存器来设定,并通过WRAP_SIZE 来设定循环的长度值。

DMA 传输模式

DMA 支持 3 种传输模式:
内存到内存
       源地址和目的地址均配置成需要传输的内存地址,DMA_MODE[0]设置为 0,软件方式。
内存到外设
       源地址设置为内存地址,目的地址设置成外设地址,DMA_MODE[0]设置为 1,硬件方式,
DMA_MODE[5:2]选择所使用的外设。
外设到内存
       源地址设置为外设地址,目的地址设置成内存地址,DMA_MODE[0]设置为 1,硬件方式,DMA_MODE[5:2]选择所使用的外设。

DMA 外设选择

       当使用外设到内存或者内存到外设这种传输方式的时候,除了相应的外设需要设置为 DMA TX 或 RX 外,DMA_MODE[5:2]也需要选择对应的外设。
       注意:因为 UART 口共有 3 个,在 UART 使用 DMA 的时候,还需要通过 UART_CH[1:0]来选择对应的UART。

DMA 链表模式

       DMA 支持链表工作模式。 通过链表模式,我们在 DMA 搬运当前链表内存数据的时候,可以提前向下一个链表中填充数据,DMA 搬完当前链表之后,判断到下一个链表有效,可以直接搬运下一个链表的数据。通过链表的方式可以有效的提高 DMA 和 CPU 配合的效率。
       链表操作方式:通过 DMA_MODE[1]寄存器设置 DMA 为链表工作方式,再将 DESC_ADDR 寄存器设置为链表结构的起始地址,然后再通过 CHNL_CTRL 寄存器使能 DMA。当 DMA 处理完成当前内存的搬移后,软件通过设置有效标志,通知 DMA 链表中依然存在有效的数据,DMA 依据链表的有效标志处理下一个待搬移数据。

DMA 中断

       DMA 传输完成或者 burst 均可以产生中断,INT_MASK 寄存器可以屏蔽 DMA 通道对应的中断。当 DMA 相应中断产生后,可以通过 INT_SRC 寄存器查询当前中断的状态,指示当前是什么产生的中断,相应的状态位需要软件写 1 清 0。

中断请求

值得注意的是,SPI的DMA是LSPI的:
在这里插入图片描述

库函数

打开wm_dma.h,有如下内容:

函数

HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma);
HAL_StatusTypeDef HAL_DMA_DeInit (DMA_HandleTypeDef *hdma);
HAL_StatusTypeDef HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint16_t DataLength);
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint16_t DataLength);
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma);
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma);
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout);
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma);

HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma);
uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma);

参数

结构体和枚举类型

typedef enum
{
	HAL_DMA_STATE_RESET		= 0x00U,
	HAL_DMA_STATE_READY		= 0x01U,
	HAL_DMA_STATE_BUSY		= 0x02U,
	HAL_DMA_STATE_TIMEOUT	= 0x03U
}HAL_DMA_StateTypeDef;

typedef struct
{
	uint32_t Direction;				/* 	Specifies if the data will be transferred from memory to peripheral,
										from peripheral to memory or from memmory to memory.
										This parameter can be a value of @ref DMA_DATA_TRANSFER_DIRECTION*/
	
	uint32_t DestInc;				/*  Specifies weather the destination address should be incremented or not.
	  									When mode is DMA_MODE_NORMAL_CIRCULAR and destination address need increment,
										must choose DMA_DINC_CIRCULAR.
	  									This parameter can be a value of @ref DMA_DEST_ADDR_INCREMENT*/
	
	uint32_t SrcInc;				/* 	Specifies weather the source address should be incremented or not.
	  									When mode is DMA_MODE_NORMAL_CIRCULAR and Source address need increment,
										must choose DMA_SINC_CIRCULAR.
	  									This parameter can be a value of @ref DMA_SRC_ADDR_INCREMENT*/
	
	uint32_t DataAlignment;			/*  Specifies the transport unit.
	  									This parameter can be a value of @ref DMA_DATAALIGN*/
	
	uint32_t Mode;					/*  Specifies the operation mode of the DMA channelx. When you need to 
	  									use half-complete interrupts, you must use link mode.
	  									This parameter can be a value of @ref DMA_MODE*/
	
	uint32_t RequestSourceSel;		/*  Specifies the request source of DMA.
										This parameter can be a value of @ref DMA_REQUEST_SOURCE*/

    uint32_t RequestUartSel;		/*  Specifies the UART number when the RequestSourceSel is DMA_REQUEST_SOURCE_UART_RX
									    or DMA_REQUEST_SOURCE_UART_TX. This parameter can be a value of @ref DMA_UART_CHANNEL_SEL*/
										
} DMA_InitTypeDef;

/* The descriptor structure is used internally by the driver layer,
   and the user layer does not need to be assigned. */
typedef struct __DMA_LinkDescriptor
{
	uint32_t Valid;					/*  According to the Bit31 to indicate whether the data pointed to by the 
										descriptor is valid. Bit31 equal to 1 means valid, equal to 0 means invalid */
	
	uint32_t Control;				/*  Equal to the value of register CR2[23:1] */
	
	uint32_t SrcAddr;				/*  Data source address */
	
	uint32_t DestAddr;				/*  Data destinathion address */
	
	struct __DMA_LinkDescriptor *Next;	/*	Point to the address of the next descriptor structure */
	
} DMA_LinkDescriptor;

typedef enum
{
	HAL_DMA_HALF_TRANSFER = 0,
	HAL_DMA_FULL_TRANSFER = 1
} HAL_DMA_LevelCompleteTypeDef;

typedef struct __DMA_HandleTypeDef
{
	DMA_Channel_TypeDef		*Instance;		/* Register base address of the channel used. 
											   Need user layer assignment.*/
	
	DMA_InitTypeDef			Init;			/* DMA communication parameters. Need user layer assignment*/
	
	HAL_LockTypeDef			Lock;			/* DMA locking object. */
	
	HAL_DMA_StateTypeDef	State;			/* DMA transfer state. */
	
	void					*Parent;		/* Parent object state. Need user layer assignment*/
	
	void					(* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /* DMA transfer complete callback. */
  
	void					(* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma);	/* DMA Half transfer complete callback. */
	
	void					(* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma);	/* DMA transfer abort callback. */
	
	DMA_TypeDef				*DmaBaseAddress;	/* DMA register base address. */
	
	uint32_t				ChannelIndex;		/* DMA Channel Index. */
	
	__IO uint32_t			ErrorCode;			/* DMA error code. */
	
	DMA_LinkDescriptor		*LinkDesc;			/* Points to the descriptor address. When user need to use the 
												   DMA half-completed interrupt, assign a value in the user layer.
												   E.g DMA_LinkDescriptor desc[2], Size must be 2. */
	
	uint32_t				offset;				/* For internal use, the user does not need to assign a value. */
	
} DMA_HandleTypeDef;

宏参数

// DMA register base address and channel base address.
#define DMA					((DMA_TypeDef *)DMA_BASE)
#define DMA_Channel0		((DMA_Channel_TypeDef *)DMA_Channel0_BASE)
#define DMA_Channel1		((DMA_Channel_TypeDef *)DMA_Channel1_BASE)
#define DMA_Channel2		((DMA_Channel_TypeDef *)DMA_Channel2_BASE)
#define DMA_Channel3		((DMA_Channel_TypeDef *)DMA_Channel3_BASE)
#define DMA_Channel4		((DMA_Channel_TypeDef *)DMA_Channel4_BASE)
#define DMA_Channel5		((DMA_Channel_TypeDef *)DMA_Channel5_BASE)
#define DMA_Channel6		((DMA_Channel_TypeDef *)DMA_Channel6_BASE)
#define DMA_Channel7		((DMA_Channel_TypeDef *)DMA_Channel7_BASE)

// DMA Error Code
#define HAL_DMA_ERROR_NONE			0x0U	// No error
#define HAL_DMA_ERROR_NO_XFER		0x1U	// no ongoing transfer
#define HAL_DMA_ERROR_TIMEOUT		0x2U	// Timout error
#define HAL_DMA_ERROR_NOT_SUPPORTED	0x4U	// Not supported mode

// DMA_DATA_TRANSFER_DIRECTION
#define DMA_PERIPH_TO_MEMORY		((uint32_t)DMA_MODE_SHM)	// Peripheral to memory direction
#define DMA_MEMORY_TO_PERIPH		((uint32_t)DMA_MODE_SHM)	// Memory to peripheral direction
#define DMA_MEMORY_TO_MEMORY		0x00000000U					// Memory to memory direction

// DMA_DEST_ADDR_INCREMENT
#define DMA_DINC_ENABLE				((uint32_t)DMA_CR2_DINC_ENABLE)		// Destination address increment mode Enable
#define DMA_DINC_DISABLE			((uint32_t)DMA_CR2_DINC_DISABLE)	// Destination address increment mode Disable
#define DMA_DINC_CIRCULAR			((uint32_t)DMA_CR2_DINC_CYCLE)		// Destination address circular mode. Only when Mode = DMA_MODE_NORMAL_CIRCULAR

// DMA_SRC_ADDR_INCREMENT
#define DMA_SINC_ENABLE				((uint32_t)DMA_CR2_SINC_ENABLE)		// Source address increment mode Enable
#define DMA_SINC_DISABLE			((uint32_t)DMA_CR2_SINC_DISABLE)	// Source address increment mode Disable
#define DMA_SINC_CIRCULAR			((uint32_t)DMA_CR2_SINC_CYCLE)		// Source address circular mode. Only when Mode = DMA_MODE_NORMAL_CIRCULAR

// DMA_DATAALIGN
#define DMA_DATAALIGN_BYTE			((uint32_t)DMA_CR2_TRANS_SIZE_BYTE)			// Memory data alignment: Byte
#define DMA_DATAALIGN_HALFWORD		((uint32_t)DMA_CR2_TRANS_SIZE_HALFWORD)		// Memory data alignment: HalfWord
#define DMA_DATAALIGN_WORD			((uint32_t)DMA_CR2_TRANS_SIZE_WORD)			// Memory data alignment: Word

// DMA_MODE
#define DMA_MODE_NORMAL_SINGLE				0x00000000U				// Normal single mode
#define DMA_MODE_NORMAL_CIRCULAR			0x00000001U				// Normal circular mode
#define DMA_MODE_LINK_SINGLE				0x00000002U				// Link	singal mode
#define DMA_MODE_LINK_CIRCULAR				0x00000003U				// Link circular mode

// DMA_INTERRUPT_TYPE
#define DMA_FLAG_TF_DONE			DMA_IF_TRANSFER_DONE			// Transfer complete interrupt
#define DMA_FLAG_BURST_DONE			DMA_IF_BURST_DONE				// Burst complete interrupt

// DMA_REQUEST_SOURCE
#define DMA_REQUEST_SOURCE_UART_RX		DMA_MODE_CH_UART_RX
#define DMA_REQUEST_SOURCE_UART_TX		DMA_MODE_CH_UART_TX
#define DMA_REQUEST_SOURCE_PWM_CAP0		DMA_MODE_CH_PWM_CAP0
#define DMA_REQUEST_SOURCE_PWM_CAP1		DMA_MODE_CH_PWM_CAP1
#define DMA_REQUEST_SOURCE_SPI_RX		DMA_MODE_CH_LSPI_RX
#define DMA_REQUEST_SOURCE_SPI_TX		DMA_MODE_CH_LSPI_TX
#define DMA_REQUEST_SOURCE_ADC_CH0		DMA_MODE_CH_ADC0
#define DMA_REQUEST_SOURCE_ADC_CH1		DMA_MODE_CH_ADC1
#define DMA_REQUEST_SOURCE_ADC_CH2		DMA_MODE_CH_ADC2
#define DMA_REQUEST_SOURCE_ADC_CH3		DMA_MODE_CH_ADC3
#define DMA_REQUEST_SOURCE_I2S_RX		DMA_MODE_CH_I2SRX
#define DMA_REQUEST_SOURCE_I2S_TX		DMA_MODE_CH_I2STX
#define DMA_REQUEST_SOURCE_SDIO			DMA_MODE_CH_SDIO

// DMA_UART_CHANNEL_SEL
#define DMA_UART_CHANNEL_SEL_UART0		DMA_REQCH_UART0
#define DMA_UART_CHANNEL_SEL_UART1		DMA_REQCH_UART1
#define DMA_UART_CHANNEL_SEL_UART2		DMA_REQCH_UART2
#define DMA_UART_CHANNEL_SEL_UART3		DMA_REQCH_UART3
#define DMA_UART_CHANNEL_SEL_UART4		DMA_REQCH_UART4
#define DMA_UART_CHANNEL_SEL_UART5		DMA_REQCH_UART5

#define IS_DMA_ALL_INSTANCE(INSTANCE)	(((INSTANCE) == DMA_Channel0) || \
										 ((INSTANCE) == DMA_Channel1) || \
										 ((INSTANCE) == DMA_Channel2) || \
										 ((INSTANCE) == DMA_Channel3) || \
										 ((INSTANCE) == DMA_Channel4) || \
										 ((INSTANCE) == DMA_Channel5) || \
										 ((INSTANCE) == DMA_Channel6) || \
										 ((INSTANCE) == DMA_Channel7))

#define IS_DMA_DIRECTION(DIRECTION)		(((DIRECTION) == DMA_PERIPH_TO_MEMORY) || \
										 ((DIRECTION) == DMA_MEMORY_TO_PERIPH) || \
										 ((DIRECTION) == DMA_MEMORY_TO_MEMORY))
										 
#define IS_DMA_DEST_INC_STATE(STATE)	(((STATE) == DMA_DINC_ENABLE) || \
											 ((STATE) == DMA_DINC_DISABLE))
											 
#define IS_DMA_SRC_INC_STATE(STATE)		(((STATE) == DMA_SINC_ENABLE) || \
											 ((STATE) == DMA_SINC_DISABLE))
											 
#define IS_DMA_DATA_SIZE(SIZE)			(((SIZE) == DMA_DATAALIGN_BYTE) || \
										 ((SIZE) == DMA_DATAALIGN_HALFWORD) || \
										 ((SIZE) == DMA_DATAALIGN_WORD))

#define IS_DMA_MODE(MODE)				(((MODE) == DMA_MODE_NORMAL_SINGLE) || \
										 ((MODE) == DMA_MODE_NORMAL_CIRCULAR) || \
										 ((MODE) == DMA_MODE_LINK_SINGLE) || \
										 ((MODE) == DMA_MODE_LINK_CIRCULAR))
										 
#define IS_DMA_REQUEST_SOURCE(SEL)		(((SEL) == DMA_REQUEST_SOURCE_UART_RX) || \
										 ((SEL) == DMA_REQUEST_SOURCE_UART_TX) || \
										 ((SEL) == DMA_REQUEST_SOURCE_PWM_CAP0) || \
										 ((SEL) == DMA_REQUEST_SOURCE_PWM_CAP1) || \
										 ((SEL) == DMA_REQUEST_SOURCE_SPI_RX) || \
										 ((SEL) == DMA_REQUEST_SOURCE_SPI_TX) || \
										 ((SEL) == DMA_REQUEST_SOURCE_ADC_CH0) || \
										 ((SEL) == DMA_REQUEST_SOURCE_ADC_CH1) || \
										 ((SEL) == DMA_REQUEST_SOURCE_ADC_CH2) || \
										 ((SEL) == DMA_REQUEST_SOURCE_ADC_CH3) || \
										 ((SEL) == DMA_REQUEST_SOURCE_I2S_RX) || \
										 ((SEL) == DMA_REQUEST_SOURCE_I2S_TX) || \
										 ((SEL) == DMA_REQUEST_SOURCE_SDIO))
										 
#define IS_DMA_UART_CHANNEL(CHANNEL)	(((CHANNEL) == DMA_UART_CHANNEL_SEL_UART0) || \
										 ((CHANNEL) == DMA_UART_CHANNEL_SEL_UART1) || \
										 ((CHANNEL) == DMA_UART_CHANNEL_SEL_UART2) || \
										 ((CHANNEL) == DMA_UART_CHANNEL_SEL_UART3) || \
										 ((CHANNEL) == DMA_UART_CHANNEL_SEL_UART4) || \
										 ((CHANNEL) == DMA_UART_CHANNEL_SEL_UART5))	

#define IS_DMA_BUFFER_SIZE(SIZE)		(((SIZE) >= 0x1U) && ((SIZE) < 0x10000U))

#define IS_DMA_SRC_ADDR(SRC)			(((SRC) % 4) == 0)

#define IS_DMA_DEST_ADDR(DEST)			(((DEST) % 4) == 0)

#define IS_DMA_LENGTH(DATAALIGN, LEN)	((((DATAALIGN) == DMA_DATAALIGN_BYTE) && (((LEN) % 1) == 0)) || \
										 (((DATAALIGN) == DMA_DATAALIGN_HALFWORD) && (((LEN) % 2) == 0)) || \
										 (((DATAALIGN) == DMA_DATAALIGN_WORD) && (((LEN) % 4) == 0)))

#define IS_DMA_LINK_LENGTH(LEN)			(((LINK) % 8) == 0)

#define IS_DMA_COMPLETELEVEL(LEVEL)		(((LEVEL) == HAL_DMA_HALF_TRANSFER) || ((LEVEL) = HAL_DMA_FULL_TRANSFER))

#define __HAL_DMA_ENABLE(__HANDLE__)	(SET_BIT((__HANDLE__)->Instance->CR1, DMA_CR1_START))

#define __HAL_DMA_DISABLE(__HANDLE__)	do {													 \
											SET_BIT((__HANDLE__)->Instance->CR1, DMA_CR1_STOP);  \
											while ((__HANDLE__)->Instance->CR1 & DMA_CR1_START); \
										} while (0)

#define __HAL_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__)	(CLEAR_BIT((__HANDLE__)->DmaBaseAddress->IM, (__INTERRUPT__)))

#define __HAL_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__)	(SET_BIT((__HANDLE__)->DmaBaseAddress->IM, (__INTERRUPT__)))

#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__)	(((__HANDLE__)->DmaBaseAddress->IF) & (__FLAG__))

#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__)	(SET_BIT((__HANDLE__)->DmaBaseAddress->IF, (__FLAG__)))

应用

在WM_SDK_W806_v0.6.0中,仅有SPI和I2S有具体的DMA实现:
在这里插入图片描述
SPI的应用见【联盛德W806上手笔记】八、SPI及其DMA

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: w806是一款(Lichee)公司生产的开发板,支持Micropython编程语言。Micropython是一种基于Python的嵌入式系统开发语言,可以在微控制器上运行Python程序。使用Micropython可以方便地开发嵌入式系统,实现各种功能。的w806开发板支持多种外设,如WIFI、蓝牙、摄像头等,可以满足各种应用需求。 ### 回答2: W806是(LELSD)出品的一款基于MicroPython的开发板,它拥有低功耗、高效、易用等特点,适用于物网、AR/VR、智能家居等领域的开发使用。W806的芯片采用的是飞思卡尔(Freescale)的Kinetis K66F,它的主频高达180MHz,拥有256KB的RAM和1MB的Flash,支持LwIP、SSL/TLS等多种协议。W806还配备了丰富的接口,例如可以通过WIFI、蓝牙、Zigbee等多种协议进行连接,还拥有USB和JTAG等调试接口,为开发人员提供了更加便捷的开发环境。 除了硬件控制,w806还支持各种高级语言编程,其中就包括了Micropython,这是一种非常便捷的语言,它已经成为了物网领域的一种核心语言。利用Micropython可以直接在W806上进行代码编写和调试,并且可以利用其强大的历史数据存储和展示能力来进行数据分析和处理。通过Micropython,w806 可以接收和发送数据,进行大量的实时数据分析和控制,大大提高了物网应用的可靠性和效率。 总之,W806Micropython这个组合非常适合开发物网系统和智能家居等智能设备,它让开发人员可以通过Micropython的编程语言进行开发,支持多种协议,拥有丰富的硬件控制接口,可以快速地进行产品原型测试,最终实现智能化的物网设备。 ### 回答3: W806是一款支持MicroPython编程语言的智能小车。它的流线型设计和高性能的电机使得它在运动中非常稳定,能够在各种复杂地形下行走。 W806的核心是一块STM32F407VET6单片机,它拥有240MHz的主频以及512KB的Flash存储和192KB的SRAM。这使得W806能够流畅地运行MicroPython脚本,同时还可以轻松处理传感器数据和控制命令。此外,W806还配备了多个传感器模块,包括超声波模块、红外线循迹模块和心率传感器模块等,可以满足不同的应用需求。 的W806还支持WiFi和蓝牙通信,可以通过手机APP或者PC控制,并支持远程控制和远程更新程序。这也让W806在科研、教育、开发等领域得到广泛的应用。 总之,W806是一款功能丰富、扩展性高的智能小车,既适用于初学者快速上手,也适用于高级开发人员进行二次开发。作为一款支持MicroPython编程语言的智能小车,W806将成为未来机器人领域的重要一员,为智能生活和人工智能的发展做出重要贡献。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乙酸氧铍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值