SHT30温湿度传感器详解(STM32)

news2024/11/13 15:22:54

目录

一、介绍

二、传感器原理

1.原理图

2.引脚描述

3.工作原理

三、程序设计

main.c文件

sht30.h文件

sht30.c文件

四、实验效果 

五、资料获取

项目分享


一、介绍

        SHT30是一种常见的温湿度传感器,是一款完全校准的线性化的温湿度数字传感器,增强了数字信号。I2C通讯频率达1MHz。具有高可靠性及高稳定性。该传感器广泛应用于各种场景,小米的温湿度传感器就是使用的SHT30,本文是已硬件IIC来驱动SHT30

以下是SHT30温湿度传感器的参数:

型号

SHT30

工作电压

2.4~5.5V

接口输出

IIC

测量温度范围

-40~125

测量湿度范围

0~100%RH

湿度精度

3%RH

温度精度

0.3

哔哩哔哩视频链接:

SHT30温湿度传感器(STM32)

(资料分享见文末) 

二、传感器原理

1.原理图

2.引脚描述

引脚名称

描述

SDA

数据信号

ADDR

连接到高电平或低电平,不可以悬空

ALERT

报警引脚,不用必须悬空

SCL

时钟信号

VDD

电源正极

nRESET

低电平复位

R

无功能,接地

VSS

电源地

EPAD

中间引脚与电源地相通,散热引脚

3.工作原理

SHT30写命令

 

SHT30读命令 

SHT30温湿度转换方法

    信号输出的转换:测量数据总是以16位值( 无符号整数)的形式传输。这些值已经线性化,并补偿了温度和电源电压的影响。 将这些原始值转换为物理标度可以使用以下公式实现。相对湿度换算公式(结果为%RH)

    Srh和St表示温湿度的原始传感器输出。计算出结果为十进制数据。

三、程序设计

1.使用STM32F103C8T6读取SHT30温湿度传感器采集的数据,通过串口发送至电脑

2.将读取得到信息数据同时在OLED上显示

SHT30_SCL

PB9

SHT30_SDA

PB8

OLED_SCL

PB11

OLED_SDA

PB10

串口

串口1

main.c文件

#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "oled.h"
#include "sht30.h"

/*****************辰哥单片机设计******************
											STM32
 * 项目			:	SHT30温湿度传感器实验                     
 * 版本			: V1.0
 * 日期			: 2024.9.9
 * MCU			:	STM32F103C8T6
 * 接口			:	参看sht30.h							
 * BILIBILI	:	辰哥单片机设计
 * CSDN			:	辰哥单片机设计
 * 作者			:	辰哥 

**********************BEGIN***********************/

u8 buff[30];//参数显示缓存数组
int Temp = 0;
uint16_t Humi = 0;	//温度和湿度

int main(void)
{ 
	
  SystemInit();//配置系统时钟为72M	
	delay_init(72);
	LED_Init();
	LED_On();
	SHT30_Init();
	USART1_Config();//串口初始化
	
	OLED_Init();
	printf("Start \n");
	delay_ms(1000);
	
	OLED_Clear();
	//显示“温度:”
	OLED_ShowChinese(0,0,0,16,1);
	OLED_ShowChinese(16,0,2,16,1);
	OLED_ShowChar(32,0,':',16,1);
	//显示“湿度:”
	OLED_ShowChinese(0,16,1,16,1);
	OLED_ShowChinese(16,16,2,16,1);
	OLED_ShowChar(32,16,':',16,1);

  while (1)
  {
		LED_Toggle();
		SHT30_Read_Humiture(&Temp,&Humi);

//		sprintf((char*)buff, "%d    ",Temp);
//		OLED_ShowString(48,0,buff,16,1);
//		
//		sprintf((char*)buff, "%d    ",Humi);
//		OLED_ShowString(48,16,buff,16,1);
		
		OLED_ShowNum(48,0,Temp,2,16,1);
		OLED_ShowNum(48,16,Humi,2,16,1);
		delay_ms(500);	//延时500ms

  }
}

sht30.h文件

