首页 > 其他分享 >IMX6ULL SPI应用-6轴陀螺仪加速度传感器ICM-20608-G

IMX6ULL SPI应用-6轴陀螺仪加速度传感器ICM-20608-G

时间:2023-10-23 22:13:04浏览次数:34  
标签:ICM20 ICM 陀螺仪 20608 SPI 寄存器 icm20608 reg define

1 6轴陀螺仪加速度传感器ICM-20608-G

1.1 概述

The ICM-20608-G is a 6-axis MotionTracking device that combines a 3-axis gyroscope, and a 3-axis accelerometer in a small 3x3x0.75mm (16-pin LGA) package.
The gyroscope has a programmable full-scale range of ±250, ±500, ±1000, and ±2000 degrees/sec. The accelerometer has a user programmable accelerometer full-scale range of ±2g, ±4g, ±8g, and ±16g.
Other industry-leading features include on-chip 16-bit ADCs, programmable digital filters, an embedded temperature sensor, and programmable interrupts. The device features I2 C and SPI serial interfaces, a VDD operating range of 1.71 to 3.45V, and a separate digital IO supply, VDDIO from 1.71V to 3.45V. Communication with all registers of the device is performed using either I2 C at 400kHz or SPI at 8MHz.
1.包含3轴陀螺仪数据和3轴加速度数据。
2.陀螺仪和加速度量程可设定,陀螺仪量程可设定位+-250,+-500,+-1000, +-2000角度每秒。加速度同理也可设定量程。
3.精度为16bit ADC转换。
4.使用I2C/SPI接口通信,I2C速率高达400KHz, SPI高达8MHz。

1.2 应用场景

image

1.3 陀螺仪和加速度特性

image

1.4 电器特性

image
image
可以看到FS_SEL,AFS_SEL用来选择陀螺仪和加速度计的量程。举个例子,当角速度量程为+-250时,那么ADC的数据为多少表示为1度呢?已知ADC精度16bit, 数据范围[0,65535], 假如ADC的数据为x, 那么x/65636 = 1/500,算出x= 131.272x,对应表格数据中的131。加速度的换算公式也是同理, 当AFS_SEL=0时,x/65536 = 1/4, x=16384。

1.5 交流电器特性

image
当用i2c通信,AD0引脚决定i2c从地址是0x68还是0x69。可以看到power-on reset上电时序,需要Valid power-on RESET时间最少0.01ms, 从启动到寄存器读写等11ms。

1.6 工作模式

image

1.7 SPI方式寄存器访问

image
数据上升沿锁存,下降沿数据发生改变。最大高达8MHz时钟,一次读写需要16个或者更多时钟周期,第一个字节传输寄存器地址,第二个字节传输数据。首字节的首位表示是读还是写。

#define ICM20608_CSN(n)    (n ? gpio_pinwrite(GPIO1, 20, 1) : gpio_pinwrite(GPIO1, 20, 0))   /* SPI片选信号	 */
/*
 * @description  : 写ICM20608指定寄存器
 * @param - reg  : 要读取的寄存器地址
 * @param - value: 要写入的值
 * @return		 : 无
 */
void icm20608_write_reg(unsigned char reg, unsigned char value)
{
	/* ICM20608在使用SPI接口的时候寄存器地址
	 * 只有低7位有效,寄存器地址最高位是读/写标志位
	 * 读的时候要为1,写的时候要为0。
	 */
	reg &= ~0X80;	

	ICM20608_CSN(0);						/* 使能SPI传输			*/
	spich0_readwrite_byte(ECSPI3, reg); 	/* 发送寄存器地址		*/ 
	spich0_readwrite_byte(ECSPI3, value);	/* 发送要写入的值			*/
	ICM20608_CSN(1);						/* 禁止SPI传输			*/
}	
/*
 * @description	: 读取ICM20608寄存器值
 * @param - reg	: 要读取的寄存器地址
 * @return 		: 读取到的寄存器值
 */
unsigned char icm20608_read_reg(unsigned char reg)
{
	unsigned char reg_val;	   	

	/* ICM20608在使用SPI接口的时候寄存器地址
	 * 只有低7位有效,寄存器地址最高位是读/写标志位
	 * 读的时候要为1,写的时候要为0。
	 */
	reg |= 0x80; 	

	ICM20608_CSN(0);               					/* 使能SPI传输	 		*/
	spich0_readwrite_byte(ECSPI3, reg);     		/* 发送寄存器地址  		*/ 
	reg_val = spich0_readwrite_byte(ECSPI3, 0XFF);	/* 读取寄存器的值 			*/
	ICM20608_CSN(1);                				/* 禁止SPI传输 			*/
	return(reg_val);               	 				/* 返回读取到的寄存器值 */
}

