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

news2025/2/21 0:37:44

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 代码编写

以下是一个

#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 的温度数据并显示在数码管上:

4. 代码编译

4. 代码编译和仿真

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

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

5. 注意事项

  • 延时函数:在实际应用中,需要根据具体的系统时钟频率调整延时函数的参数,以确保 DS18B20 的通信正常。
  • 数码管驱动:数码管的驱动方式可以根据实际情况进行调整,例如使用动态扫描或静态显示。
  • 错误处理:在代码中添加适当的错误处理机制,以提高系统的稳定性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2297889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vulhub靶机 ActiveMQ 反序列化漏洞(CVE-2015-5254)(渗透测试详解)

一、开启vulhub环境 docker-compose up -d 启动 docker ps 查看开放的端口 漏洞版本&#xff1a;Apache ActiveMQ 5.x ~ Apache ActiveMQ 5.13.0 二、访问靶机IP 8161端口 默认账户密码 admin/admin&#xff0c;登录 此时qucues事件为空 1、使用jmet-0.1.0-all.jar工具将…

2025年二级建造师报名流程图解

2025年二级建造师报名时间&#xff01;附报名流程&#xff01; ⏰️已公布25年二建考试时间的省份如下&#xff1a; ️4月19日、20日考试的城市有&#xff1a;贵州 ️5月10日、11日考试的城市有&#xff1a;湖北、陕西、宁夏、甘肃、福建、浙江、江西、黑龙江、河南、湖南、…

hexo 魔改 | 修改卡片透明度

hexo 魔改 | 修改卡片透明度 ** 博客食物用更佳 博客地址 ** 这是笔者自己瞎倒腾的。作为前端菜鸡一枚&#xff0c;大佬们随便看看就好~ 我用的主题是 butterfly 4.12.0 分析 通过开发者工具可以看出来卡片的背景和 --card-bg 变量有关 再在 sources 下的 css 文件夹下的…

Golang的并发编程案例详解

Golang的并发编程案例详解 一、并发编程概述 并发编程是指程序中有多个独立的执行线索&#xff0c;并且这些线索在时间上是重叠的。在 Golang 中&#xff0c;并发是其核心特性之一&#xff0c;通过 goroutine 和 channel 来支持并发编程&#xff0c;使得程序可以更高效地利用计…

策略模式-小结

总结一下看到的策略模式&#xff1a; A:一个含有一个方法的接口 B:具体的实行方式行为1,2,3&#xff0c;实现上面的接口。 C:一个环境类&#xff08;或者上下文类&#xff09;&#xff0c;形式可以是&#xff1a;工厂模式&#xff0c;构造器注入模式&#xff0c;枚举模式。 …

硬件学习笔记--41 电磁兼容试验-5 射频场感应的传导干扰试验介绍

目录 电磁兼容试验-射频场感应的传导干扰试验介绍 1.试验目的 2.试验方法 3.判定依据及意义 电磁兼容试验-射频场感应的传导干扰试验介绍 驻留时间是在规定频率下影响量施加的持续时间。被试设备&#xff08;EUT&#xff09;在经受扫频频带的电磁影响量或电磁干扰的情况下&a…

泛型 类 接口 方法 通配符

泛型 泛型类 what: 类型参数化 why use&#xff1a; 1. 输出时候是object类型 而不是真正类型转化麻烦 import java.util.ArrayList; import java.util.List;public class ObjectExample {public static void main(String[] args) {List<Object> list new ArrayLi…

文字转语音(三)FreeTTS实现

项目中有相关的功能&#xff0c;就简单研究了一下。 说明 FreeTTS 是一个基于 Java 的开源文本转语音&#xff08;TTS&#xff09;引擎&#xff0c;旨在将文字内容转换为自然语音输出。 FreeTTS 适合对 英文语音质量要求低、预算有限且需要离线运行 的场景&#xff0c;但若需…

STM32 RTC 实时时钟说明

目录 背景 RTC(实时时钟)和后备寄存器 32.768HZ 如何产生1S定时 RTC配置程序 第一次上电RTC配置 第1步、启用备用寄存器外设时钟和PWR外设时钟 第2步、使能RTC和备份寄存器访问 第3步、备份寄存器初始化 第4步、开启LSE 第5步、等待LSE启动后稳定状态 第6步、配置LSE为…

Open-R1 项目代码文件的详细剖析

目录 1. configs.py 功能概述 关键代码与细节 2. evaluate.py 功能概述 关键代码与细节 3. generate.py 功能概述 关键代码与细节 4. grpo.py 功能概述 关键代码与细节 5. rewards.py 功能概述 关键代码与细节 6. sft.py 功能概述 关键代码与细节 安装 训练…

Android RenderEffect对Bitmap高斯模糊(毛玻璃),Kotlin(1)

Android RenderEffect对Bitmap高斯模糊(毛玻璃)&#xff0c;Kotlin&#xff08;1&#xff09; import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.HardwareRenderer import android.graphics.PixelFormat import android.graphic…

区块链+隐私计算:长安链多方计算合约标准协议(CMMPC-1)发布

建设背景 长安链与隐私计算的深度融合是构建分布式数据与价值流通网络的关键基石&#xff0c;可以在有效连接多元参与主体的同时确保数据的分布式、可追溯、可计算&#xff0c;以及隐私性与安全性。在长安链与隐私计算的融合实践中&#xff0c;开源社区提炼并抽象出多方计算场…

#渗透测试#批量漏洞挖掘#Crocus系统—Download 文件读取

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

LabVIEW用户界面设计原则

在LabVIEW开发中&#xff0c;用户界面&#xff08;UI&#xff09;设计不仅仅是为了美观&#xff0c;它直接关系到用户的操作效率和体验。一个直观、简洁、易于使用的界面能够大大提升软件的可用性&#xff0c;尤其是在复杂的实验或工业应用中。设计良好的UI能够减少操作错误&am…

MySQL8.0 innodb Cluster 高可用集群部署(MySQL、MySQL Shell、MySQL Router安装)

简介 MySQL InnoDB集群&#xff08;Cluster&#xff09;提供了一个集成的&#xff0c;本地的&#xff0c;HA解决方案。Mysq Innodb Cluster是利用组复制的 pxos 协议&#xff0c;保障数据一致性&#xff0c;组复制支持单主模式和多主模式。 InnoDB Cluster组件&#xff1a; …

Effective Objective-C 2.0 读书笔记——内存管理(上)

Effective Objective-C 2.0 读书笔记——内存管理&#xff08;上&#xff09; 文章目录 Effective Objective-C 2.0 读书笔记——内存管理&#xff08;上&#xff09;引用计数属性存取方法中的内存管理autorelease保留环 ARCARC必须遵循的方法命名原则ARC 的自动优化&#xff1…

软件测试覆盖率详解

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、覆盖率概念 覆盖率是用来度量测试完整性的一个手段&#xff0c;是测试技术有效性的一个度量。分为&#xff1a;白盒覆盖、灰盒覆盖和黑盒覆盖&#xff1b;测…

控制玉米株高基因 PHR1 的基因克隆

https://zwxb.chinacrops.org/CN/10.3724/SP.J.1006.2024.33011

windows10本地的JMeter+Influxdb+Grafana压测性能测试,【亲测,避坑】

一、环境&#xff0c;以下软件需要解压、安装到电脑上。 windows10 apache-jmeter-5.6.3 jdk-17.0.13 influxdb2-2.7.11 grafana-enterprise-11.5.1二、配置Influxdb&#xff0c;安装完默认连接http://localhost:8086/。打开连接&#xff0c;配置如下。 开启Influxdb&#xf…