#ifndef __SHT30_H
#define	__SHT30_H
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"

/*****************辰哥单片机设计******************
											STM32
 * 文件			:	SHT30温湿度传感器h文件                   
 * 版本			: V1.0
 * 日期			: 2024.9.9
 * MCU			:	STM32F103C8T6
 * 接口			:	见代码							
 * BILIBILI	:	辰哥单片机设计
 * CSDN			:	辰哥单片机设计
 * 作者			:	辰哥

**********************BEGIN***********************/


/***************根据自己需求更改****************/
// CSHT30 GPIO宏定义

#define		SHT30_IIC_CLK										RCC_APB2Periph_GPIOB
#define 	SHT30_IIC_PORT									GPIOB
#define 	SHT30_IIC_SDA_PIN								GPIO_Pin_8	
#define 	SHT30_IIC_SCL_PIN								GPIO_Pin_9	

//IO操作函数	 
#define  SHT30_IIC_SDA_H   			GPIO_SetBits(SHT30_IIC_PORT,SHT30_IIC_SDA_PIN)
#define  SHT30_IIC_SDA_L   			GPIO_ResetBits(SHT30_IIC_PORT,SHT30_IIC_SDA_PIN)
				 
#define  SHT30_IIC_SCL_H   			GPIO_SetBits(SHT30_IIC_PORT,SHT30_IIC_SCL_PIN)
#define  SHT30_IIC_SCL_L   			GPIO_ResetBits(SHT30_IIC_PORT,SHT30_IIC_SCL_PIN) 

#define SHT30_READ_SDA  				GPIO_ReadInputDataBit(SHT30_IIC_PORT, SHT30_IIC_SDA_PIN) 		//输入SDA 

/*********************END**********************/

#define SHT30_ADDR (uint8_t)(0x44<<1) //sht30 i2c地址,ADDR管脚接低电平时为0x44,接高电平为0x45

//SHT30命令
#define SHT30_READ_HUMITURE (uint16_t)0x2c06  //读温湿度

//CRC多项式
#define POLYNOMIAL 0x31 // X^8 + X^5 + X^4 + 1




//SHT30

void SHT30_Init(void);
void SHT30_IIC_SDA_IN(void);
void SHT30_IIC_SDA_OUT(void);
	

void SHT30_IIC_Init(void);
void SHT30_IIC_start(void); 
void SHT30_IIC_stop(void);
uint8_t SHT30_IIC_Get_ack(void);
void SHT30_IIC_ACK(void);
void SHT30_IIC_NACK(void);
void SHT30_IIC_write_byte(uint8_t Data);
uint8_t SHT30_IIC_read_byte(uint8_t ack);



/**********************************
函数声明
**********************************/
unsigned char SHT3X_CRC(uint8_t *data, uint8_t len);
void SHT30_CMD(uint16_t cmd);
u8 SHT30_Read_Humiture(int *temp,uint16_t *humi);


#endif

sht30.c文件

#include "sht30.h"


/*****************辰哥单片机设计******************
											STM32
 * 文件			:	SHT30温湿度传感器c文件                   
 * 版本			: V1.0
 * 日期			: 2024.9.9
 * MCU			:	STM32F103C8T6
 * 接口			:	见代码							
 * BILIBILI	:	辰哥单片机设计
 * CSDN			:	辰哥单片机设计
 * 作者			:	辰哥

**********************BEGIN***********************/

#define POLYNOMIAL_CXDZ 0x31 // X^8 + X^5 + X^4 + 1



void SHT30_Init(void)	
{

	GPIO_InitTypeDef  GPIO_InitStructure;  

	RCC_APB2PeriphClockCmd(SHT30_IIC_CLK,ENABLE);
 

	GPIO_InitStructure.GPIO_Pin =  SHT30_IIC_SDA_PIN | SHT30_IIC_SCL_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//
	GPIO_Init(SHT30_IIC_PORT, &GPIO_InitStructure);

	SHT30_IIC_SDA_H;//释放IIC总线的数据线。
	SHT30_IIC_SCL_H;//释放IIC总线的时钟线。
	delay_us(6);
	
}


