{"id":855,"date":"2026-04-29T15:20:30","date_gmt":"2026-04-29T07:20:30","guid":{"rendered":"https:\/\/hsiang.cc\/?p=855"},"modified":"2026-04-28T15:28:59","modified_gmt":"2026-04-28T07:28:59","slug":"c-%e7%9a%84%e9%82%a3%e4%ba%9b%e7%9c%89%e8%a7%92%e4%b8%80%e5%80%8b%e5%87%bd%e5%bc%8f%e5%8f%aa%e5%81%9a%e4%b8%80%e4%bb%b6%e4%ba%8b-%e8%81%bd%e8%b5%b7%e4%be%86%e7%b0%a1%e5%96%ae%e4%bd%86","status":"publish","type":"post","link":"https:\/\/hsiang.cc\/?p=855","title":{"rendered":"[C \u7684\u90a3\u4e9b\u7709\u89d2]\u4e00\u500b\u51fd\u5f0f\u53ea\u505a\u4e00\u4ef6\u4e8b \u2014 \u807d\u8d77\u4f86\u7c21\u55ae\u4f46\u5f88\u96e3"},"content":{"rendered":"<p>\u300c\u4e00\u500b\u51fd\u5f0f\u53ea\u505a\u4e00\u4ef6\u4e8b\u3002\u300d<\/p>\n<p>\u9019\u53e5\u8a71\u6211\u5f88\u65e9\u5c31\u807d\u904e\uff0c\u89ba\u5f97\u81ea\u5df1\u61c2\u4e86\uff0c\u7136\u5f8c\u7e7c\u7e8c\u5beb\u51fa\u9019\u7a2e\u6771\u897f\uff1a<\/p>\n<pre><code class=\"language-c\">int process_sensor_data(void) {\n    \/\/ \u8b80\u53d6\u611f\u6e2c\u5668\n    uint8_t raw[8];\n    i2c_read(SENSOR_ADDR, raw, sizeof(raw));\n\n    \/\/ \u89e3\u6790\u8cc7\u6599\n    int16_t temp = (raw[0] &lt;&lt; 8) | raw[1];\n    int16_t humidity = (raw[2] &lt;&lt; 8) | raw[3];\n\n    \/\/ \u63db\u7b97\u55ae\u4f4d\n    float temp_c = temp \/ 100.0f;\n    float humi_pct = humidity \/ 100.0f;\n\n    \/\/ \u6aa2\u67e5\u662f\u5426\u8d85\u904e\u95be\u503c\n    if (temp_c &gt; 85.0f || humi_pct &gt; 95.0f) {\n        trigger_alarm();\n    }\n\n    \/\/ \u5b58\u5230\u5168\u57df\u8b8a\u6578\n    g_temperature = temp_c;\n    g_humidity = humi_pct;\n\n    \/\/ \u767c\u9001\u5230 server\n    mqtt_publish(&quot;sensor\/data&quot;, temp_c, humi_pct);\n\n    return 0;\n}<\/code><\/pre>\n<p>\u9019\u500b\u51fd\u5f0f\u505a\u4e86\u5e7e\u4ef6\u4e8b\uff1f<\/p>\n<p>\u8b80\u53d6\u3001\u89e3\u6790\u3001\u63db\u7b97\u3001\u5224\u65b7\u3001\u5b58\u503c\u3001\u767c\u9001\u3002<strong>\u516d\u4ef6\u4e8b\u3002<\/strong><\/p>\n<p>\u7576\u6642\u89ba\u5f97\u300c\u9019\u6a23\u5beb\u5f88\u65b9\u4fbf\uff0c\u4e00\u500b\u51fd\u5f0f\u641e\u5b9a\u6240\u6709\u4e8b\u60c5\u300d\u3002<br \/>\n\u76f4\u5230\u9700\u8981\u4fee\u6539\u7684\u6642\u5019\u624d\u767c\u73fe\uff0c\u727d\u4e00\u9aee\u52d5\u5168\u8eab\uff0c<br \/>\n\u6539\u500b\u95be\u503c\u8981\u627e\u534a\u5929\uff0c\u52a0\u500b\u932f\u8aa4\u8655\u7406\u4e0d\u77e5\u9053\u8981\u52a0\u5728\u54ea\u88e1\uff0c<br \/>\n\u55ae\u5143\u6e2c\u8a66\u6839\u672c\u4e0d\u77e5\u9053\u5f9e\u54ea\u88e1\u4e0b\u624b\u3002<\/p>\n<p><!--more--><\/p>\n<hr \/>\n<h2>\u300c\u4e00\u4ef6\u4e8b\u300d\u5230\u5e95\u662f\u591a\u5927\uff1f<\/h2>\n<p>\u9019\u662f\u6700\u96e3\u7684\u90e8\u5206\u3002<\/p>\n<p>\u6c92\u6709\u4e00\u500b\u7cbe\u78ba\u7684\u5b9a\u7fa9\u8aaa\u300c\u4e00\u4ef6\u4e8b\u300d\u662f\u4ec0\u9ebc\uff0c<br \/>\n\u4f46\u6709\u5e7e\u500b\u554f\u984c\u53ef\u4ee5\u5e6b\u4f60\u5224\u65b7\uff1a<\/p>\n<p><strong>\u300c\u4f60\u80fd\u4e0d\u80fd\u7528\u4e00\u53e5\u8a71\u63cf\u8ff0\u9019\u500b\u51fd\u5f0f\u5728\u505a\u4ec0\u9ebc\uff0c\u800c\u4e14\u4e0d\u9700\u8981\u7528\u300e\u7136\u5f8c\u300f\u6216\u300e\u9084\u6709\u300f\uff1f\u300d<\/strong><\/p>\n<pre><code>process_sensor_data \u2014 \u8b80\u53d6\u611f\u6e2c\u5668\uff0c\u7136\u5f8c\u89e3\u6790\uff0c\u7136\u5f8c\u63db\u7b97\uff0c\u7136\u5f8c\u767c\u9001\n                                  ^^^^        ^^^^        ^^^^\n                                  \u9019\u4e9b\u300c\u7136\u5f8c\u300d\u5c31\u662f\u8b66\u8a0a<\/code><\/pre>\n<pre><code>read_sensor_raw     \u2014 \u5f9e I2C \u8b80\u53d6\u611f\u6e2c\u5668\u539f\u59cb\u8cc7\u6599\nparse_sensor_raw    \u2014 \u628a\u539f\u59cb\u4f4d\u5143\u7d44\u89e3\u6790\u6210\u6578\u503c\nconvert_to_celsius  \u2014 \u628a ADC \u503c\u63db\u7b97\u6210\u651d\u6c0f\u6eab\u5ea6\ncheck_alarm_condition \u2014 \u6aa2\u67e5\u662f\u5426\u9700\u8981\u89f8\u767c\u8b66\u5831<\/code><\/pre>\n<p>\u6bcf\u500b\u51fd\u5f0f\u4e00\u53e5\u8a71\u8aaa\u6e05\u695a\uff0c\u6c92\u6709\u300c\u7136\u5f8c\u300d\u3002<\/p>\n<hr \/>\n<h2>\u62c6\u958b\u4e4b\u5f8c\u9577\u4ec0\u9ebc\u6a23<\/h2>\n<p>\u628a\u525b\u624d\u90a3\u500b\u51fd\u5f0f\u62c6\u958b\uff1a<\/p>\n<pre><code class=\"language-c\">\/\/ \u53ea\u8ca0\u8cac I2C \u8b80\u53d6\nstatic int read_sensor_raw(uint8_t *buf, size_t len) {\n    return i2c_read(SENSOR_ADDR, buf, len);\n}\n\n\/\/ \u53ea\u8ca0\u8cac\u89e3\u6790\u4f4d\u5143\u7d44\nstatic void parse_sensor_raw(const uint8_t *raw,\n                              int16_t *temp_raw,\n                              int16_t *humi_raw) {\n    *temp_raw = (raw[0] &lt;&lt; 8) | raw[1];\n    *humi_raw = (raw[2] &lt;&lt; 8) | raw[3];\n}\n\n\/\/ \u53ea\u8ca0\u8cac\u55ae\u4f4d\u63db\u7b97\nstatic float raw_to_celsius(int16_t raw) {\n    return raw \/ 100.0f;\n}\n\nstatic float raw_to_humidity(int16_t raw) {\n    return raw \/ 100.0f;\n}\n\n\/\/ \u53ea\u8ca0\u8cac\u5224\u65b7\u8b66\u5831\u689d\u4ef6\nstatic bool is_alarm_condition(float temp_c, float humi_pct) {\n    return (temp_c &gt; TEMP_ALARM_THRESHOLD ||\n            humi_pct &gt; HUMI_ALARM_THRESHOLD);\n}\n\n\/\/ \u4e0a\u5c64\u51fd\u5f0f\u8ca0\u8cac\u7d44\u5408\nint update_sensor_reading(void) {\n    uint8_t raw[8];\n\n    if (read_sensor_raw(raw, sizeof(raw)) != 0) {\n        return -1;\n    }\n\n    int16_t temp_raw, humi_raw;\n    parse_sensor_raw(raw, &amp;temp_raw, &amp;humi_raw);\n\n    g_temperature = raw_to_celsius(temp_raw);\n    g_humidity    = raw_to_humidity(humi_raw);\n\n    if (is_alarm_condition(g_temperature, g_humidity)) {\n        trigger_alarm();\n    }\n\n    return 0;\n}<\/code><\/pre>\n<p>\u7a0b\u5f0f\u78bc\u8b8a\u591a\u4e86\uff0c\u4f46\u6bcf\u500b\u51fd\u5f0f\u90fd\u5f88\u597d\u7406\u89e3\uff0c<br \/>\n\u800c\u4e14\u53ef\u4ee5\u7368\u7acb\u6e2c\u8a66\u3001\u7368\u7acb\u4fee\u6539\u3002<\/p>\n<hr \/>\n<h2>\u62c6\u51fd\u5f0f\u7684\u5be6\u969b\u597d\u8655<\/h2>\n<h3>\u6e2c\u8a66\u8b8a\u5f97\u53ef\u80fd<\/h3>\n<pre><code class=\"language-c\">\/\/ \u53ef\u4ee5\u55ae\u7368\u6e2c\u8a66\u89e3\u6790\u908f\u8f2f\uff0c\u4e0d\u9700\u8981\u771f\u5be6\u786c\u9ad4\nvoid test_parse_sensor_raw(void) {\n    uint8_t raw[] = {0x09, 0xC4, 0x17, 0x70, 0, 0, 0, 0};\n    int16_t temp_raw, humi_raw;\n\n    parse_sensor_raw(raw, &amp;temp_raw, &amp;humi_raw);\n\n    assert(temp_raw == 2500);   \/\/ 25.00\u00b0C\n    assert(humi_raw == 6000);   \/\/ 60.00%\n}<\/code><\/pre>\n<p>\u5982\u679c\u89e3\u6790\u908f\u8f2f\u8ddf I2C \u8b80\u53d6\u6df7\u5728\u4e00\u8d77\uff0c<br \/>\n\u4f60\u5c31\u5fc5\u9808\u6709\u771f\u5be6\u786c\u9ad4\u624d\u80fd\u6e2c\u8a66\uff0c\u975e\u5e38\u9ebb\u7169\u3002<\/p>\n<hr \/>\n<h3>\u4fee\u6539\u53ea\u5f71\u97ff\u4e00\u500b\u5730\u65b9<\/h3>\n<p>\u611f\u6e2c\u5668\u63db\u4e86\uff0c\u539f\u59cb\u8cc7\u6599\u683c\u5f0f\u4e0d\u540c\uff1f<br \/>\n\u53ea\u6539 <code>parse_sensor_raw<\/code>\uff0c\u5176\u4ed6\u4e0d\u52d5\u3002<\/p>\n<p>\u95be\u503c\u908f\u8f2f\u8981\u6539\uff1f<br \/>\n\u53ea\u6539 <code>is_alarm_condition<\/code>\uff0c\u5176\u4ed6\u4e0d\u52d5\u3002<\/p>\n<p>\u63db\u6210\u4e0d\u540c\u7684\u901a\u8a0a\u4ecb\u9762\uff1f<br \/>\n\u53ea\u6539 <code>read_sensor_raw<\/code>\uff0c\u5176\u4ed6\u4e0d\u52d5\u3002<\/p>\n<hr \/>\n<h3>\u932f\u8aa4\u8655\u7406\u66f4\u6e05\u695a<\/h3>\n<pre><code class=\"language-c\">\/\/ \u6bcf\u500b\u6b65\u9a5f\u7684\u932f\u8aa4\u53ef\u4ee5\u5206\u958b\u8655\u7406\nint update_sensor_reading(void) {\n    uint8_t raw[8];\n\n    if (read_sensor_raw(raw, sizeof(raw)) != 0) {\n        LOG_ERROR(&quot;Failed to read sensor via I2C&quot;);\n        return ERR_SENSOR_READ;\n    }\n\n    \/\/ \u89e3\u6790\u4e0d\u6703\u5931\u6557\uff0c\u6240\u4ee5\u4e0d\u7528\u6aa2\u67e5\n    int16_t temp_raw, humi_raw;\n    parse_sensor_raw(raw, &amp;temp_raw, &amp;humi_raw);\n\n    \/\/ ...\n    return 0;\n}<\/code><\/pre>\n<hr \/>\n<h2>\u4ec0\u9ebc\u6642\u5019\u4e0d\u61c9\u8a72\u62c6<\/h2>\n<p>\u8aaa\u4e86\u9019\u9ebc\u591a\u62c6\u51fd\u5f0f\u7684\u597d\u8655\uff0c\u4f46\u4e5f\u4e0d\u662f\u4ec0\u9ebc\u90fd\u8981\u62c6\u3002<\/p>\n<p><strong>\u62c6\u904e\u982d\u4e5f\u662f\u554f\u984c\uff1a<\/strong><\/p>\n<pre><code class=\"language-c\">\/\/ \u274c \u9019\u5c31\u592a\u8a87\u5f35\u4e86\nstatic int add_one(int x) {\n    return x + 1;\n}\n\nstatic int multiply(int a, int b) {\n    return a * b;\n}\n\nint calculate_area(int width, int height) {\n    return multiply(width, height);\n}<\/code><\/pre>\n<p>\u62c6\u5230\u9019\u7a2e\u7a0b\u5ea6\uff0c\u8b80\u7a0b\u5f0f\u78bc\u53cd\u800c\u8981\u4e00\u76f4\u8df3\u4f86\u8df3\u53bb\uff0c<br \/>\n\u6bd4\u76f4\u63a5\u5beb\u5728\u4e00\u8d77\u66f4\u96e3\u8b80\u3002<\/p>\n<p>\u6211\u7684\u5224\u65b7\u6a19\u6e96\uff1a<\/p>\n<ul>\n<li><strong>\u6709\u6c92\u6709\u7368\u7acb\u7684\u6e2c\u8a66\u50f9\u503c\uff1f<\/strong> \u5982\u679c\u9019\u6bb5\u908f\u8f2f\u503c\u5f97\u55ae\u7368\u6e2c\u8a66\uff0c\u5c31\u62c6<\/li>\n<li><strong>\u6709\u6c92\u6709\u53ef\u80fd\u88ab\u8907\u7528\uff1f<\/strong> \u5982\u679c\u5176\u4ed6\u5730\u65b9\u4e5f\u6703\u7528\u5230\uff0c\u5c31\u62c6<\/li>\n<li><strong>\u6709\u6c92\u6709\u4e0d\u540c\u7684\u8b8a\u5316\u983b\u7387\uff1f<\/strong> \u5982\u679c\u9019\u6bb5\u908f\u8f2f\u6bd4\u5176\u4ed6\u90e8\u5206\u66f4\u5e38\u6539\uff0c\u5c31\u62c6<\/li>\n<li><strong>\u770b\u8d77\u4f86\u50cf\u4e00\u500b\u5b8c\u6574\u7684\u6982\u5ff5\u55ce\uff1f<\/strong> \u6191\u611f\u89ba\uff0c\u4f46\u901a\u5e38\u662f\u5c0d\u7684<\/li>\n<\/ul>\n<hr \/>\n<h2>\u51fd\u5f0f\u9577\u5ea6\u7684\u554f\u984c<\/h2>\n<p>\u5f88\u591a\u4eba\u8aaa\u300c\u51fd\u5f0f\u4e0d\u80fd\u8d85\u904e X \u884c\u300d\uff0c<br \/>\n\u6211\u89ba\u5f97\u9019\u500b\u898f\u5247\u592a\u6b7b\u677f\u3002<\/p>\n<p>\u6709\u4e9b\u51fd\u5f0f\u5929\u751f\u5c31\u6bd4\u8f03\u9577\uff0c\u6bd4\u5982\u4e00\u500b\u8907\u96dc\u7684\u72c0\u614b\u6a5f\uff0c<br \/>\n\u786c\u8981\u62c6\u6210\u5f88\u591a\u5c0f\u51fd\u5f0f\u53cd\u800c\u66f4\u96e3\u7406\u89e3\u3002<\/p>\n<p>\u4f46\u5982\u679c\u4e00\u500b\u51fd\u5f0f\u8d85\u904e\u4e00\u500b\u87a2\u5e55\u7684\u9ad8\u5ea6\uff08\u5927\u6982 40-50 \u884c\uff09\uff0c<br \/>\n\u6211\u6703\u958b\u59cb\u554f\u81ea\u5df1\uff1a\u300c\u9019\u88e1\u6709\u6c92\u6709\u54ea\u500b\u6bb5\u843d\u53ef\u4ee5\u7368\u7acb\u51fa\u53bb\uff1f\u300d<\/p>\n<p>\u901a\u5e38\u90fd\u6709\u3002<\/p>\n<hr \/>\n<h2>\u8aaa\u5be6\u8a71<\/h2>\n<p>\u9019\u500b\u539f\u5247\u6211\u5230\u73fe\u5728\u9084\u662f\u5e38\u5e38\u9055\u53cd\u3002<\/p>\n<p>\u8d95\u529f\u80fd\u7684\u6642\u5019\uff0c\u6700\u5feb\u7684\u65b9\u5f0f\u5c31\u662f\u5728\u73fe\u6709\u51fd\u5f0f\u88e1\u9762\u7e7c\u7e8c\u52a0\uff0c<br \/>\n\u53cd\u6b63\u80fd\u52d5\u5c31\u597d\u3002<\/p>\n<p>\u7136\u5f8c\u904e\u4e86\u5e7e\u500b\u6708\uff0c\u90a3\u500b\u51fd\u5f0f\u8b8a\u6210 200 \u884c\u7684\u602a\u7269\uff0c<br \/>\n\u6c92\u6709\u4eba\u6562\u52d5\u5b83\uff0c\u56e0\u70ba\u4e0d\u77e5\u9053\u6539\u4e86\u54ea\u88e1\u6703\u5f71\u97ff\u4ec0\u9ebc\u3002<\/p>\n<p>\u6211\u89ba\u5f97\u9019\u500b\u7fd2\u6163\u9700\u8981\u5728<strong>\u5beb\u7684\u7576\u4e0b<\/strong>\u5c31\u523b\u610f\u7df4\u7fd2\uff0c<br \/>\n\u4e0d\u80fd\u7b49\u5230\u300c\u4e4b\u5f8c\u6709\u7a7a\u518d\u91cd\u69cb\u300d\uff0c\u56e0\u70ba\u90a3\u500b\u300c\u4e4b\u5f8c\u300d\u901a\u5e38\u4e0d\u6703\u4f86\u3002<\/p>\n<p>\u6bcf\u6b21\u5beb\u65b0\u51fd\u5f0f\u7684\u6642\u5019\uff0c\u591a\u554f\u81ea\u5df1\u4e00\u53e5\uff1a<br \/>\n\u300c\u9019\u500b\u51fd\u5f0f\u5728\u505a\u5e7e\u4ef6\u4e8b\uff1f\u300d<\/p>\n<hr \/>\n<h2>\u9019\u7bc7\u7684 Checklist<\/h2>\n<ul>\n<li>[ ] \u51fd\u5f0f\u80fd\u7528\u4e00\u53e5\u8a71\u63cf\u8ff0\uff0c\u4e0d\u9700\u8981\u300c\u7136\u5f8c\u300d\u6216\u300c\u9084\u6709\u300d<\/li>\n<li>[ ] \u51fd\u5f0f\u540d\u7a31\u662f\u300c\u52d5\u8a5e + \u540d\u8a5e\u300d\uff0c\u6e05\u695a\u8aaa\u660e\u505a\u4ec0\u9ebc<\/li>\n<li>[ ] \u6709\u7368\u7acb\u6e2c\u8a66\u50f9\u503c\u7684\u908f\u8f2f\u6709\u62c6\u51fa\u4f86<\/li>\n<li>[ ] \u53ef\u80fd\u88ab\u8907\u7528\u7684\u908f\u8f2f\u6709\u62c6\u51fa\u4f86<\/li>\n<li>[ ] \u51fd\u5f0f\u8d85\u904e 50 \u884c\u6642\uff0c\u6709\u554f\u81ea\u5df1\u662f\u5426\u53ef\u4ee5\u62c6<\/li>\n<li>[ ] \u6c92\u6709\u70ba\u4e86\u62c6\u800c\u62c6\uff0c\u6bcf\u500b\u5b50\u51fd\u5f0f\u90fd\u6709\u5b58\u5728\u7684\u610f\u7fa9<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>\u300c\u4e00\u500b\u51fd\u5f0f\u53ea\u505a\u4e00\u4ef6\u4e8b\u3002\u300d \u9019\u53e5\u8a71\u6211\u5f88\u65e9\u5c31\u807d\u904e\uff0c\u89ba\u5f97\u81ea\u5df1\u61c2\u4e86\uff0c\u7136\u5f8c\u7e7c\u7e8c\u5beb\u51fa\u9019\u7a2e\u6771\u897f &hellip; <a href=\"https:\/\/hsiang.cc\/?p=855\">\u95b1\u8b80\u5168\u6587 <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[15],"tags":[965,962,912,922,968,966,964,967,963,919,911,910,927,969,917],"class_list":{"0":"post-855","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"hentry","6":"category-prog","7":"tag-clean-code-c","8":"tag-c","13":"tag-964","14":"tag-967","15":"tag-963","17":"tag-911","18":"tag-910","19":"tag-927","20":"tag-969","21":"tag-917"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/hsiang.cc\/index.php?rest_route=\/wp\/v2\/posts\/855","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hsiang.cc\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hsiang.cc\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hsiang.cc\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hsiang.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=855"}],"version-history":[{"count":1,"href":"https:\/\/hsiang.cc\/index.php?rest_route=\/wp\/v2\/posts\/855\/revisions"}],"predecessor-version":[{"id":856,"href":"https:\/\/hsiang.cc\/index.php?rest_route=\/wp\/v2\/posts\/855\/revisions\/856"}],"wp:attachment":[{"href":"https:\/\/hsiang.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=855"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hsiang.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=855"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hsiang.cc\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=855"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}