CCS811.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /////////////////////////////////////////////////////////////////
  2. //
  3. // 本程序只供学习使用,未经作者许可,不得用于其它任何用途
  4. // STM32F103C8T6核心板
  5. // by Pang
  6. // 修改日期:2019/01/02
  7. // 版本:V1.0
  8. // 版权所有,盗版必究。
  9. // All rights reserved
  10. // 模块接线方式:PB10-I2C_SCL、PB11-I2C_SDA、PA4-nWAK
  11. //
  12. ////////////////////////////////////////////////////////////////
  13. #include "CCS811.h"
  14. u8 CCS_BUF[12];
  15. u8 Information[10];
  16. u8 MeasureMode, Status, Error_ID;
  17. u8 FlagGetId = 1;
  18. u8 n = 4; // 3次读取ID都对则说明没问题
  19. u8 CCS_temp = 0x5a;
  20. ccs811_measurement_t CCS;
  21. #define STEP_DELAY 100
  22. void CCS811_GPIO_Config()
  23. {
  24. GPIO_InitTypeDef GPIO_InitStructure;
  25. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开端口时钟
  26. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // CCS811-CS
  27. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  28. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  29. GPIO_Init(GPIOA, &GPIO_InitStructure);
  30. CCS811_CS_OFF();
  31. CCS811_I2C_GPIO_Config(); //IIC GPIO Configure
  32. }
  33. void CCS811Init()
  34. {
  35. u8 idCount = 0; // count the correct times of id.
  36. CCS811_CS_ON(); //nWAKE pin is asserted at least 50μs before the transaction and kept asserted throughout,nWAKE pin is active low
  37. delay_ms(STEP_DELAY);
  38. // get CCS811 device id,when addr pin connect to GND and the id is 0x81(129)
  39. while( FlagGetId)
  40. {
  41. CCS811_ReadI2C(CCS811_Add, 0x20, Information, 1); //Read CCS's information ,ID
  42. if(Information[0] == 0x81)
  43. {
  44. if(++idCount == n)
  45. {
  46. FlagGetId = 0;
  47. }
  48. else
  49. {
  50. //printf("id=%d,correct %d!\r\n", Information[0], idCount);
  51. }
  52. }
  53. else
  54. {
  55. //printf("id=%d,incorrect,continuing...\r\n", Information[0]);
  56. }
  57. delay_ms(STEP_DELAY);
  58. }
  59. //printf("id correct,initing...\r\n");
  60. delay_ms(STEP_DELAY);
  61. CCS811_ReadI2C(CCS811_Add, 0x23, &Information[1], 2); //FW_Boot_Version
  62. delay_ms(STEP_DELAY);
  63. CCS811_ReadI2C(CCS811_Add, 0x24, &Information[3], 2); //FW_App_Version
  64. delay_ms(STEP_DELAY);
  65. CCS811_ReadI2C(CCS811_Add, 0x00, &Status, 1); //Firstly the status register is read and the APP_VALID flag is checked.
  66. delay_ms(STEP_DELAY);
  67. // if there is valid application firmware loaded
  68. if(Status & 0x10)
  69. {
  70. while(!(Status & 0x80)) // if firmware not in application mode but boot mode.
  71. {
  72. CCS811_WriteI2C_byte(CCS811_Add, 0xF3, 0xF0); // Application Verify
  73. // printf("trying to transition the CCS811 state from boot to application mode...\r\n");
  74. CCS811_MWriteI2C_byte(CCS811_Add, 0xF4, &CCS_temp, 0); //Used to transition the CCS811 state from boot to application mode, a write with no data is required.
  75. delay_ms(STEP_DELAY);
  76. CCS811_ReadI2C(CCS811_Add, 0x00, &Status, 1);
  77. delay_ms(STEP_DELAY);
  78. }
  79. //printf("CCS811 is already in application mode!\r\n");
  80. }
  81. delay_ms(STEP_DELAY);
  82. CCS811_ReadI2C(CCS811_Add, 0x01, &MeasureMode, 1);
  83. delay_ms(STEP_DELAY);
  84. MeasureMode &= 0x70; // get measure mode
  85. //if measure mode incorrect,and reset the measure mode.
  86. while(MeasureMode != DRIVE_MODE_1SEC)
  87. {
  88. CCS811_WriteI2C_byte(CCS811_Add, 0x01, DRIVE_MODE_1SEC); // Write Measure Mode Register,sensor measurement every second,no interrupt
  89. delay_ms(STEP_DELAY);
  90. CCS811_ReadI2C(CCS811_Add, 0x01, &MeasureMode, 1);
  91. MeasureMode &= 0x70;
  92. // printf("trying to enter measure mode...\r\n");
  93. delay_ms(STEP_DELAY);
  94. }
  95. delay_ms(STEP_DELAY);
  96. CCS811_ReadI2C(CCS811_Add, 0x00, &Status, 1);
  97. delay_ms(STEP_DELAY);
  98. CCS811_ReadI2C(CCS811_Add, 0x01, &MeasureMode, 1);
  99. delay_ms(STEP_DELAY);
  100. CCS811_CS_OFF();
  101. delay_ms(STEP_DELAY);
  102. CCS811_ReadI2C(CCS811_Add, 0xE0, &Error_ID, 1);
  103. //printf("status=%d error_id=%d measureMode=%d \r\n", Status, Error_ID, MeasureMode);
  104. }
  105. void CCS811GetData()
  106. {
  107. CCS811_CS_ON(); // nWAKE pin is asserted at least 50μs before the transaction and kept asserted throughout,nWAKE pin is active low
  108. delay_ms(10);
  109. CCS811_ReadI2C(CCS811_Add, 0x02, CCS_BUF, 8);
  110. delay_ms(10);
  111. CCS811_ReadI2C(CCS811_Add, 0x20, Information, 1); // Read CCS's information ,ID
  112. delay_ms(10);
  113. CCS811_ReadI2C(CCS811_Add, 0xE0, &Error_ID, 1);
  114. CCS811_CS_OFF();
  115. CCS.eco2 = (u16)CCS_BUF[0] * 256 + CCS_BUF[1];
  116. CCS.tvoc = (u16)CCS_BUF[2] * 256 + CCS_BUF[3];
  117. CCS.device_id = Information[0];
  118. CCS.error_id = Error_ID;
  119. Error_ID = 0;
  120. Information[0] = 0;
  121. }
  122. void CCS811ClearData()
  123. {
  124. CCS.device_id = 0;
  125. CCS.eco2 = 0;
  126. CCS.status = 0;
  127. CCS.tvoc = 0;
  128. CCS.error_id = 0;
  129. }