//SHT30引脚输出模式控制
void SHT30_IIC_SDA_OUT(void)//SDA输出方向配置
{
	GPIO_InitTypeDef GPIO_InitStructure;	
	
	GPIO_InitStructure.GPIO_Pin=SHT30_IIC_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//SDA推挽输出
	GPIO_Init(SHT30_IIC_PORT,&GPIO_InitStructure); 						
}

void SHT30_IIC_SDA_IN(void)//SDA输入方向配置
{
	GPIO_InitTypeDef GPIO_InitStructure;	
	
	GPIO_InitStructure.GPIO_Pin=SHT30_IIC_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//SCL上拉输入
	GPIO_Init(SHT30_IIC_PORT,&GPIO_InitStructure);
	
}



/****************************************************************
通讯起始信号:当 SCL 线是高电平时 SDA 线从高电平向低电平切换,表示通讯的开始;
*****************************************************************/

void SHT30_IIC_start(void)  
{

		SHT30_IIC_SDA_H;//拉高
		SHT30_IIC_SCL_H;
		delay_us(6);
		SHT30_IIC_SDA_L;
		SHT30_IIC_SCL_L;		//拉低时钟线,准备开始时钟
		delay_us(6);
}
/****************************************************************
通讯停止信号:当 SCL 是高电平时 SDA线由低电平向高电平切换,表示通讯的停止。
*****************************************************************/

void SHT30_IIC_stop(void) 
{

		SHT30_IIC_SCL_H;
		SHT30_IIC_SDA_L;
		delay_us(6);
		SHT30_IIC_SDA_H;	//通讯停止
		SHT30_IIC_SCL_L;
		delay_us(6);
}
/****************************************************************
//接收应答信号函数
*****************************************************************/

uint8_t SHT30_IIC_Get_ack(void)
{
		uint16_t CNT;
		SHT30_IIC_SDA_IN();
		SHT30_IIC_SCL_L;		//拉低时钟线。
		SHT30_IIC_SCL_H;		//拉高时钟线。
		delay_us(6);
		while((SHT30_READ_SDA)  && (CNT < 100) )
		{
				CNT++;
				if(CNT == 100)
				{
						return 0;
				}
		}

		SHT30_IIC_SCL_L;		//拉低时钟线。
		delay_us(6);
		SHT30_IIC_SDA_OUT();
		return 1;

}
/****************************************************************
//发送应答信号函数
*****************************************************************/

void SHT30_IIC_ACK(void)	
{ 

		SHT30_IIC_SDA_L;	//拉低数据线,应答
		SHT30_IIC_SCL_H;	//产生第九个时钟信号。
		delay_us(6);
		SHT30_IIC_SCL_L;	
		delay_us(6);
}
//非应答

void SHT30_IIC_NACK(void)
{ 

		SHT30_IIC_SDA_H;	//拉高数据线,非应答
		SHT30_IIC_SCL_H;	//产生第九个时钟信号。
		delay_us(6);
		SHT30_IIC_SCL_L;	

}

/****************************************************************
//向IIC总线写入一个字节的数据
*****************************************************************/

void SHT30_IIC_write_byte(uint8_t Data)
{

		uint8_t i;
		for(i=0;i<8;i++)//八位数据
		{
				if((Data & 0x80) == 0x80)
				{
						SHT30_IIC_SDA_H;
						
				}
				else
				{
						SHT30_IIC_SDA_L;
						
				}
				
				SHT30_IIC_SCL_H; //一个时钟信号送入数据
				delay_us(6);
				SHT30_IIC_SCL_L;
				delay_us(6);
				Data = Data << 1;//数据左移一位,把次高位放在最高位,为写入次高位做准备
				
		}
		SHT30_IIC_SDA_L;		//应答处理前拉低,跳过应答

}
/****************************************************************
//从IIC总线读取一个字节的数据函数
*****************************************************************/