2 ICM-20608-G寄存器描述

image
ICM-20608-G寄存器的地址和数据都是单字节。

2.1 控制寄存器

控制配置寄存器0x1a,0x1b,0x1c,0x1d,设置量程等配置。
image
0x19设置分频,不分频,配成0
image
0x1a设置陀螺仪低通滤波带宽BW=20Hz,配成0x4.
image
0x1b设置gyro量程,配成最大0x18.
image
0x1c设置加速度计的量程,也配成最大0x18.
image
0x1d设置加速度计低通滤波BW=21.2Hz
image
0x1e设置low power,配成0,关闭低功耗.
image
0x23设置fifo功能,这里配置0x0,禁用fifo.

设定量程,配置相关参数:

#define	ICM20_SMPLRT_DIV			0x19
#define	ICM20_CONFIG				0x1A
#define	ICM20_GYRO_CONFIG			0x1B
#define	ICM20_ACCEL_CONFIG			0x1C
#define	ICM20_ACCEL_CONFIG2			0x1D
#define	ICM20_LP_MODE_CFG			0x1E
#define	ICM20_FIFO_EN				0x23
icm20608_write_reg(ICM20_SMPLRT_DIV, 0x00); 	/* 输出速率是内部采样率					*/
icm20608_write_reg(ICM20_GYRO_CONFIG, 0x18); 	/* 陀螺仪±2000dps量程 				*/
icm20608_write_reg(ICM20_ACCEL_CONFIG, 0x18); 	/* 加速度计±16G量程 					*/
icm20608_write_reg(ICM20_CONFIG, 0x04); 		/* 陀螺仪低通滤波BW=20Hz 				*/
icm20608_write_reg(ICM20_ACCEL_CONFIG2, 0x04); 	/* 加速度计低通滤波BW=21.2Hz 			*/
icm20608_write_reg(ICM20_PWR_MGMT_2, 0x00); 	/* 打开加速度计和陀螺仪所有轴 				*/
icm20608_write_reg(ICM20_LP_MODE_CFG, 0x00); 	/* 关闭低功耗 						*/
icm20608_write_reg(ICM20_FIFO_EN, 0x00);		/* 关闭FIFO						*/

2.2 数据寄存器

数据寄存器0x3b~0x48表示加速度和陀螺仪数据,可以看到该传感器的寄存器地址都是单字节,ADC精度16bit,因此需要2个寄存器来表示一个轴的坐标数据。
image
0x3b-0x40表示加速度计3轴数据。
image
0x42 温度数据
image
image
0x43~0x48陀螺仪3轴数据。

2.3 WHO_AM_I

image
寄存器表示设备ID,默认0xAF.

2.4 PWR_MGMT_1/PWR_MGMT_2

电源管理模式寄存器
image
可以看到bit6默认是一个sleep mode, bit7是复位信号,复位后,默认bit6会变成1,进入睡眠模式。Bit4 陀螺仪待机,bit3关闭温度传感器等等都不要开启,设置成0,bit[2:0]时钟选择自动。
image
可以看到设置成0,6轴数据全使能

复位初始化:

#define	ICM20_PWR_MGMT_1			0x6B
#define	ICM20_WHO_AM_I 				0x75
icm20608_write_reg(ICM20_PWR_MGMT_1, 0x80);		/* 复位,复位后为0x40,睡眠模式 			*/
delayms(50);
icm20608_write_reg(ICM20_PWR_MGMT_1, 0x01);		/* 关闭睡眠,自动选择时钟 					*/
delayms(50);
regvalue = icm20608_read_reg(ICM20_WHO_AM_I);
printf("icm20608 id = %#X\r\n", regvalue);

3 代码解析

icm20608.h
/* ICM20608寄存器 
 *复位后所有寄存器地址都为0,除了
 *Register 107(0X6B) Power Management 1 	= 0x40
 *Register 117(0X75) WHO_AM_I 				= 0xAF或0xAE
 */
