欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vscode 上使用 SDCC 工具链开发 8051(DHT11温湿度传感器示例)

程序员文章站 2022-03-21 12:42:00
...

使用 DHT11 温湿度传感器完成测量,并打印结果到串口;使用 SDCC 工具链编译


1. 下载并安装 SDCC,在 EIDE 上设置好安装路径

下载链接:SDCC
vscode 上使用 SDCC 工具链开发 8051(DHT11温湿度传感器示例)


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

vscode 上使用 SDCC 工具链开发 8051(DHT11温湿度传感器示例)


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 里的注释说明,这里不再阐述
vscode 上使用 SDCC 工具链开发 8051(DHT11温湿度传感器示例)


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"
    }
}

vscode 上使用 SDCC 工具链开发 8051(DHT11温湿度传感器示例)


6. 设置烧录参数,F7 下载到芯片

烧录参数

{
    "device": "auto"
}

vscode 上使用 SDCC 工具链开发 8051(DHT11温湿度传感器示例)
vscode 上使用 SDCC 工具链开发 8051(DHT11温湿度传感器示例)


7. 设置串口监视器波特率 9600,然后打开

如果一切连接正常,则会在串口完成温度、湿度信息的打印
vscode 上使用 SDCC 工具链开发 8051(DHT11温湿度传感器示例)


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

相关标签: EIDE 使用教程