查看: 1729|回复: 1

[主题月] 当LPC800DIP遇上中科银河芯GXHT30温湿度传感器

[复制链接]
  • TA的每日心情
    慵懒
    2023-1-31 09:34
  • 签到天数: 202 天

    [LV.7]常住居民III

    7

    主题

    1515

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    3814
    最后登录
    2024-2-19
    发表于 2021-5-30 13:38:33 | 显示全部楼层 |阅读模式
          去年NXP公众号活动,有幸获得LPC800-DIP,这也是手上仅有的NXP开发板了话不多说直接进入主题
        概要:采用此开发板加上中科银河芯的GXHT30温湿度传感器(国产)实现温湿度测量,通过串口打印出来
    一、     LPC800-DIP BOARD
                                19.png

    1.官网下载此芯片的keil  demo,在此基础上新建自己的工程
    2.根据自己的需要写出串口的,LED灯实现函数,测试基本功能
    3.下载调试基本功能
    查看MCU的丝印确实是834,但是在选择device时如果选在834,JLINK不能识别

    选择LPC824M201JHI33可以正确的识别
                    13.png         

    4.测试结果完成如图所示

                16.png
    基本的功能测试完成后就可以针对温湿度传感器进行调试了,写代码之前先对GXHT30温湿度进行一个简单的介绍
    二、GXHT30温湿度传感器介绍

    北京中科银河芯科技有限公司研发了的温湿度传感器产品, I2C接口温湿度传感器。温度湿度传感器的温度精度可达±0.3℃,湿度精度从±3%RH   
          自己画一个底板

                       7.png
    1.关于传感器的使用方式,在手册上截取了一些个人认为比较重要的贴出来
            
             17.png
        

    下面针对时序图写GXHT30的IIC的代码,本代码采用IO口模拟IIC时序

    1. #define GXHT30_SDA_OUT     GPIOSetDir(LPC_GPIO_PORT->PIN0, 20, 1)        
    2. #define GXHT30_SDA_IN        GPIOSetDir(LPC_GPIO_PORT->PIN0, 20, 0)
    3. #define GXHT30_SCL              GPIOSetDir(LPC_GPIO_PORT->PIN0, 21, 1)
    4. #define GXHT30_State            GPIOGetPinValue(LPC_GPIO_PORT->PIN0, 20)
    5. #define GXHT30_SDA_1          GPIOSetBitValue(LPC_GPIO_PORT->PIN0, 20, 1 )
    6. #define GXHT30_SDA_0          GPIOSetBitValue(LPC_GPIO_PORT->PIN0, 20, 0 )
    7. #define GXHT30_SCL_1           GPIOSetBitValue(LPC_GPIO_PORT->PIN0, 21, 1 )
    8. #define GXHT30_SCL_0           GPIOSetBitValue(LPC_GPIO_PORT->PIN0, 21, 0 )

    9. uint8_t TEM_Str[5];
    10. uint8_t CRC_TEM_BUF[2];
    11. uint8_t CRC_HUM_BUF[2];
    12. uint8_t CRC_HUM,CRC_TEM;
    13. uint16_t TEM_Buffer,HUM_Buffer,TEM,HUM;
    14. float TEM_Flash,HUM_Flash;

    15. /****************************************************************************
    16. * 功    能:CRC8校验函数
    17. * 名    称:uint8_t crc_high_first(uint8_t *ptr, uint8_t len)
    18. * 说    明:宽度:8位
    19. *                        起始值:0xFF
    20. *                        多项式:0x31(x^8+x^5+x^4++1)
    21. *                        计算顺序:正序异或的计算
    22. * 返 回 值:计算结果
    23. ****************************************************************************/

    24. uint8_t Crc_High_First(uint8_t *ptr, uint8_t len)
    25. {
    26.     uint8_t i;
    27.     uint8_t crc=0xFF;                 /* 计算的初始crc值 */

    28.     while(len--)
    29.     {
    30.         crc ^= *ptr++;  /* 每次先与需要计算的数据异或,计算完指向下一数据 */
    31.         for (i=8; i>0; --i)   /* 下面这段计算过程与计算一个字节crc一样 */
    32.         {
    33.             if (crc & 0x80)
    34.                 crc = (crc << 1) ^ 0x31;
    35.             else
    36.                 crc = (crc << 1);
    37.         }
    38.     }

    39.     return (crc);
    40. }

    41. /*****************************************************************
    42. ADDR = 0,传感器芯片的地址为 0x44
    43. ADDR = 1,传感器芯片的地址为 0x45
    44. *****************************************************************/
    45. void GXHT30_Init(void)
    46. {
    47.     GXHT30_SDA_OUT;
    48.     GXHT30_SCL;
    49.     GXHT30_SDA_1;
    50.     GXHT30_SCL_1;
    51. }


    52. /*****************************************************************
    53. 产生GXHT30起始信号
    54. *****************************************************************/
    55. void GXHT30_Start(void)
    56. {
    57.     GXHT30_SDA_OUT;     //SDA线输出
    58.     GXHT30_SCL_0;
    59.     GXHT30_SDA_1;
    60.     Delay_us(4);
    61.     GXHT30_SCL_1;
    62.     Delay_us(4);
    63.     GXHT30_SDA_0;//START:when CLK is high,DATA change form high to low
    64.     Delay_us(4);
    65.     GXHT30_SCL_0;//钳住I2C总线,准备发送或接收数据

    66. }

    67. /*****************************************************************
    68. 产生GXHT30停止信号
    69. *****************************************************************/
    70. void GXHT30_Stop(void)
    71. {
    72.     GXHT30_SDA_OUT;//sda线输出
    73.     GXHT30_SCL_0;
    74.     GXHT30_SDA_0;   //STOP:when CLK is high DATA change form low to high
    75.     Delay_us(4);
    76.     GXHT30_SCL_1;
    77.     Delay_us(4);
    78.     GXHT30_SDA_1;//发送I2C总线结束信号
    79.     Delay_us(4);
    80. }

    81. /*****************************************************************
    82. 等待应答信号到来,此应答信号为芯片产生
    83. 返回值:1,接收应答失败
    84.         0,接收应答成功
    85. *****************************************************************/
    86. uint8_t GXHT30_Wait_Ack(void)
    87. {
    88.     uint16_t ErrTime=0;
    89.     GXHT30_SDA_IN;      //SDA设置为输入
    90.     GXHT30_SDA_1;
    91.     Delay_us(4);
    92.     GXHT30_SCL_1;
    93.     Delay_us(4);
    94.     while(GXHT30_State)
    95.     {
    96.         ErrTime++;
    97.         if(ErrTime>65530)
    98.         {
    99.             GXHT30_Stop();
    100.             return 1;
    101.         }
    102.     }
    103.     GXHT30_SCL_0;//时钟输出0
    104.     Delay_us(4);
    105.     return 0;
    106. }

    107. /*****************************************************************
    108. 产生ACK应答
    109. *****************************************************************/
    110. void GXHT30_Ack(void)
    111. {
    112.     GXHT30_SCL_0;
    113.     GXHT30_SDA_OUT;
    114.     GXHT30_SDA_0;
    115.     Delay_us(4);
    116.     GXHT30_SCL_1;
    117.     Delay_us(4);
    118.     GXHT30_SCL_0;
    119. }
    120. /*****************************************************************
    121. 不产生ACK应答
    122. *****************************************************************/
    123. void GXHT30_NAck(void)
    124. {
    125.     GXHT30_SCL_0;
    126.     GXHT30_SDA_OUT;
    127.     GXHT30_SDA_1;
    128.     Delay_us(4);
    129.     GXHT30_SCL_1;
    130.     Delay_us(4);
    131.     GXHT30_SCL_0;
    132. }

    133. /*****************************************************************
    134. GXHT30发送一个字节
    135. 返回从机有无应答
    136. 1,有应答
    137. 0,无应答
    138. *****************************************************************/
    139. void GXHT30_Send_Byte(uint8_t data)
    140. {
    141.     uint8_t t;
    142.     GXHT30_SDA_OUT;
    143.     GXHT30_SCL_0;   //拉低时钟开始数据传输
    144.     for(t=0; t<8; t++)
    145.     {
    146.         if (data & 0x80)
    147.             GXHT30_SDA_1;
    148.         else
    149.             GXHT30_SDA_0;
    150.         Delay_us(4);
    151.         GXHT30_SCL_1;
    152.         Delay_us(4);
    153.         GXHT30_SCL_0;
    154.         Delay_us(4);
    155.         data = data << 1;
    156.     }
    157. }

    158. /*****************************************************************
    159. 读1个字节,ack=1时,发送ACK,ack=0,发送nACK
    160. *****************************************************************/
    161. uint8_t GXHT30_Read_Byte(uint8_t ack)
    162. {
    163.     uint8_t i,R_Data=0;
    164.     GXHT30_SDA_IN;//SDA设置为输入
    165.     GXHT30_SCL_0;
    166.     Delay_us(4);
    167.     for(i=0; i<8; i++ )
    168.     {
    169.         GXHT30_SCL_1;
    170.         // Delay_us(4);
    171.         R_Data = R_Data << 1;
    172.         if (GXHT30_State)
    173.             R_Data |= 0x01;
    174.         else
    175.             R_Data &= 0xFE;
    176.         Delay_us(4);
    177.         GXHT30_SCL_0;
    178.         Delay_us(4);
    179.     }
    180.     if (!ack)
    181.         GXHT30_NAck();//发送nACK
    182.     else
    183.         GXHT30_Ack(); //发送ACK
    184.     return R_Data;
    185. }

    186. /*****************************************************************
    187. 写16位命令函数,用于实现GXHT30的一些特殊功能
    188. 软件复位:0x30A2
    189. 中断周期测量:0x3093
    190. 加热器使能:0x306D
    191. 加热器禁止:0x3066
    192. 清除内部寄存器:0x3041
    193. *****************************************************************/
    194. void GXHT30_WR_16Bits_CMD(uint16_t CMD)
    195. {
    196.     uint8_t CMD_L,CMD_H;
    197.     CMD_H = CMD >> 8;
    198.     CMD_L = (uint8_t)CMD;
    199.     GXHT30_Start();
    200.     GXHT30_Send_Byte(0x88);//地址写命令
    201.     GXHT30_Wait_Ack();
    202.     GXHT30_Send_Byte(CMD_H);
    203.     GXHT30_Wait_Ack();
    204.     GXHT30_Send_Byte(CMD_L);
    205.     GXHT30_Wait_Ack();
    206.     GXHT30_Stop();
    207. }


    208. /*****************************************************************
    209. 读取内部状态寄存器函数

    210. *****************************************************************/
    211. uint16_t GXHT30_Read_Register(uint8_t CMD_MSB,uint8_t CMD_LSB)
    212. {

    213.     uint16_t Register;
    214.     uint8_t Register_H,Register_L,CRC_Buf;
    215.     GXHT30_Start();
    216.     GXHT30_Send_Byte(0x88);//地址写命令
    217.     GXHT30_Wait_Ack();
    218.     GXHT30_Send_Byte(CMD_MSB);
    219.     GXHT30_Wait_Ack();
    220.     GXHT30_Send_Byte(CMD_LSB);
    221.     GXHT30_Wait_Ack();
    222.     GXHT30_Start();
    223.     GXHT30_Send_Byte(0x89);//地址读命令
    224.     GXHT30_Wait_Ack();
    225.     Register_H=GXHT30_Read_Byte(1);
    226.     Register_L=GXHT30_Read_Byte(1);
    227.     CRC_Buf=GXHT30_Read_Byte(0);
    228.     Register  = ((uint16_t)Register_H << 8) + Register_L;
    229.     return Register;
    230. }

    231. /*****************************************************************
    232. 软复位命令:0x30A2

    233. 写命令:0B10001000 即0x88
    234. 写命令:0B10001001 即0x89
    235. *****************************************************************/

    236. void GXHT30_RST(void)
    237. {
    238.     GXHT30_Start();
    239.     GXHT30_Send_Byte(0x88);//地址写命令
    240.     GXHT30_Wait_Ack();
    241.     GXHT30_Send_Byte(0x30);
    242.     GXHT30_Wait_Ack();
    243.     GXHT30_Send_Byte(0xA2);
    244.     GXHT30_Wait_Ack();
    245.     GXHT30_Stop();
    246. }



    247. /*****************************************************************
    248. 中断周期测量模式
    249. 命令:0x3093
    250. *****************************************************************/
    251. void GXHT30_Stop_Period_Convert(void)
    252. {
    253.     GXHT30_Start();
    254.     GXHT30_Send_Byte(0x88);//地址写命令
    255.     GXHT30_Wait_Ack();
    256.     GXHT30_Send_Byte(0x30);
    257.     GXHT30_Wait_Ack();
    258.     GXHT30_Send_Byte(0x93);
    259.     GXHT30_Wait_Ack();
    260.     GXHT30_Stop();
    261. }

    262. /*****************************************************************
    263. 单次转换(命令:)
    264. *****************************************************************/


    265. void GXHT30_Signal_Convert(uint8_t CMD_MSB,uint8_t CMD_LSB)
    266. {
    267.     uint8_t TEM_Low,TEM_High,HUM_Low,HUM_High;
    268.     GXHT30_Start();
    269.     GXHT30_Send_Byte(0x88);//地址写命令
    270.     GXHT30_Wait_Ack();
    271.     GXHT30_Send_Byte(CMD_MSB);
    272.     GXHT30_Wait_Ack();
    273.     GXHT30_Send_Byte(CMD_LSB);
    274.     GXHT30_Wait_Ack();
    275.     GXHT30_Stop();
    276.     Delay_ms(10);
    277.     GXHT30_Start();
    278. //    GXHT30_Send_Byte(0x89);//地址读命令
    279. //    GXHT30_NAck();
    280. //    GXHT30_Stop();
    281. //    Delay_ms(2);
    282. //    GXHT30_Start();
    283.     GXHT30_Send_Byte(0x89);//地址读命令
    284.     Delay_ms(5);
    285.     GXHT30_Wait_Ack();
    286.     TEM_High=GXHT30_Read_Byte(1);
    287.     TEM_Low=GXHT30_Read_Byte(1);
    288.     CRC_TEM=GXHT30_Read_Byte(1);
    289.     CRC_TEM_BUF[0]=TEM_High;
    290.     CRC_TEM_BUF[1]=TEM_Low;
    291.     HUM_High=GXHT30_Read_Byte(1);
    292.     HUM_Low=GXHT30_Read_Byte(1);
    293.     CRC_HUM=GXHT30_Read_Byte(0);
    294.     CRC_HUM_BUF[0]=HUM_High;
    295.     CRC_HUM_BUF[1]=HUM_Low;
    296.     GXHT30_Stop();
    297.     TEM_Buffer  = ((uint16_t)TEM_High << 8) + TEM_Low;
    298.     HUM_Buffer  = ((uint16_t)HUM_High << 8) + HUM_Low;
    299. }


    300. /*****************************************************************
    301. 周期转换

    302. *****************************************************************/

    303. void GXHT30_Period_Convert(uint8_t CMD_MSB,uint8_t CMD_LSB)
    304. {
    305.     uint8_t TEM_Low,TEM_High,HUM_Low,HUM_High;
    306. //        uint16_t TEM_Buf ,HUM_Buffer;
    307.     uint8_t CRC_Buf;
    308.     GXHT30_Start();
    309.     GXHT30_Send_Byte(0x88);//地址写命令
    310.     GXHT30_Wait_Ack();
    311.     GXHT30_Send_Byte(CMD_MSB);
    312.     GXHT30_Wait_Ack();
    313.     GXHT30_Send_Byte(CMD_LSB);
    314.     GXHT30_Wait_Ack();
    315.     GXHT30_Start();
    316.     GXHT30_Send_Byte(0x89);//地址读命令
    317.     GXHT30_Wait_Ack();
    318.     TEM_High=GXHT30_Read_Byte(1);
    319.     TEM_Low=GXHT30_Read_Byte(1);
    320.     CRC_Buf=GXHT30_Read_Byte(1);
    321.     HUM_High=GXHT30_Read_Byte(1);
    322.     HUM_Low=GXHT30_Read_Byte(1);
    323.     CRC_Buf=GXHT30_Read_Byte(0);
    324.     GXHT30_Stop();
    325.     TEM_Buffer  = ((uint16_t)TEM_High << 8) + TEM_Low;
    326.     HUM_Buffer  = ((uint16_t)HUM_High << 8) + HUM_Low;
    327. }

    328. /*****************************************************************
    329. 测量处理函数,转换成具体的温度数值
    330. *****************************************************************/

    331. void GXHT30_Measure_Action(void)
    332. {

    333.     TEM_Flash =(175.0 * (float)TEM_Buffer/65535.0 -45.0); //温度计算
    334.     HUM_Flash = (100.0*HUM_Buffer/65535.0);
    335.     if (TEM_Flash < 0.0) //如为负数,首位为1
    336.         TEM = (uint16_t) (TEM_Flash * (-10.0)) + 0x8000; //10倍储存
    337.     else
    338.         TEM = (uint16_t) (TEM_Flash * 10.0); //10倍储存
    339.     HUM = (uint16_t) (HUM_Flash * 10.0); //10倍储存

    340. }

    341. void TEM_TO_Str(void)
    342. {
    343.     memset(TEM_Str,0,sizeof(TEM_Str));
    344.     if(TEM&0x8000)
    345.         TEM_Str[0]='1';
    346.     else
    347.         TEM_Str[0]='0';
    348.     TEM=TEM&0x7FFF;
    349.     TEM_Str[1]=TEM/100+'0';
    350.     TEM_Str[2]=(TEM%100)/10+'0';
    351.     TEM_Str[3]=TEM%10+'0';
    352.     TEM_Str[4]='\0';
    353. }

    354. //十进制三位数转换为字符串(0~999?

    355. void Three_DigitNum2_Str(uint16_t Num,  uint8_t *Num_Str)
    356. {
    357.     Num_Str[0]= Num/100 + '0';
    358.     Num_Str[1]= (Num%100)/10 + '0';
    359.     Num_Str[2]= Num%10 + '0';
    360.     Num_Str[3]=  '\0';
    361. }


    362. //读取单次转换的温湿度数据并转换成字符串

    363. void GXHT30_Read_Signal_Result(void)
    364. {
    365.          char tem_buf[6];
    366.          char tem_buf1[5];
    367.          GXHT30_Signal_Convert(0x24,0x16);
    368.          GXHT30_Measure_Action();
    369.          if(TEM_Str[0]=='1')
    370.                  tem_buf[0]='-';
    371.          else
    372.                  tem_buf[0] = '+';
    373.                  tem_buf[1] = TEM/100+'0';
    374.            tem_buf[2] = (TEM%100)/10+'0';
    375.                   tem_buf[3] = '.';
    376.            tem_buf[4] = TEM%10+'0';
    377.                  tem_buf[5] = '\0';
    378.          tem_buf1[0] = HUM/100+'0';
    379.          tem_buf1[1] = (HUM%100)/10+'0';
    380.          tem_buf1[2] = '.';
    381.          tem_buf1[3] = HUM%10+'0';
    382.          tem_buf1[4] = '\0';
    383.          UART_SendStr("Temperature= ");
    384.          UART_SendStr(tem_buf);
    385.          UART_SendStr("℃ ;");
    386.          UART_SendStr(" Humidity= ");
    387.          UART_SendStr(tem_buf1);
    388.          UART_SendStr("% ");
    389.          
    390.          
    391. }
    复制代码
             
           硬件搭建图
              3.jpg




    上个视频效果图,视频中间用手按住温湿度传感器,观察温湿度的变化情况

          
    代码工程
    LPC834_GXHT30.zip (546.15 KB, 下载次数: 20)
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-10 22:38
  • 签到天数: 1335 天

    [LV.10]以坛为家III

    88

    主题

    4292

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9049
    最后登录
    2024-4-13
    发表于 2021-5-31 14:34:46 | 显示全部楼层
    使用NXP的芯片,IIC居然使用模拟IO的方式。简直是暴殄天物呀

    楼主的动手能力真棒!
    膜拜一下。

    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-24 05:52 , Processed in 0.114524 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表