uint8_t SHT30_IIC_read_byte(uint8_t ack)
{

		uint8_t i;
		uint8_t Data = 0;       //定义一个缓冲寄存器。
		SHT30_IIC_SDA_IN();
		SHT30_IIC_SCL_L;	//先拉低时钟线
		SHT30_IIC_SDA_H;	//再拉高数据线
		delay_us(6);
		for(i = 0;i < 8;i++)
		{
				Data = Data<<1;		//将缓冲字节的数据左移一位,准备读取数据。
				
				SHT30_IIC_SCL_H;				//拉高时钟线,开始读取下一位数据
				delay_us(6);
				if(SHT30_READ_SDA)		//如果数据线为高平电平。
				{
						Data = Data|0x01;	//则给缓冲字节的最低位写1。
				}
				SHT30_IIC_SCL_L;				//拉低时钟线,一位读取完成
				delay_us(6);
		}
		SHT30_IIC_SDA_OUT();
		if (!ack)
				SHT30_IIC_NACK();//发送nACK
    else
        SHT30_IIC_ACK(); //发送ACK   
		return Data;					//返回读取的一个字节数据。



}



//SHT3X CRC校验
unsigned char SHT3X_CRC(uint8_t *data, uint8_t len)
{
	uint8_t bit;        // bit mask
	uint8_t crc = 0xFF; // calculated checksum
	uint8_t byteCtr;    // byte counter

	// calculates 8-Bit checksum with given polynomial @GZCXDZ
	for(byteCtr = 0; byteCtr < len; byteCtr++) {
			crc ^= (data[byteCtr]);
			for(bit = 8; bit > 0; --bit) {
					if(crc & 0x80) {
							crc = (crc << 1) ^ POLYNOMIAL_CXDZ;
					}  else {
							crc = (crc << 1);
					}
			}
	}
  return crc;
}

//SHT30命令函数
//addr:表示产品的序号,因为SHT30使用IIC总线的话一条线上可以挂两个

void SHT30_CMD(uint16_t cmd)
{
	SHT30_IIC_start();
  SHT30_IIC_write_byte(SHT30_ADDR+0);  //发送设备地址,写寄存器
	SHT30_IIC_Get_ack();
	SHT30_IIC_write_byte((cmd>>8)&0xff); //MSB
	SHT30_IIC_Get_ack();
	SHT30_IIC_write_byte(cmd&0xff); //LSB
	SHT30_IIC_Get_ack();
	SHT30_IIC_stop();
	delay_ms(50);//命令发完后需要等待20ms以上才能读写
}



//SHT30读取温湿度
//temp:温度,-400~1250,实际温度=temp/10,分辨率0.1℃,精度±0.3℃
//humi:湿度,0~1000,实际湿度=humi/10,分辨率0.1%rh,精度±3
//返回0成功,1失败

u8 SHT30_Read_Humiture(int *temp,uint16_t *humi)
{
	uint8_t buff[6];
	
	SHT30_CMD(SHT30_READ_HUMITURE);//读温湿度命令
	
	SHT30_IIC_start();
	SHT30_IIC_write_byte(SHT30_ADDR+1); //发送设备地址,读寄存器
	SHT30_IIC_Get_ack();
	buff[0]=SHT30_IIC_read_byte(1);//继续读,给应答
	buff[1]=SHT30_IIC_read_byte(1);//继续读,给应答
	buff[2]=SHT30_IIC_read_byte(1);//继续读,给应答
	buff[3]=SHT30_IIC_read_byte(1);//继续读,给应答
	buff[4]=SHT30_IIC_read_byte(1);//继续读,给应答
	buff[5]=SHT30_IIC_read_byte(0);//不继续给停止应答
	SHT30_IIC_stop();

	
	//printf("buff=%d,%d,%d,%d,%d,%d\r\n",buff[0],buff[1],buff[2],buff[3],buff[4],buff[5]);
	//CRC校验
	if(SHT3X_CRC(&buff[0],2)==buff[2] && SHT3X_CRC(&buff[3],2)==buff[5])
	{

		*temp=(-45+(175.0*((buff[0]<<8)+buff[1])/65535.0));
		*humi=100*(((buff[3]<<8)+buff[4])/65535.0);
		if(*temp>12500) *temp=12500;
		else if(*temp<-4000) *temp=-4000;
		return 0;
	}
	else return 1;	
	
}