/* 陀螺仪和加速度自测(出产时设置,用于与用户的自检输出值比较) */
#define	ICM20_SELF_TEST_X_GYRO		0x00
#define	ICM20_SELF_TEST_Y_GYRO		0x01
#define	ICM20_SELF_TEST_Z_GYRO		0x02
#define	ICM20_SELF_TEST_X_ACCEL		0x0D
#define	ICM20_SELF_TEST_Y_ACCEL		0x0E
#define	ICM20_SELF_TEST_Z_ACCEL		0x0F

/* 陀螺仪静态偏移 */
#define	ICM20_XG_OFFS_USRH			0x13
#define	ICM20_XG_OFFS_USRL			0x14
#define	ICM20_YG_OFFS_USRH			0x15
#define	ICM20_YG_OFFS_USRL			0x16
#define	ICM20_ZG_OFFS_USRH			0x17
#define	ICM20_ZG_OFFS_USRL			0x18

#define	ICM20_SMPLRT_DIV			0x19
#define	ICM20_CONFIG				0x1A
#define	ICM20_GYRO_CONFIG			0x1B
#define	ICM20_ACCEL_CONFIG			0x1C
#define	ICM20_ACCEL_CONFIG2			0x1D
#define	ICM20_LP_MODE_CFG			0x1E
#define	ICM20_ACCEL_WOM_THR			0x1F
#define	ICM20_FIFO_EN				0x23
#define	ICM20_FSYNC_INT				0x36
#define	ICM20_INT_PIN_CFG			0x37
#define	ICM20_INT_ENABLE			0x38
#define	ICM20_INT_STATUS			0x3A

/* 加速度输出 */
#define	ICM20_ACCEL_XOUT_H			0x3B
#define	ICM20_ACCEL_XOUT_L			0x3C
#define	ICM20_ACCEL_YOUT_H			0x3D
#define	ICM20_ACCEL_YOUT_L			0x3E
#define	ICM20_ACCEL_ZOUT_H			0x3F
#define	ICM20_ACCEL_ZOUT_L			0x40

/* 温度输出 */
#define	ICM20_TEMP_OUT_H			0x41
#define	ICM20_TEMP_OUT_L			0x42

/* 陀螺仪输出 */
#define	ICM20_GYRO_XOUT_H			0x43
#define	ICM20_GYRO_XOUT_L			0x44
#define	ICM20_GYRO_YOUT_H			0x45
#define	ICM20_GYRO_YOUT_L			0x46
#define	ICM20_GYRO_ZOUT_H			0x47
#define	ICM20_GYRO_ZOUT_L			0x48

#define	ICM20_SIGNAL_PATH_RESET		0x68
#define	ICM20_ACCEL_INTEL_CTRL 		0x69
#define	ICM20_USER_CTRL				0x6A
#define	ICM20_PWR_MGMT_1			0x6B
#define	ICM20_PWR_MGMT_2			0x6C
#define	ICM20_FIFO_COUNTH			0x72
#define	ICM20_FIFO_COUNTL			0x73
#define	ICM20_FIFO_R_W				0x74
#define	ICM20_WHO_AM_I 				0x75

/* 加速度静态偏移 */
#define	ICM20_XA_OFFSET_H			0x77
#define	ICM20_XA_OFFSET_L			0x78
#define	ICM20_YA_OFFSET_H			0x7A
#define	ICM20_YA_OFFSET_L			0x7B
#define	ICM20_ZA_OFFSET_H			0x7D
#define	ICM20_ZA_OFFSET_L 			0x7E

/*
 * ICM20608结构体
 */
struct icm20608_dev_struc
{
	signed int gyro_x_adc;		/* 陀螺仪X轴原始值 			*/
	signed int gyro_y_adc;		/* 陀螺仪Y轴原始值 			*/
	signed int gyro_z_adc;		/* 陀螺仪Z轴原始值 			*/
	signed int accel_x_adc;		/* 加速度计X轴原始值 			*/
	signed int accel_y_adc;		/* 加速度计Y轴原始值 			*/
	signed int accel_z_adc;		/* 加速度计Z轴原始值 			*/
	signed int temp_adc;		/* 温度原始值 				*/

