PageRenderTime 53ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/src/hardware/sht11/sht11.c

https://bitbucket.org/blackbird745/stm32f4-webserver
C | 360 lines | 286 code | 46 blank | 28 comment | 26 complexity | bc1169bab3c0ae072872c134df4e576d MD5 | raw file
  1. #include "main.h"
  2. #include "sht11_config.h"
  3. #include "sht11.h"
  4. #define SHT11_CMD_TEMP 0x03
  5. #define SHT11_CMD_HUMID 0x05
  6. #define SHT11_CMD_WSTAT 0x06
  7. #define SHT11_CMD_RSTAT 0x07
  8. #define SHT11_CMD_RESET 0x1E
  9. /////////////////////////////////////////////////////////////////////////////
  10. // This version needs external pullups on SDA!
  11. /////////////////////////////////////////////////////////////////////////////
  12. static void delay(void) { uint8_t i; for(i = 0; i<25;i++); }
  13. #define scl_hi GPIO_SetBits(SHT11_SCK_GPIO_PORT, SHT11_SCK_PIN)
  14. #define scl_lo GPIO_ResetBits(SHT11_SCK_GPIO_PORT, SHT11_SCK_PIN)
  15. static void sda_hi(void) {
  16. GPIO_InitTypeDef GPIO_InitStructure;
  17. //SHT11_SDA_GPIO_PORT->MODER &= ~(GPIO_MODER_MODER6_0);
  18. //SHT11_SDA_GPIO_PORT->PUPDR &= ~(GPIO_PUPDR_PUPDR6);
  19. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  20. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
  21. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  22. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  23. GPIO_InitStructure.GPIO_Pin = SHT11_SDA_PIN;
  24. GPIO_Init(SHT11_SDA_GPIO_PORT, &GPIO_InitStructure);
  25. }
  26. static void sda_lo(void) {
  27. GPIO_InitTypeDef GPIO_InitStructure;
  28. //SHT11_SDA_GPIO_PORT->MODER |= GPIO_MODER_MODER6_0;
  29. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  30. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
  31. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  32. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  33. GPIO_InitStructure.GPIO_Pin = SHT11_SDA_PIN;
  34. GPIO_Init(SHT11_SDA_GPIO_PORT, &GPIO_InitStructure);
  35. }
  36. static void scl_pulse(void) { scl_hi; delay(); scl_lo; }
  37. static uint8_t sda_val(void) { return GPIO_ReadInputDataBit(SHT11_SDA_GPIO_PORT,SHT11_SDA_PIN) != Bit_RESET; }
  38. /////////////////////////////////////////////////////////////////////////////
  39. static uint8_t crc_value;
  40. static uint8_t sht11_state;
  41. static uint16_t sht11_hum_raw=0,
  42. sht11_tmp_raw=0;
  43. static int16_t sht11_hum=0,
  44. sht11_tmp=0;
  45. static void
  46. crc8(uint8_t b)
  47. {
  48. uint8_t i;
  49. for (i = 0; i < 8; ++i) {
  50. if ((crc_value ^ b) & 0x80) {
  51. crc_value <<= 1;
  52. crc_value ^= 0x31;
  53. } else
  54. crc_value <<= 1;
  55. b <<= 1;
  56. }
  57. }
  58. /////////////////////////////////////////////////////////////////////////////
  59. static uint8_t
  60. send(uint16_t b)
  61. {
  62. crc8(b);
  63. // data
  64. uint8_t i;
  65. for (i = 0; i < 8; ++i) {
  66. if (b & 0x80)
  67. sda_hi();
  68. else
  69. sda_lo();
  70. b <<= 1;
  71. delay();
  72. scl_pulse();
  73. }
  74. // acknowledge
  75. sda_hi();
  76. delay();
  77. uint8_t ack = sda_val();
  78. scl_pulse();
  79. return ack;
  80. }
  81. static uint8_t
  82. recv_data(void)
  83. {
  84. // data
  85. uint8_t b = 0;
  86. uint8_t i;
  87. for (i = 0; i < 8; ++i) {
  88. // data is transmitted MSB first
  89. b <<= 1;
  90. if (sda_val())
  91. b |= 1;
  92. scl_pulse();
  93. delay();
  94. }
  95. // lo acknowledge
  96. sda_lo();
  97. delay();
  98. scl_pulse();
  99. sda_hi();
  100. delay();
  101. crc8(b);
  102. return b;
  103. }
  104. static uint8_t
  105. recv_crc(void)
  106. {
  107. // data
  108. uint8_t b = 0;
  109. uint8_t i;
  110. for (i = 0; i < 8; ++i) {
  111. // CRC is transmitted LSB first
  112. b >>= 1;
  113. if (sda_val())
  114. b |= 0x80;
  115. scl_pulse();
  116. delay();
  117. }
  118. // hi acknowledge
  119. sda_hi();
  120. delay();
  121. scl_pulse();
  122. delay();
  123. return b;
  124. }
  125. static void
  126. start(void) {
  127. // reset communication
  128. uint8_t i;
  129. for (i = 0; i < 10; ++i) {
  130. scl_pulse();
  131. delay();
  132. }
  133. // "start" sequence
  134. scl_hi; delay();
  135. sda_lo(); delay();
  136. scl_lo; delay();
  137. scl_hi; delay();
  138. sda_hi(); delay();
  139. scl_lo; delay();
  140. }
  141. /////////////////////////////////////////////////////////////////////////////
  142. // Measurement sequence.
  143. uint8_t
  144. sht11_start_temp(void)
  145. {
  146. crc_value = SHT11_RESOLUTION << 7; // bit-reversed
  147. start();
  148. return send(SHT11_CMD_TEMP) == 0;
  149. }
  150. uint8_t
  151. sht11_start_humid(void)
  152. {
  153. crc_value = SHT11_RESOLUTION << 7; // bit-reversed
  154. start();
  155. return send(SHT11_CMD_HUMID) == 0;
  156. }
  157. uint8_t
  158. sht11_ready(void)
  159. {
  160. return sda_val() == 0;
  161. }
  162. int16_t
  163. result(void)
  164. {
  165. if (!sht11_ready())
  166. return SHT11_UNAVAIL;
  167. int16_t v = recv_data() << 8; v |= recv_data();
  168. uint8_t crc = recv_crc();
  169. if (crc != crc_value)
  170. return SHT11_CRC_FAIL;
  171. return v;
  172. }
  173. int16_t
  174. sht11_result_temp(void)
  175. {
  176. int16_t v = result();
  177. if (sht11_valid(v))
  178. {
  179. sht11_tmp_raw=(uint16_t)v;
  180. #if SHT11_RESOLUTION
  181. v = v * 4 - SHT11_TEMP_V_COMP;
  182. #else
  183. v -= SHT11_TEMP_V_COMP;
  184. #endif
  185. }
  186. return v;
  187. }
  188. int16_t
  189. sht11_result_humid(void)
  190. {
  191. int16_t v = result();
  192. if (sht11_valid(v))
  193. {
  194. sht11_hum_raw=(uint16_t)v;
  195. #if SHT11_RESOLUTION
  196. // inspired by Werner Hoch, modified for low resolution mode
  197. const int32_t C1 = (int32_t)(-4.0 * 100);
  198. const int32_t C2 = (int32_t)(0.648 * 100 * (1L<<24));
  199. const int32_t C3 = (int32_t)(-7.2e-4 * 100 * (1L<<24));
  200. v = (int16_t)((((C3 * v + C2) >> 7) * v + (1L<<16)) >> 17) + C1;
  201. const int32_t T1 = (uint32_t)(0.01 * (1L<<30));
  202. const int32_t T2 = (uint32_t)(0.00128 * (1L<<30));
  203. #else
  204. // inspired by Werner Hoch
  205. const int32_t C1 = (int32_t)(-4.0 * 100);
  206. const int32_t C2 = (int32_t)(0.0405 * 100 * (1L<<28));
  207. const int32_t C3 = (int32_t)(-2.8e-6 * 100 * (1L<<30));
  208. v = (int16_t)((((((C3 * v) >> 2) + C2) >> 11) * v + (1L<<16)) >> 17) + C1;
  209. const int32_t T1 = (uint32_t)(0.01 * (1L<<30));
  210. const int32_t T2 = (uint32_t)(0.00008 * (1L<<30));
  211. #endif
  212. // implemented by whitejack (temp compensation)
  213. v = (int16_t)( (((((int32_t)sht11_tmp-2500) * (int32_t)( (T1+T2*((int32_t)sht11_hum_raw)) >>13))>>17) + ((int32_t)v)) );
  214. }
  215. if(v>9999)v=9999;
  216. if(v<0001)v=0001;
  217. return v;
  218. }
  219. /////////////////////////////////////////////////////////////////////////////
  220. // Initialize.
  221. void
  222. sht11_init(void) {
  223. GPIO_InitTypeDef GPIO_InitStructure;
  224. /*!< Enable GPIO clocks */
  225. RCC_AHB1PeriphClockCmd(SHT11_SDA_GPIO_CLK | SHT11_SCK_GPIO_CLK, ENABLE);
  226. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  227. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
  228. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  229. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  230. GPIO_InitStructure.GPIO_Pin = SHT11_SCK_PIN;
  231. GPIO_Init(SHT11_SCK_GPIO_PORT, &GPIO_InitStructure);
  232. scl_lo;
  233. GPIO_InitStructure.GPIO_Pin = SHT11_SDA_PIN;
  234. GPIO_Init(SHT11_SDA_GPIO_PORT, &GPIO_InitStructure);
  235. GPIO_ResetBits(SHT11_SDA_GPIO_PORT, SHT11_SDA_PIN);
  236. delay();
  237. start();
  238. send(SHT11_CMD_RESET);
  239. uint32_t i;
  240. for(i = 0; i<154000;i++); //_delay_ms(11);
  241. start();
  242. send(SHT11_CMD_WSTAT);
  243. send(SHT11_RESOLUTION); //set resolution
  244. sht11_state=SHT11_STATE_MEASURE_TMP;
  245. }
  246. /////////////////////////////////////////////////////////////////////////////
  247. // User.
  248. void sht11_start_measure(void)
  249. {
  250. if(sht11_state==SHT11_STATE_READY)
  251. {
  252. sht11_state=SHT11_STATE_MEASURE_TMP;
  253. }
  254. }
  255. uint8_t sht11_measure(void)
  256. {
  257. switch(sht11_state)
  258. {
  259. case SHT11_STATE_MEASURE_TMP:
  260. {
  261. sht11_start_temp();
  262. sht11_state = SHT11_STATE_CALC_TMP;
  263. }break;
  264. case SHT11_STATE_CALC_TMP:
  265. {
  266. if(sht11_ready())
  267. {
  268. sht11_tmp=sht11_result_temp();
  269. sht11_state = SHT11_STATE_MEASURE_HUM;
  270. }
  271. }break;
  272. case SHT11_STATE_MEASURE_HUM:
  273. {
  274. sht11_start_humid();
  275. sht11_state = SHT11_STATE_CALC_HUM;
  276. }break;
  277. case SHT11_STATE_CALC_HUM:
  278. {
  279. if(sht11_ready())
  280. {
  281. sht11_hum=sht11_result_humid();
  282. sht11_state = SHT11_STATE_READY;
  283. }
  284. }break;
  285. }
  286. return sht11_state;
  287. }
  288. uint8_t sht11_measure_finish(void)
  289. {
  290. if(sht11_measure()==SHT11_STATE_READY)
  291. {
  292. return 1;
  293. }
  294. else
  295. {
  296. return 0;
  297. }
  298. }
  299. uint16_t sht11_get_tmp_raw(void)
  300. {
  301. return sht11_tmp_raw;
  302. }
  303. uint16_t sht11_get_hum_raw(void)
  304. {
  305. return sht11_hum_raw;
  306. }
  307. int16_t sht11_get_tmp(void)
  308. {
  309. return sht11_tmp;
  310. }
  311. int16_t sht11_get_hum(void)
  312. {
  313. return sht11_hum;
  314. }