去年NXP公众号活动,有幸获得LPC800-DIP,这也是手上仅有的NXP开发板了话不多说直接进入主题 概要:采用此开发板加上中科银河芯的GXHT30温湿度传感器(国产)实现温湿度测量,通过串口打印出来 一、 LPC800-DIP BOARD
1.官网下载此芯片的keil demo,在此基础上新建自己的工程 2.根据自己的需要写出串口的,LED灯实现函数,测试基本功能 3.下载调试基本功能 查看MCU的丝印确实是834,但是在选择device时如果选在834,JLINK不能识别
选择LPC824M201JHI33可以正确的识别
4.测试结果完成如图所示
基本的功能测试完成后就可以针对温湿度传感器进行调试了,写代码之前先对GXHT30温湿度进行一个简单的介绍 二、GXHT30温湿度传感器介绍
北京中科银河芯科技有限公司研发了的温湿度传感器产品, I2C接口温湿度传感器。温度湿度传感器的温度精度可达±0.3℃,湿度精度从±3%RH 自己画一个底板
1.关于传感器的使用方式,在手册上截取了一些个人认为比较重要的贴出来
下面针对时序图写GXHT30的IIC的代码,本代码采用IO口模拟IIC时序
- #define GXHT30_SDA_OUT GPIOSetDir(LPC_GPIO_PORT->PIN0, 20, 1)
- #define GXHT30_SDA_IN GPIOSetDir(LPC_GPIO_PORT->PIN0, 20, 0)
- #define GXHT30_SCL GPIOSetDir(LPC_GPIO_PORT->PIN0, 21, 1)
- #define GXHT30_State GPIOGetPinValue(LPC_GPIO_PORT->PIN0, 20)
- #define GXHT30_SDA_1 GPIOSetBitValue(LPC_GPIO_PORT->PIN0, 20, 1 )
- #define GXHT30_SDA_0 GPIOSetBitValue(LPC_GPIO_PORT->PIN0, 20, 0 )
- #define GXHT30_SCL_1 GPIOSetBitValue(LPC_GPIO_PORT->PIN0, 21, 1 )
- #define GXHT30_SCL_0 GPIOSetBitValue(LPC_GPIO_PORT->PIN0, 21, 0 )
- uint8_t TEM_Str[5];
- uint8_t CRC_TEM_BUF[2];
- uint8_t CRC_HUM_BUF[2];
- uint8_t CRC_HUM,CRC_TEM;
- uint16_t TEM_Buffer,HUM_Buffer,TEM,HUM;
- float TEM_Flash,HUM_Flash;
- /****************************************************************************
- * 功 能:CRC8校验函数
- * 名 称:uint8_t crc_high_first(uint8_t *ptr, uint8_t len)
- * 说 明:宽度:8位
- * 起始值:0xFF
- * 多项式:0x31(x^8+x^5+x^4++1)
- * 计算顺序:正序异或的计算
- * 返 回 值:计算结果
- ****************************************************************************/
- uint8_t Crc_High_First(uint8_t *ptr, uint8_t len)
- {
- uint8_t i;
- uint8_t crc=0xFF; /* 计算的初始crc值 */
- while(len--)
- {
- crc ^= *ptr++; /* 每次先与需要计算的数据异或,计算完指向下一数据 */
- for (i=8; i>0; --i) /* 下面这段计算过程与计算一个字节crc一样 */
- {
- if (crc & 0x80)
- crc = (crc << 1) ^ 0x31;
- else
- crc = (crc << 1);
- }
- }
- return (crc);
- }
- /*****************************************************************
- ADDR = 0,传感器芯片的地址为 0x44
- ADDR = 1,传感器芯片的地址为 0x45
- *****************************************************************/
- void GXHT30_Init(void)
- {
- GXHT30_SDA_OUT;
- GXHT30_SCL;
- GXHT30_SDA_1;
- GXHT30_SCL_1;
- }
- /*****************************************************************
- 产生GXHT30起始信号
- *****************************************************************/
- void GXHT30_Start(void)
- {
- GXHT30_SDA_OUT; //SDA线输出
- GXHT30_SCL_0;
- GXHT30_SDA_1;
- Delay_us(4);
- GXHT30_SCL_1;
- Delay_us(4);
- GXHT30_SDA_0;//START:when CLK is high,DATA change form high to low
- Delay_us(4);
- GXHT30_SCL_0;//钳住I2C总线,准备发送或接收数据
- }
- /*****************************************************************
- 产生GXHT30停止信号
- *****************************************************************/
- void GXHT30_Stop(void)
- {
- GXHT30_SDA_OUT;//sda线输出
- GXHT30_SCL_0;
- GXHT30_SDA_0; //STOP:when CLK is high DATA change form low to high
- Delay_us(4);
- GXHT30_SCL_1;
- Delay_us(4);
- GXHT30_SDA_1;//发送I2C总线结束信号
- Delay_us(4);
- }
- /*****************************************************************
- 等待应答信号到来,此应答信号为芯片产生
- 返回值:1,接收应答失败
- 0,接收应答成功
- *****************************************************************/
- uint8_t GXHT30_Wait_Ack(void)
- {
- uint16_t ErrTime=0;
- GXHT30_SDA_IN; //SDA设置为输入
- GXHT30_SDA_1;
- Delay_us(4);
- GXHT30_SCL_1;
- Delay_us(4);
- while(GXHT30_State)
- {
- ErrTime++;
- if(ErrTime>65530)
- {
- GXHT30_Stop();
- return 1;
- }
- }
- GXHT30_SCL_0;//时钟输出0
- Delay_us(4);
- return 0;
- }
- /*****************************************************************
- 产生ACK应答
- *****************************************************************/
- void GXHT30_Ack(void)
- {
- GXHT30_SCL_0;
- GXHT30_SDA_OUT;
- GXHT30_SDA_0;
- Delay_us(4);
- GXHT30_SCL_1;
- Delay_us(4);
- GXHT30_SCL_0;
- }
- /*****************************************************************
- 不产生ACK应答
- *****************************************************************/
- void GXHT30_NAck(void)
- {
- GXHT30_SCL_0;
- GXHT30_SDA_OUT;
- GXHT30_SDA_1;
- Delay_us(4);
- GXHT30_SCL_1;
- Delay_us(4);
- GXHT30_SCL_0;
- }
- /*****************************************************************
- GXHT30发送一个字节
- 返回从机有无应答
- 1,有应答
- 0,无应答
- *****************************************************************/
- void GXHT30_Send_Byte(uint8_t data)
- {
- uint8_t t;
- GXHT30_SDA_OUT;
- GXHT30_SCL_0; //拉低时钟开始数据传输
- for(t=0; t<8; t++)
- {
- if (data & 0x80)
- GXHT30_SDA_1;
- else
- GXHT30_SDA_0;
- Delay_us(4);
- GXHT30_SCL_1;
- Delay_us(4);
- GXHT30_SCL_0;
- Delay_us(4);
- data = data << 1;
- }
- }
- /*****************************************************************
- 读1个字节,ack=1时,发送ACK,ack=0,发送nACK
- *****************************************************************/
- uint8_t GXHT30_Read_Byte(uint8_t ack)
- {
- uint8_t i,R_Data=0;
- GXHT30_SDA_IN;//SDA设置为输入
- GXHT30_SCL_0;
- Delay_us(4);
- for(i=0; i<8; i++ )
- {
- GXHT30_SCL_1;
- // Delay_us(4);
- R_Data = R_Data << 1;
- if (GXHT30_State)
- R_Data |= 0x01;
- else
- R_Data &= 0xFE;
- Delay_us(4);
- GXHT30_SCL_0;
- Delay_us(4);
- }
- if (!ack)
- GXHT30_NAck();//发送nACK
- else
- GXHT30_Ack(); //发送ACK
- return R_Data;
- }
- /*****************************************************************
- 写16位命令函数,用于实现GXHT30的一些特殊功能
- 软件复位:0x30A2
- 中断周期测量:0x3093
- 加热器使能:0x306D
- 加热器禁止:0x3066
- 清除内部寄存器:0x3041
- *****************************************************************/
- void GXHT30_WR_16Bits_CMD(uint16_t CMD)
- {
- uint8_t CMD_L,CMD_H;
- CMD_H = CMD >> 8;
- CMD_L = (uint8_t)CMD;
- GXHT30_Start();
- GXHT30_Send_Byte(0x88);//地址写命令
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(CMD_H);
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(CMD_L);
- GXHT30_Wait_Ack();
- GXHT30_Stop();
- }
- /*****************************************************************
- 读取内部状态寄存器函数
- *****************************************************************/
- uint16_t GXHT30_Read_Register(uint8_t CMD_MSB,uint8_t CMD_LSB)
- {
- uint16_t Register;
- uint8_t Register_H,Register_L,CRC_Buf;
- GXHT30_Start();
- GXHT30_Send_Byte(0x88);//地址写命令
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(CMD_MSB);
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(CMD_LSB);
- GXHT30_Wait_Ack();
- GXHT30_Start();
- GXHT30_Send_Byte(0x89);//地址读命令
- GXHT30_Wait_Ack();
- Register_H=GXHT30_Read_Byte(1);
- Register_L=GXHT30_Read_Byte(1);
- CRC_Buf=GXHT30_Read_Byte(0);
- Register = ((uint16_t)Register_H << 8) + Register_L;
- return Register;
- }
- /*****************************************************************
- 软复位命令:0x30A2
- 写命令:0B10001000 即0x88
- 写命令:0B10001001 即0x89
- *****************************************************************/
- void GXHT30_RST(void)
- {
- GXHT30_Start();
- GXHT30_Send_Byte(0x88);//地址写命令
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(0x30);
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(0xA2);
- GXHT30_Wait_Ack();
- GXHT30_Stop();
- }
- /*****************************************************************
- 中断周期测量模式
- 命令:0x3093
- *****************************************************************/
- void GXHT30_Stop_Period_Convert(void)
- {
- GXHT30_Start();
- GXHT30_Send_Byte(0x88);//地址写命令
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(0x30);
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(0x93);
- GXHT30_Wait_Ack();
- GXHT30_Stop();
- }
- /*****************************************************************
- 单次转换(命令:)
- *****************************************************************/
- void GXHT30_Signal_Convert(uint8_t CMD_MSB,uint8_t CMD_LSB)
- {
- uint8_t TEM_Low,TEM_High,HUM_Low,HUM_High;
- GXHT30_Start();
- GXHT30_Send_Byte(0x88);//地址写命令
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(CMD_MSB);
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(CMD_LSB);
- GXHT30_Wait_Ack();
- GXHT30_Stop();
- Delay_ms(10);
- GXHT30_Start();
- // GXHT30_Send_Byte(0x89);//地址读命令
- // GXHT30_NAck();
- // GXHT30_Stop();
- // Delay_ms(2);
- // GXHT30_Start();
- GXHT30_Send_Byte(0x89);//地址读命令
- Delay_ms(5);
- GXHT30_Wait_Ack();
- TEM_High=GXHT30_Read_Byte(1);
- TEM_Low=GXHT30_Read_Byte(1);
- CRC_TEM=GXHT30_Read_Byte(1);
- CRC_TEM_BUF[0]=TEM_High;
- CRC_TEM_BUF[1]=TEM_Low;
- HUM_High=GXHT30_Read_Byte(1);
- HUM_Low=GXHT30_Read_Byte(1);
- CRC_HUM=GXHT30_Read_Byte(0);
- CRC_HUM_BUF[0]=HUM_High;
- CRC_HUM_BUF[1]=HUM_Low;
- GXHT30_Stop();
- TEM_Buffer = ((uint16_t)TEM_High << 8) + TEM_Low;
- HUM_Buffer = ((uint16_t)HUM_High << 8) + HUM_Low;
- }
- /*****************************************************************
- 周期转换
- *****************************************************************/
- void GXHT30_Period_Convert(uint8_t CMD_MSB,uint8_t CMD_LSB)
- {
- uint8_t TEM_Low,TEM_High,HUM_Low,HUM_High;
- // uint16_t TEM_Buf ,HUM_Buffer;
- uint8_t CRC_Buf;
- GXHT30_Start();
- GXHT30_Send_Byte(0x88);//地址写命令
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(CMD_MSB);
- GXHT30_Wait_Ack();
- GXHT30_Send_Byte(CMD_LSB);
- GXHT30_Wait_Ack();
- GXHT30_Start();
- GXHT30_Send_Byte(0x89);//地址读命令
- GXHT30_Wait_Ack();
- TEM_High=GXHT30_Read_Byte(1);
- TEM_Low=GXHT30_Read_Byte(1);
- CRC_Buf=GXHT30_Read_Byte(1);
- HUM_High=GXHT30_Read_Byte(1);
- HUM_Low=GXHT30_Read_Byte(1);
- CRC_Buf=GXHT30_Read_Byte(0);
- GXHT30_Stop();
- TEM_Buffer = ((uint16_t)TEM_High << 8) + TEM_Low;
- HUM_Buffer = ((uint16_t)HUM_High << 8) + HUM_Low;
- }
- /*****************************************************************
- 测量处理函数,转换成具体的温度数值
- *****************************************************************/
- void GXHT30_Measure_Action(void)
- {
- TEM_Flash =(175.0 * (float)TEM_Buffer/65535.0 -45.0); //温度计算
- HUM_Flash = (100.0*HUM_Buffer/65535.0);
- if (TEM_Flash < 0.0) //如为负数,首位为1
- TEM = (uint16_t) (TEM_Flash * (-10.0)) + 0x8000; //10倍储存
- else
- TEM = (uint16_t) (TEM_Flash * 10.0); //10倍储存
- HUM = (uint16_t) (HUM_Flash * 10.0); //10倍储存
- }
- void TEM_TO_Str(void)
- {
- memset(TEM_Str,0,sizeof(TEM_Str));
- if(TEM&0x8000)
- TEM_Str[0]='1';
- else
- TEM_Str[0]='0';
- TEM=TEM&0x7FFF;
- TEM_Str[1]=TEM/100+'0';
- TEM_Str[2]=(TEM%100)/10+'0';
- TEM_Str[3]=TEM%10+'0';
- TEM_Str[4]='\0';
- }
- //十进制三位数转换为字符串(0~999?
- void Three_DigitNum2_Str(uint16_t Num, uint8_t *Num_Str)
- {
- Num_Str[0]= Num/100 + '0';
- Num_Str[1]= (Num%100)/10 + '0';
- Num_Str[2]= Num%10 + '0';
- Num_Str[3]= '\0';
- }
- //读取单次转换的温湿度数据并转换成字符串
- void GXHT30_Read_Signal_Result(void)
- {
- char tem_buf[6];
- char tem_buf1[5];
- GXHT30_Signal_Convert(0x24,0x16);
- GXHT30_Measure_Action();
- if(TEM_Str[0]=='1')
- tem_buf[0]='-';
- else
- tem_buf[0] = '+';
- tem_buf[1] = TEM/100+'0';
- tem_buf[2] = (TEM%100)/10+'0';
- tem_buf[3] = '.';
- tem_buf[4] = TEM%10+'0';
- tem_buf[5] = '\0';
- tem_buf1[0] = HUM/100+'0';
- tem_buf1[1] = (HUM%100)/10+'0';
- tem_buf1[2] = '.';
- tem_buf1[3] = HUM%10+'0';
- tem_buf1[4] = '\0';
- UART_SendStr("Temperature= ");
- UART_SendStr(tem_buf);
- UART_SendStr("℃ ;");
- UART_SendStr(" Humidity= ");
- UART_SendStr(tem_buf1);
- UART_SendStr("% ");
-
-
- }
复制代码
硬件搭建图
上个视频效果图,视频中间用手按住温湿度传感器,观察温湿度的变化情况
代码工程 |