	/* 下面是计算得到的实际值,扩大100倍 */
	signed int gyro_x_act;		/* 陀螺仪X轴实际值 			*/
	signed int gyro_y_act;		/* 陀螺仪Y轴实际值 			*/
	signed int gyro_z_act;		/* 陀螺仪Z轴实际值 			*/
	signed int accel_x_act;		/* 加速度计X轴实际值 			*/
	signed int accel_y_act;		/* 加速度计Y轴实际值 			*/
	signed int accel_z_act;		/* 加速度计Z轴实际值 			*/
	signed int temp_act;		/* 温度实际值 				*/
};

struct icm20608_dev_struc icm20608_dev;	/* icm20608设备 */

icm20608.h定义了该模块的6轴数据寄存器地址和值。
连续顺序读写模块:前一个字节得写入寄存器地址,然后每次突发读取1字节数据,注意:这里不用每次都发送寄存器地址,顺序访问时,地址自动增长,即可顺序依次访问寄存器。如:向0x00~0x05地址依次发送6 byte数据,icm20608_read_len(0x00, buf, 6);

void icm20608_read_len(unsigned char reg, unsigned char *buf, unsigned char len)
{  
	unsigned char i;

	/* ICM20608在使用SPI接口的时候寄存器地址,只有低7位有效,
	 * 寄存器地址最高位是读/写标志位读的时候要为1,写的时候要为0。
	 */
	reg |= 0x80; 

	ICM20608_CSN(0);               				/* 使能SPI传输	 		*/
	spich0_readwrite_byte(ECSPI3, reg);			/* 发送寄存器地址  		*/   	   
	for(i = 0; i < len; i++)					/* 顺序读取寄存器的值 			*/
	{
		buf[i] = spich0_readwrite_byte(ECSPI3, 0XFF);	
	}
	ICM20608_CSN(1);                			/* 禁止SPI传输 			*/
}

icm20608_gyro_scaleget()和icm20608_accel_scaleget()是获取陀螺仪和加速度计的最小单位:

float icm20608_gyro_scaleget(void)
{
	unsigned char data;
	float gyroscale;

	data = (icm20608_read_reg(ICM20_GYRO_CONFIG) >> 3) & 0X3;
	switch(data) {
		case 0: 
			gyroscale = 131;
			break;
		case 1:
			gyroscale = 65.5;
			break;
		case 2:
			gyroscale = 32.8;
			break;
		case 3:
			gyroscale = 16.4;
			break;
	}
	return gyroscale;
}

/*
 * @description : 获取加速度计的分辨率
 * @param		: 无
 * @return		: 获取到的分辨率
 */
unsigned short icm20608_accel_scaleget(void)
{
	unsigned char data;
	unsigned short accelscale;

	data = (icm20608_read_reg(ICM20_ACCEL_CONFIG) >> 3) & 0X3;
	switch(data) {
		case 0: 
			accelscale = 16384;
			break;
		case 1:
			accelscale = 8192;
			break;
		case 2:
			accelscale = 4096;
			break;
		case 3:
			accelscale = 2048;
			break;
	}
	return accelscale;
}


/*
 * @description : 读取ICM20608的加速度、陀螺仪和温度原始值
 * @param 		: 无
 * @return		: 无
 */
void icm20608_getdata(void)
{
	float gyroscale;
	unsigned short accescale;
	unsigned char data[14];

	icm20608_read_len(ICM20_ACCEL_XOUT_H, data, 14);

	gyroscale = icm20608_gyro_scaleget();
	accescale = icm20608_accel_scaleget();

	icm20608_dev.accel_x_adc = (signed short)((data[0] << 8) | data[1]);
	icm20608_dev.accel_y_adc = (signed short)((data[2] << 8) | data[3]);
	icm20608_dev.accel_z_adc = (signed short)((data[4] << 8) | data[5]);
	icm20608_dev.temp_adc    = (signed short)((data[6] << 8) | data[7]);
	icm20608_dev.gyro_x_adc  = (signed short)((data[8] << 8) | data[9]);
	icm20608_dev.gyro_y_adc  = (signed short)((data[10] << 8) | data[11]);
	icm20608_dev.gyro_z_adc  = (signed short)((data[12] << 8) | data[13]);

	/* 计算实际值 */
	icm20608_dev.gyro_x_act = ((float)(icm20608_dev.gyro_x_adc)  / gyroscale) * 100;
	icm20608_dev.gyro_y_act = ((float)(icm20608_dev.gyro_y_adc)  / gyroscale) * 100;
	icm20608_dev.gyro_z_act = ((float)(icm20608_dev.gyro_z_adc)  / gyroscale) * 100;

	icm20608_dev.accel_x_act = ((float)(icm20608_dev.accel_x_adc) / accescale) * 100;
	icm20608_dev.accel_y_act = ((float)(icm20608_dev.accel_y_adc) / accescale) * 100;
	icm20608_dev.accel_z_act = ((float)(icm20608_dev.accel_z_adc) / accescale) * 100;

	icm20608_dev.temp_act = (((float)(icm20608_dev.temp_adc) - 25 ) / 326.8 + 25) * 100;
}

