STM32+Proteus+DS18B20数码管仿真实验

1. 实验准备

  • 硬件方面
    • 了解 STM32 单片机的基本原理和使用方法,本实验可选用常见的 STM32F103 系列。
    • 熟悉 DS18B20 温度传感器的工作原理和通信协议(单总线协议)。
    • 数码管可选用共阴极或共阳极数码管,用于显示温度值。
  • 软件方面
    • 安装 Keil MDK 开发环境,用于编写和编译 STM32 的程序代码。
    • 安装 Proteus 仿真软件,用于搭建电路并进行仿真。

2. Proteus 电路搭建

  1. 打开 Proteus 软件 :新建一个工程,在元件库中搜索并添加以下元件:
    • STM32F103R6:作为主控芯片。
    • DS18B20:温度传感器。
    • 7SEG-MPX4-CC:4 位共阴极数码管。
    • 电阻、电容等辅助元件。
  2. 连接电路
    • DS18B20 连接:将 DS18B20 的 VDD 引脚连接到 3.3V 电源,GND 引脚接地,DQ 引脚连接到 STM32 的一个 GPIO 引脚(例如 PA0)。
    • 数码管连接:将数码管的段选引脚(a - g、dp)连接到 STM32 的一组 GPIO 引脚(例如 PB0 - PB7),位选引脚(COM1 - COM4)连接到另一组 GPIO 引脚(例如 PC0 - PC3)。
    • 电源和地:将 STM32 的 VDD 和 VSS 引脚分别连接到 3.3V 电源和地。

3. Keil MDK 代码编写

以下是一个

cs 复制代码
#include "stm32f10x.h"
#include <stdio.h>

// 定义 DS18B20 引脚
#define DS18B20_PORT GPIOA
#define DS18B20_PIN GPIO_Pin_0

// 定义数码管段选和位选端口
#define SEG_PORT GPIOB
#define DIG_PORT GPIOC

// 共阴极数码管段码表
const u8 SEG_CODE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

// 延时函数
void Delay(__IO uint32_t nCount) {
    for (; nCount != 0; nCount--);
}

// DS18B20 初始化
u8 DS18B20_Init(void) {
    u8 presence = 0;
    GPIO_InitTypeDef GPIO_InitStructure;

    // 配置 DS18B20 引脚为推挽输出
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);

    // 拉低总线 480 - 960us
    GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN);
    Delay(500);

    // 释放总线
    GPIO_SetBits(DS18B20_PORT, DS18B20_PIN);
    Delay(60);

    // 配置为浮空输入
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);

    // 检测存在脉冲
    if (!GPIO_ReadInputDataBit(DS18B20_PORT, DS18B20_PIN)) {
        presence = 1;
    }
    Delay(480);

    return presence;
}

// 向 DS18B20 写一个字节
void DS18B20_WriteByte(u8 dat) {
    u8 i;
    GPIO_InitTypeDef GPIO_InitStructure;

    // 配置为推挽输出
    GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);

    for (i = 0; i < 8; i++) {
        GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN);
        Delay(2);
        if (dat & 0x01) {
            GPIO_SetBits(DS18B20_PORT, DS18B20_PIN);
        } else {
            GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN);
        }
        Delay(60);
        GPIO_SetBits(DS18B20_PORT, DS18B20_PIN);
        dat >>= 1;
    }
}

// 从 DS18B20 读一个字节
u8 DS18B20_ReadByte(void) {
    u8 i, dat = 0;
    GPIO_InitTypeDef GPIO_InitStructure;

    for (i = 0; i < 8; i++) {
        // 配置为推挽输出
        GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);

        GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN);
        Delay(2);
        GPIO_SetBits(DS18B20_PORT, DS18B20_PIN);

        // 配置为浮空输入
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);

        if (GPIO_ReadInputDataBit(DS18B20_PORT, DS18B20_PIN)) {
            dat |= (0x01 << i);
        }
        Delay(60);
    }
    return dat;
}