四、实验效果 

五、资料获取

项目分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2142054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8.1 溪降技术:横渡绳

目录 8.1 横渡绳将其置于上下文中&#xff1a;观看视频课程电子书&#xff1a;横渡绳一级横渡绳&#xff1a;识别使用横渡绳固定到横渡绳V7提示&#xff1a;保持张力中间点通过横渡绳上的中间点固定到锚点总结 8.1 横渡绳 绳上移动 横渡绳是一条水平安全绳&#xff0c;探险者可…

vue3 自定义el-tree树形结构样式

这里样式设置主要用到了 windcss 实现效果 模拟数据 这里也可以用模拟的数据,下面用的是后端请求的真实数据 [{"id": 5,"rule_id": 0,"status": 1,"create_time": "2019-08-11 13:36:09","update_time": "…

集团门户网站设计与实现

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装集团门户网站软件来发挥其高效地信息处理的作用&#xff0c…

深度学习之线性代数预备知识点

概念定义公式/案例标量(Scalar)一个单独的数值&#xff0c;表示单一的量。例如&#xff1a;5, 3.14, -2向量 (Vector)一维数组&#xff0c;表示具有方向和大小的量。 &#xff0c;表示三维空间中的向量 模(Magnitude)向量的长度&#xff0c;也称为范数&#xff08;通常为L2范数…

【论文阅读】BC-Z: Zero-Shot Task Generalization with Robotic Imitation Learning

Abstract 在这篇论文中&#xff0c;我们研究了使基于视觉的机器人操纵系统能够泛化到新任务的问题&#xff0c;这是机器人学习中的一个长期挑战。我们从模仿学习的角度来应对这一挑战&#xff0c;旨在研究如何扩展和扩大收集的数据来促进这种泛化。为此&#xff0c;我们开发了…

掌握回流与重绘面试回答:优化网页加载与响应速度

认识回流reflow和重绘repaint 理解回流reflow:(也可以称之为重排) 第一次确定节点的大小和位置&#xff0c;称之为布局(layout)。 之后对节点的大小、位置修改重新计算称之为回流 什么情况下引起回流呢&#xff1f; 比如DOM结构发生改变&#xff08;添加新的节点或者移除节…

Cortex-A7的GIC(通用中断控制器):边沿触发和电平触发中断的区别

0 资料 ARM Generic Interrupt Controller Architecture version 2.0 Architecture Specification1 边沿触发和电平触发中断的区别 1.1 边沿触发和电平触发中断官方解释 边沿触发&#xff08;Edge-triggered&#xff09; This is an interrupt that is asserted on detectio…

架构设计——概念和基础

&#x1f3e0;1 架构基础 想要搞清楚架构到底指什么&#xff0c;架构与框架的区别&#xff0c;就需要了解梳理系统、子系统、模块、组件、框架和架构 1.1系统与子系统 1.1.1系统 wiki:系统泛指由一群有关联的个体组成&#xff0c;根据某种规则运作&#xff0c;能完成个别元…

无限制使用OpenAI最新o1-mini、o1-preview模型:经济高效的AI推理模型

OpenAI 最新推出的 o1 模型是该公司推理模型家族的首位成员&#xff0c;它通过创新的“思维链”训练模式&#xff0c;显著提升了逻辑推理和问题解决的能力。o1 模型在编程竞赛问题、数学奥林匹克资格赛以及物理、生物和化学问题的基准测试中表现出色&#xff0c;甚至在某些领域…

数据爬虫中遇到验证码的解决方法

在数据爬虫中遇到验证码是一个常见且复杂的问题&#xff0c;验证码的存在主要是为了阻止自动化工具&#xff08;如爬虫&#xff09;对网站进行过度访问或数据抓取&#xff0c;以保护网站的安全性和数据的准确性。 一、验证码的基本概念与类型 验证码&#xff08;CAPTCHA&…

PointNet++改进策略 :模块改进 | LFA | RandLA-Net,通过随机采样与局部特征聚合提升大规模3D点云处理效率

论文题目:RandLA-Net: Efficient Semantic Segmentation of Large-Scale Point Clouds发布期刊:CVPR作者地址:1牛津大学、2中山大学、3国防科学技术大学代码地址:https://github.com/QingyongHu/RandLA-Net介绍 这篇论文题为《RandLA-Net: Efficient Semantic Segmentatio…

我又做了一个国标GB28181设备模拟器的Windows版本,让国标28181开发更简单,不用再费劲弄个摄像机来调试国标GB28181开发了

之前我搞过一个《EasyGBD国标GB28181设备端模拟器帮助测试国标GB28181平台&#xff08;EasyGBD-&#xff1e;EasyGBS&#xff09;》&#xff0c;当时&#xff0c;主要是在安卓手机上&#xff0c;用摄像机的本地摄像头来做为视频源、用摄像机的麦克风做为音频源&#xff0c;对外…

基于windows的mysql5.7安装配置教程

目录 0.写在前面的话 1.下载安装包 2.进行目录选择和解压操作 3.配置环境变量 4.创建my.ini文件 5.管理员运行终端 6.安装mysqld 7.初始化数据库 8.启动mysql服务 9.进入mysql管理终端 10.修改root密码 11.刷新权限 12.注销内容 13.重启mysql 14.输入密码测试 1…

Node.js 安装及项目实践

node.js安装 node安装&#xff0c;选择版本 一直next&#xff0c;或者自己修改路径&#xff0c;添加两个包 选择自己的安装的node的路径&#xff0c;cmd或者winr cmd 显示node与npm的版本号 node -vnpm -v可以跟着这个博客将node安装 2024最新版Node.js下载安装及环境配…

云原生信息安全:筑牢数字化时代的安全防线

云原生信息安全&#xff1a;筑牢数字化时代的安全防线 一、云原生信息安全概述 云原生安全包含两层重要含义。一方面&#xff0c;面向云原生环境的安全&#xff0c;目标是防护云原生环境中的基础设施、编排系统和微服务等系统的安全。在云原生内部&#xff0c;安全机制多以云原…

Java--String类(StringBuilder与StringBuffer)

String类的特征&#xff1a; String类的特点&#xff1a; 1. String 类在设计时就是不可改变的&#xff0c; String 类实现描述中已经说明了 String部分源码如下&#xff1a; 2. 所有涉及到可能修改字符串内容的操作都是创建一个新对象&#xff0c;改变的是新对象 例如…

string的模拟实现and友元

一、引言 “知所从来&#xff0c;方知其往。”只有了解一个物体的构造才能更好的使用它。正所谓“不入虎穴&#xff0c;焉得虎子。”那我们学会使用一个类了&#xff0c;可不可以建造一个简易的类和对象出来呢&#xff1f;答案显而易见。因为这是C的内容&#xff0c;所以我们用…

C++八股文之STL篇

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 思维导图链接&#xff1a;STL 持续更新中…… &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 &#x1f64…

找搭子是什么意思?有没有找搭子的平台?靠谱找搭子软件推荐!

“找搭子” 指寻找在特定活动或兴趣方面有共同爱好的伙伴。比如饭搭子一起吃饭&#xff0c;运动搭子共同健身。它满足人们在特定场景下的社交需求&#xff0c;让生活更丰富有趣&#xff0c;是一种新型社交方式。以下是国内排名靠前的找搭子平台 1. 咕哇找搭子小程序&#xff1a…

Mac下nvm无法安装node问题

背景 最近换用mac开发&#xff0c;然后使用nvm&#xff08;版本0.40.1&#xff09;进行node安装的时候出现了一些问题 使用 nvm ls-remote发现只有 iojs 版本 原因可能是nodejs升级了某个协议导致的 解决方案 可以使用 NVM_NODEJS_ORG_MIRRORhttp://nodejs.org/dist nvm ls-re…