由于前面设置的陀螺仪和加速度计量程都是拉满的设置的0x18,因此gyroscale读出来就是对应16.4(最小单位),accescale读出来就是对应2048(最小单位)
然后读出14 byte数据,组装成short类型数据,16位ADC, 一轴数据刚好16位数据。最后转成人眼直观的实际的陀螺仪和加速度计数据,放大了100倍,放大一百倍目的是为了能够将小数的部分也能记录下来。
以陀螺仪为例:量程位+-2000时,换算出16.4为1°。同理以加速度计为例:量程为+-16是,换算出2048为1g。

可以看到用到了浮点运算,那么IMX6ULL属于armv7,支持硬件浮点运算:执行浮点运算前调用imx6ul_hardfpu_enable()函数。

/*
 * @description	: 使能I.MX6U的硬件NEON和FPU
 * @param 		: 无
 * @return 		: 无
 */
 void imx6ul_hardfpu_enable(void)
{
	uint32_t cpacr;
	uint32_t fpexc;

	/* 使能NEON和FPU */
	cpacr = __get_CPACR();
	cpacr = (cpacr & ~(CPACR_ASEDIS_Msk | CPACR_D32DIS_Msk))
		   |  (3UL << CPACR_cp10_Pos) | (3UL << CPACR_cp11_Pos);
	__set_CPACR(cpacr);
	fpexc = __get_FPEXC();
	fpexc |= 0x40000000UL;
	__set_FPEXC(fpexc);
}

打开Cortex-A7 MPCore Technical Reference Manual的4.3.34 Non-Secure Access Control Register介绍:开启硬件NEON和FPU
image
image
打开ARM®Architecture Reference Manual ARMv7-A and ARMv7-R edition介绍FPEXC寄存器, bit30置1,使能浮点运算
image

打开IM6ULL 参考手册:可见IMX6U支持浮点单元:
image
编译选项开启硬件浮点编译:
$(COBJS) : obj/%.o : %.c
$(CC) -Wall -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -Wa,-mimplicit-it=thumb -nostdlib -fno-builtin -c -O2 $(INCLUDE) -o $@ $<

效果:

/*
 * @description	: 指定的位置显示小数数据,比如5123,显示为51.23
 * @param - x	: X轴位置
 * @param - y 	: Y轴位置
 * @param - size: 字体大小
 * @param - num : 要显示的数据,实际小数扩大100倍,
 * @return 		: 无
 */
void decimals_display(unsigned short x, unsigned short y, unsigned char size, signed int num)
{
	signed int integ; 	/* 整数部分 */
	signed int fract;	/* 小数部分 */
	signed int uncomptemp = num; 
	char buf[200];

	if(num < 0)
		uncomptemp = -uncomptemp;
	integ = uncomptemp / 100;
	fract = uncomptemp % 100;

	memset(buf, 0, sizeof(buf));
	if(num < 0)
		sprintf(buf, "-%d.%d", integ, fract);
	else 
		sprintf(buf, "%d.%d", integ, fract);
	lcd_fill(x, y, x + 60, y + size, tftlcd_dev.backcolor);
	lcd_show_string(x, y, 60, size, size, buf); 
}

image
静止时,有一个z方向的加速度2048,也就是1g,刚好时重力加速度。静止时,陀螺仪几乎没有角速度,因此3轴数据都几乎为0°。

image
左右晃动时,陀螺仪数据明显增加。

标签:ICM20,ICM,陀螺仪,20608,SPI,寄存器,icm20608,reg,define
From: https://www.cnblogs.com/fuzidage/p/17780817.html