// 读取 DS18B20 温度值
float DS18B20_ReadTemp(void) {
    u8 LSB, MSB;
    short temp;
    float temperature;

    if (DS18B20_Init()) {
        DS18B20_WriteByte(0xCC); // 跳过 ROM 操作
        DS18B20_WriteByte(0x44); // 启动温度转换
        Delay(750000); // 等待转换完成

        DS18B20_Init();
        DS18B20_WriteByte(0xCC); // 跳过 ROM 操作
        DS18B20_WriteByte(0xBE); // 读取温度寄存器

        LSB = DS18B20_ReadByte();
        MSB = DS18B20_ReadByte();

        temp = (MSB << 8) | LSB;
        temperature = (float)temp / 16.0;
    } else {
        temperature = -1;
    }
    return temperature;
}

// 数码管显示函数
void DisplayTemp(float temp) {
    u8 digit[4];
    u16 temp_int = (u16)(temp * 10);

    digit[0] = temp_int / 1000;
    digit[1] = (temp_int % 1000) / 100;
    digit[2] = (temp_int % 100) / 10;
    digit[3] = temp_int % 10;

    // 位选和段选
    for (int i = 0; i < 4; i++) {
        GPIO_ResetBits(DIG_PORT, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);
        GPIO_SetBits(DIG_PORT, GPIO_Pin_0 << i);
        GPIO_Write(SEG_PORT, SEG_CODE[digit[i]]);
        Delay(1000);
    }
}

int main(void) {
    float temperature;
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能 GPIOB 和 GPIOC 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);

    // 配置数码管段选引脚为推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SEG_PORT, &GPIO_InitStructure);

    // 配置数码管位选引脚为推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_Init(DIG_PORT, &GPIO_InitStructure);

    while (1) {
        temperature = DS18B20_ReadTemp();
        DisplayTemp(temperature);
    }
}

简单的示例代码,用于读取 DS18B20 的温度数据并显示在数码管上:

  1. 代码编译

4. 代码编译和仿真

编译代码 :在 Keil MDK 中,将上述代码保存为 .c 文件,进行编译,确保代码没有错误。

  1. 生成 hex 文件 :在 Keil MDK 的项目选项中,配置生成 .hex 文件。
  2. 加载 hex 文件 :在 Proteus 中,双击 STM32 芯片,在弹出的对话框中选择生成的 .hex 文件。
  3. 开始仿真:点击 Proteus 中的运行按钮,开始仿真。此时,数码管应该会显示 DS18B20 读取到的温度值。

5. 注意事项

  • 延时函数:在实际应用中,需要根据具体的系统时钟频率调整延时函数的参数,以确保 DS18B20 的通信正常。
  • 数码管驱动:数码管的驱动方式可以根据实际情况进行调整,例如使用动态扫描或静态显示。
  • 错误处理:在代码中添加适当的错误处理机制,以提高系统的稳定性。
相关推荐
小殷学长2 小时前
【单片机毕业设计17-基于stm32c8t6的智能倒车监测系统】
stm32·单片机·课程设计
TESmart碲视3 小时前
HKS201-M24 大师版 8K60Hz USB 3.0 适用于 2 台 PC 1台显示器 无缝切换 KVM 切换器
单片机·嵌入式硬件·物联网·游戏·计算机外设·电脑·智能硬件
花落已飘5 小时前
STM32中实现shell控制台(shell窗口输入实现)
stm32·单片机·嵌入式硬件
花落已飘5 小时前
STM32中实现shell控制台(命令解析实现)
stm32·shell
没有钱的钱仔5 小时前
STM32低功耗模式全面指南
css·stm32·css3
牵牛老人7 小时前
Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用
stm32·单片机·qt
宇钶宇夕8 小时前
针对工业触摸屏维修的系统指南和资源获取途径
单片机·嵌入式硬件·自动化
和风化雨8 小时前
stm32的三种开发方式
stm32·单片机·嵌入式硬件
kanhao1009 小时前
三态逻辑详解:单片机GPIO、计算机总线系统举例
单片机·嵌入式硬件
竹照煜_ysn11 小时前
STM32
stm32·单片机·嵌入式硬件