vscode 上使用 SDCC 工具链开发 8051(DHT11温湿度传感器示例)
程序员文章站
2022-03-21 12:42:00
...
使用 DHT11 温湿度传感器完成测量,并打印结果到串口;使用 SDCC 工具链编译
1. 下载并安装 SDCC,在 EIDE 上设置好安装路径
下载链接:SDCC
2. 使用 EIDE 新建一个 C51 项目
3. 编写代码
main.c
#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
#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
#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
#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
#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
#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 开始编译
{
"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 下载到芯片
烧录参数
{
"device": "auto"
}
7. 设置串口监视器波特率 9600,然后打开
如果一切连接正常,则会在串口完成温度、湿度信息的打印
工程已经打包为 EIDE 模板,已上传,可直接在 EIDE 上安装此项目
下一篇: 支付宝如何开通享攒钱?