相关文章

  • IMX6ULL SPI控制器
    1IMX6ULLSPI控制器NXP的6ull参考手册第Chapter20介绍了SPI控制器,EnhancedConfigurableSPI(ECSPI)。1.1特点①、全双工同步串行接口。②、可配置的主/从模式。③、四个硬件片选信号,支持多从机。④、发送和接收都有一个32x64的FIFO。⑤、片选信号SS/CS,时钟信号S......
  • pgspider 3.1.0 发布
    从最近一段时间pgspider迭代速度似乎是很快新版本支持的特性数据迁移 支持本地表,外表等的迁移路由添加并行存储函数支持批量insert的表修改不少开发的fdw的更新说明pgspider最近的迭代速度的确是快了不少,一些新功能也是值得试用的参考资料https://github.com/pgs......
  • ACS系列(6) ACS QT版SPiiPlusClibraryDemo
    工程文件QT+=coreguigreaterThan(QT_MAJOR_VERSION,4):QT+=widgetsCONFIG+=c++17#YoucanmakeyourcodefailtocompileifitusesdeprecatedAPIs.#Inordertodoso,uncommentthefollowingline.#DEFINES+=QT_DISABLE_DEPRECATED_BEFORE=0x......
  • 【通信传输协议】总线协议之SPI
    一、SPI简介串行外设接口serialperipheralinterfacce,是摩托罗拉公司最先推出的一种同步串行传输规范。高速、全双工、同步的串行通信总线。SPI有主从两种模式,通常由一主多从模块组成。SPI通信需要至少4根线,单向传输时3根,MISO(主设备入)、MOSI(主设备出)、SCLK和CS/SS(片选)。 ......
  • Debian衍生桌面项目SpiralLinux12.231001发布
    SpiralLinux 是一个从Debian衍生出来的桌面项目,其重点是在所有主要桌面环境中实现简洁性和开箱即用的可用性。spiralLinux是为刚接触Linux世界的人们量身定制的发行版。这是GeckoLinux开发人员的创意,他更喜欢保持匿名。尽管他不愿透露姓名,但他的操作系统值得称赞,......
  • SPI 接口 CAN协议控制器 MCP2515/DP2515国产替代芯片DPC15
    can控制器是CAN局域网控制器的简称,为解决现代汽车中众多测量控制部件之间的数据交换而开发的一种串行数据通信总线。CAN可提供高达1Mbit/s的数据传输速率,这使实时控制变得非常容易。另外,硬件的错误检定特性也增强了CAN的抗电磁干扰能力。can控制器最初是为汽车的监测、控制系统而......
  • Thread.Sleep() 和 Thread.SpinWait()
    Thread.Sleep()和Thread.SpinWait() 前言:应用程序应该让线程等待而不是切换。 一:Thread.Sleep(1000);Thread.Sleep()方法:是强制放弃CPU的时间片,然后重新和其他线程一起参与CPU的竞争。 二:Thread.SpinWait(1000);Thread.SpinWait()方法:只是让CPU去执行一段没有用的代......
  • C语言数据类型占用字节大小+rand_mode/randomize_mode/static constraint+I2C和SPI的
    C语言数据类型占用字节大小https://blog.csdn.net/sinan1995/article/details/79577106对于整形,最大8字节,超出8字节的计算,要么用库,要么不用。64位编译器:char/unsignedchar:1字节char*:8字节shortint:2字节int/unsignedint:4字节longint:8字节float:4字节double:8字节lon......
  • 普冉PY32系列(九) GPIO模拟和硬件SPI方式驱动无线收发芯片XL2400
    目录普冉PY32系列(一)PY32F0系列32位CortexM0+MCU简介普冉PY32系列(二)UbuntuGCCToolchain和VSCode开发环境普冉PY32系列(三)PY32F002A资源实测-这个型号不简单普冉PY32系列(四)PY32F002A/003/030的时钟设置普冉PY32系列(五)使用JLinkRTT代替串口输出日志普冉P......
  • 普冉PY32系列(八) GPIO模拟和硬件SPI方式驱动无线收发芯片XN297LBW
    目录普冉PY32系列(一)PY32F0系列32位CortexM0+MCU简介普冉PY32系列(二)UbuntuGCCToolchain和VSCode开发环境普冉PY32系列(三)PY32F002A资源实测-这个型号不简单普冉PY32系列(四)PY32F002A/003/030的时钟设置普冉PY32系列(五)使用JLinkRTT代替串口输出日志普冉P......