使用 DHT11 温湿度传感器完成测量,并打印结果到串口;使用 SDCC 工具链编译
1. 下载并安装 SDCC,在 EIDE 上设置好安装路径
下载链接:SDCC

2. 使用 EIDE 新建一个 C51 项目

3. 编写代码
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include "dht11.h" #include "stdio.h" #include "soft_uart.h" /** * * 使用 DHT11 温湿度传感器完成测量,并打印结果到串口;使用 SDCC 工具链编译 * * 时钟频率 16 Mhz,要修改时钟频率,更改宏 CLOCK 的值即可; * 注意:CLOCK 的值为:晶振频率/一条指令所需周期数,如 12M 晶振的 89c52 单片机:CLOCK=1 * * -------------------- 引脚配置 --------------------- * * DHT11 DATA 引脚:P11 * * 串口输出引脚 TX:P10 * * ---------------------- 串口配置 ------------------------ * * 波特率:9600,位宽度:8,停止位:1 * * */ void main() { DHT11_Data dhtData; DHT11_Init(); while (1) { switch (DHT11_Measure(&dhtData)) { case DHT11_CONNECT_ERR: printf("connect DHT11 failed !\n"); break; case DHT11_VERIFY_ERR: printf("data verify error !\n"); break; default: printf("temp: %d, humidity: %d%%\n", (uint8_t)dhtData.temperature, dhtData.humidity); break; } Delay(2000); } } int putchar(int c) { TxSend((uint8_t)c); return c; } |
dht11.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #ifndef _H_DHT11 #define _H_DHT11 #include "stdint.h" /** * Interface define */ #include "mcs51/8051.h" #include "delay.h" #define DATA_WRITE(val) P1_1 = (val) #define DATA_READ() P1_1 #define _Delay(ms) Delay(ms) void _Delay10us() //@16MHz { unsigned char i; _nop_(); _nop_(); i = 37; while (--i) ; } //--------------------- // 返回值含义 #define DHT11_DONE 0 #define DHT11_CONNECT_ERR 1 #define DHT11_VERIFY_ERR 2 typedef struct { uint8_t humidity; float temperature; } DHT11_Data; #define DHT11_Init() DATA_WRITE(1) uint8_t DHT11_Measure(DHT11_Data *dat) { int8_t buf[5]; uint8_t i, j, errCode = DHT11_DONE; DATA_WRITE(0); _Delay(20); // 开始信号 20 ms DATA_WRITE(1); // 60 us _Delay10us(); _Delay10us(); _Delay10us(); _Delay10us(); _Delay10us(); _Delay10us(); if (DATA_READ() == 0) { while (DATA_READ() == 0) //等待 DHT11 拉高 ; while (DATA_READ() == 1) ; i = 0; while (i < 5) { j = 0; while (j < 8) { while (DATA_READ() == 0) ; _Delay10us(); _Delay10us(); _Delay10us(); buf[i] <<= 1; buf[i] |= DATA_READ(); while (DATA_READ() == 1) ; j++; } i++; } _Delay10us(); _Delay10us(); _Delay10us(); _Delay10us(); _Delay10us(); _Delay10us(); if (buf[4] == buf[0] + buf[1] + buf[2] + buf[3]) { dat->temperature = buf[2]; dat->humidity = buf[0]; } else { errCode = DHT11_VERIFY_ERR; } } else { errCode = DHT11_CONNECT_ERR; } DATA_WRITE(1); _Delay(1); return errCode; } #endif |
delay.h
1 2 3 4 5 6 7 8 9 10 11 12 | #ifndef _H_DELAY_ #define _H_DELAY_ #include "stdint.h" #define _nop_() __asm nop __endasm void DelayUs(uint16_t us); void Delay(uint16_t ms); #endif |
delay.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include "delay.h" void DelayUs(uint16_t us) { uint16_t i, n = (us * CLOCK) >> 5; for (i = 0; i < n; i++) ; } void Delay(uint16_t ms) { uint16_t i, n = 62 * CLOCK; while (ms--) { for (i = 0; i < n; i++) ; } } |
soft_uart.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #ifndef _H_SOFT_UART #define _H_SOFT_UART /** * 波特率:9600,位宽度:8,停止位:1 */ #include "stdint.h" #include "mcs51/8051.h" #define P_TXD P1_0 //定义模拟串口发送端,可以是任意IO void TxSend(uint8_t dat); #endif |
soft_uart.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include "soft_uart.h" void BitTime(void) { uint16_t i; i = (CLOCK * 104) / 12 - 1; //根据主时钟来计算位时间 while (--i) ; } void TxSend(uint8_t dat) { uint8_t i; EA = 0; P_TXD = 0; BitTime(); for (i = 0; i < 8; i++) { if (dat & 1) P_TXD = 1; else P_TXD = 0; dat >>= 1; BitTime(); } P_TXD = 1; EA = 1; BitTime(); BitTime(); } |
4. 添加宏 CLOCK,本例中为 CLOCK=16,代表时钟为 16Mhz
CLOCK 怎样取值见 main.c 里的注释说明,这里不再阐述

5. 切换工具链为 SDCC,设置好编译参数,F6 开始编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | { "beforeBuildTasks":[], "afterBuildTasks": [ { "name": "清理输出目录", "command": "del "${OutDir}\\*.map" "${OutDir}\\*.lst" "${OutDir}\\*.rst" "${OutDir}\\*.sym"" } ], "global": { "device": "mcs51", "optimize-type": "speed", "specific-options": [ "--model-large" ] }, "c/cpp-compiler": { "language-c": "c99" }, "asm-compiler": {}, "linker": { "$mainFileName": "main" } } |

6. 设置烧录参数,F7 下载到芯片
烧录参数
1 2 3 | { "device": "auto" } |


7. 设置串口监视器波特率 9600,然后打开
如果一切连接正常,则会在串口完成温度、湿度信息的打印

工程已经打包为 EIDE 模板,已上传,可直接在 EIDE 上安装此项目