嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记11:数字电位器MCP4017

系列文章目录

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记01:赛事介绍与硬件平台

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记02:开发环境安装

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记03:G4时钟结构

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记04:从零开始创建工程模板并开始点灯

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记05:Systick滴答定时器

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记06:按键输入

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记07:ADC模数转换

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记08:LCD液晶屏

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记09:EEPROM

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记10:USART串口通讯

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记11:数字电位器MCP4017


目录

系列文章目录

前言

一、电路原理

二、程序设计

三、ADC采样分压电压


前言

数字电位器MCP4017本质是一个IC器件,也就是说它是一个集成芯片,而板子上的蓝色旋转电位器R37、R38本质是一个电阻。数字电位器本质是一个芯片,但是内部有一个电阻网络,通过很多模拟开关来给电阻网络切换不同的阻值,我们是通过之前介绍过的I2C总线来给芯片发送数据,告诉芯片我要打开哪些模拟开关,从而控制它的阻值。

一、电路原理

首先我们看一下MCP4017,首先1号管脚接3.3V,2号管脚接GND,3、4管脚是I2C的通讯线,最重要的是5、6,数字电位器W、B两个管脚,5脚相当于是一个可变电阻的一端,另一端是悬空的,6脚相当于是可变电阻的滑片。

我们假设W滑到最左边,则5、6之间的电阻R_{WB}就等于AB之间整个电阻的总值R_{AB},如果滑到AB的中点,那么R_{WB}=\frac{1}{2}R_{AB},如果滑到B端,那么R_{WB}就约等于0。需要注意的是,芯片内部并不是这样的结构,而是一堆模拟开关实现了这样的功能。因为模拟开关本身是有阻值的,所以也会存在一些误差。

这个电位器的型号是104ELT(原理图可见),也就是说最多有10*10^4欧姆的电阻可调,即100kΩ

那么我们看电路图,W端接了一个10k的电阻接到3.3V,B端接地,很容易看出这是一个分压电路,那么我们很容易可以算出W端的电位:V=3.3\cdot \frac{R_{WB}}{R_{WB}+10}。而这个分压的电压V是接到了单片机的PB14这个口,PB14在STM32上也是一个ADC的输入口,所以我们可以通过ADC来采集这个电压的分压情况,从而可以知道WB之间的阻值变化。当然我们也可以设置好一个阻值,然后通过ADC来确认它的电压。

通过对这个电路的分析我们可知,我们实际上就是通过一个10k的电阻与一个数字电位器分压来得到PB14口的模拟输入。

那么我们接下来简单了解一下MCP4017这个芯片。可以看到它是一个7bit的支持IIC总线的数字电位器,并且拥有可变内存。SC70是它的封装。401系列还有4018、4019,其中4018一般用于分压器,4017、4019一般用于可变电阻,具体的我们就不去了解了。

 

  • 7bit是指它的电阻网络有7个位可以配置,也就是可以配置一共127个不同的阻值。因为总阻值是100kΩ,那么我们就可以把100k分成127个档
  • 抽头的电阻是100Ω,也就是说如果把WB短接,那也有100Ω的阻值(几乎可忽略)。
  • 低温漂:可变电阻的温漂是50ppm(百万分之50)。
  • 用IIC协议来读写。
  • 掉电时WB的电压不能超过1.5V。
  • 不编任何程序的话,它默认上电就是中间电压(50kΩ)。
  • 低功耗(2.5微安)
  • 电压工作范围:2.7V-5.5V。

还有一点就是芯片的存储形式是RAM,也就是说每次掉电都会清空,这就是为什么要规定默认上电时要中间电压。

除此之外比较重要的就是MCP4017的器件地址:0101111,还有一个R/W位,如果是写入的话,R/W就是0,加上器件地址就是01011110,即0x5e,如果是读就是0x5f

我们再看一下内部的电阻网络是怎么构成的。可以看到电阻网络还是挺简单的,我们甚至可以自己用电阻加模拟开关来构成一个类似的电路,当然,芯片帮我们集成好了用起来更方便。

可以看到每个Rs的电阻上都加了一个开关,每个开关上都有一个数,也就是说我们每往上增加一个数,就会增加一个Rs的电阻。Rs一共有127个,加起来等于100kΩ,这样我们可以算出Rs的值应该是0.7874kΩ。比方说:如果控制字节是0x7F,那么电阻就是100kΩ,如果控制字节是0x3F,就是中间位,即50kΩ,如果控制字节是0x00,那么电阻就是0(实际上是100Ω)。

二、程序设计

我们可以利用I2C总线控制数字电位器芯片的电阻值,与R17的10kΩ形成分压,这样PB14的电位就会发生相应的变化,再用ADC来进行读取。

这里我们先看一下怎么编程STM32来改变MCP4017的阻值。

程序流程:

  • 复制i2c的底层驱动文件到“编程工程”并改名
  • 在main.c调用i2c的IO初始化代码并包含头文件
  • 在i2c.c文件里编程:读写MCP4017函数,并在i2c.h中声明
  • 在main.c调用MCP4017_Write和MCP4017_Read完成程序

其中重点是MCP4017读写函数的编写,其他的部分我们在EEPROM里面已经做过了就不赘述了。我们这里主要看一下怎么编写MCP4017读写函数。下图是厂商芯片资料给的如何写一个字节数据的示例。

主器件就是我们的STM32,首先要发一个Start起始命令,然后发送从器件的地址+一个R/W位,因为是写数据,所以R/W位是0,所以是0x5E。然后等待应答。完成后,我们要送一个数据给MCP4017,送的数据就是我们要控制它的电阻的大小,它是一个7bit的控制字,就是0-0x7F的控制范围。主设备把这个字节发送过去,第一位用不到所以丢弃。然后等待应答。最后主器件再发一个终止命令STOP。

根据这个图我们很容易就可以写出MCP4017_Write()函数:

void MCP4018_Write(u8 val)
{I2CStart();I2CSendByte(0x5E);I2CWaitAck();I2CSendByte(val);I2CWaitAck();I2CStop();
}

读取函数我们一般用不到,因为我们只需要写入控制它的阻值就行了,并不需要读取现在阻值多少。比赛的时候也几乎很少遇到,但是最好还是学一下,也可以通过读取函数来判断是否成功写入,防止数据干扰。比方说可以写完之后读取一下,判断写的对不对,如果不对就再写一次。但是比赛中不需要这样。

u8 MCP4017_Read(void)
{u8 val;I2CStart();I2CSendByte(0x5F);I2CWaitAck();val=I2CReceiveByte();I2CSendNotAck();I2CStop();return val;
}

 还有一点就是,MCP4017两次写入之间是不需要延时的,不同于EEPROM。

三、ADC采样分压电压

MCP4017的W端接了一个PB14的管脚,并接在了ADC1的输入口上,所以我们可以用PB14来采样分压电压。

进入CubeMX开始配置引脚。可以看到PB14可以设置为ADC1的5通道,与PB12共用一个ADC,但是通道不同。我们把它设置为单端模式直接采集电压就行了。如果这部分内容还不清楚的话可以翻到之前的内容看一下ADC的讲解。

我们需要注意的是,ADC1现在有两个通道,那我们怎么告诉STM32现在要采集哪个通道呢?这边就有一个内容要在CubeMX上配置的,在ADC1的Configuration中有一个Number of Conversion也就是ADC转换的数量,这里要改成2。改完后下面有个Rank就自动变成2个了,并自动打开Scan conversion mode扫描转换模式,它会先转换一个通道的输入后再去转换另一个通道,转化的顺序就是由Rank决定,Rank1就是第一个被转换的通道,我们可以在Rank里面选择,并且这里我们可以调整它的采样速度Sampling Time(采样时间)。注意,多通道采集的时候,采样速度最好不要太快,否则会容易出错,所以我们可以把采样速度调的慢一点,这里我们调640.5个周期。

再把Rank1设置为通道5,Rank2设置为通道11。

生成代码,我们可以看到ADC1的初始化定义里面已经有了要转换的通道数量为2,和不同Rank对应的通道。

我们已经有了之前的ADC的程序,现在在此基础上增加ADC1通道5的内容。(如果没有的话就自己写一下,配置ADC的教程在前面有,写完记得初始化一下,有的时候程序写完了发现运行不对有可能就是忘了初始化)

我们定义一个变量volt_mcp来表示通过mcp采集到的电压值。

因为我们定义的Rank1是采集mcp,也就是先采集mcp再采集R37,所以我们是在采集R37的程序前面添加采集mcp的程序。

u16 adc1_val,adc2_val;
float volt_r37,volt_r38,volt_mcp;
void ADC_Process(void)
{//rank1HAL_ADC_Start(&hadc1);volt_mcp = HAL_ADC_GetValue(&hadc1)/4095.0f*3.3f;//rank2HAL_ADC_Start(&hadc1);adc1_val = HAL_ADC_GetValue(&hadc1);volt_r37 = adc2_val/4095.0f*3.3f;HAL_ADC_Start(&hadc2);adc2_val = HAL_ADC_GetValue(&hadc2);volt_r38 = adc1_val/4095.0f*3.3f;
}

这样就完成了ADC1先采集通道5,再采集通道11的过程,需要注意的是,我们并不需要手动切换采集通道,只需要再调用一次HAL_ADC_Start()函数就可以自动切换通道了,这是因为我们之前配置了扫描转换,正因如此,我们在编写程序的时候一定要注意采样的顺序!

我们可以调用一下前面写好的MCP4017_Write(),然后写入0x3F,也就是中位点。设置好电阻后在主循环中调用ADC采样函数就可以看一下现在的分压电压了。

int main()
{MCP4017_Write(0x3F);while(1);{ADC_Process();}
}

我们可以写个LCD显示函数来看一下此时volt_mcp的值,这里就跳过了。显示出来的值应该是2.7左右。如果输入0x7F的话,输出应该是2.95左右。

如果之前没有现成的ADC程序的话,我们总结一下利用ADC1双通道采集的程序设计步骤:

  • 用给的“模版”生成代码
  • 设置ADC相关的GPIO为输入模式,并设置成单端模式。(PB15、PB12、PB14)
  • 设置ADC1的转换的通道数(number of conversion)为2,并设置Rank和采集速度。
  • 添加ADC相关的HAL库驱动文件
  • 包含ADC的头文件,并初始化ADC(如果是移植代码的话要初始化外设时钟)
  • 利用HAL_ADC_Start和HAL_ADC_GetValue编写程序(双通道要调用两次Start)

总结

这节课主要是学习如何使用MCP4017数字电位器,它需要通过I2C总线进行通信,利用I2C向其内部写入数据从而控制它的内部电阻大小,并且外部接了一个分压电路,并把分压电压作为ADC的输入采样,从而转化成数字量被我们读取。所以这一节的内容需要结合I2C总线和ADC这两部分内容一起来学习的。其中最重要的内容是MCP4017读写函数的编写ADC的双通道采集这两部分内容,比赛时是需要自己编写的,需要牢记。此外,还需要记得ADC的采样Rank和采样速度。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一周是一年的2%

今天读到阮一峰的293期周刊,其中有句话很让我震动——“一周是一年的2%”。 过去的时间里,我都没有在意时间的流逝,过的好的时候就觉得一周过的好快,周三一过这周也就过去了,过的不好的时候就感觉很漫长。 确实&…

C# wpf 嵌入hwnd窗口

WPF Hwnd窗口互操作系列 第一章 嵌入Hwnd窗口(本章) 第二章 嵌入WinForm控件 第三章 嵌入WPF控件 文章目录 WPF Hwnd窗口互操作系列前言一、如何实现1、继承HwndHost2、实现抽象方法3、xaml中使用HwndHost控件 二、具体实现1、Win32窗口2、HwndSource窗…

【Python】搭建 Python 环境

目 录 一.安装 Python二.安装 PyCharm 要想能够进行 Python 开发,就需要搭建好 Python 的环境 需要安装的环境主要是两个部分: 运行环境: Python开发环境: PyCharm 一.安装 Python (1) 找到官方网站 (2) 找到下载页面 选择 “Download for Windows”…

PHPCMS v9城市分站插件

PHPCMS自带的有多站点功能,但是用过的朋友都知道,自带的多站点功能有很多的不方便之处,例如站点栏目没法公用,每个站点都需要创建模型、每个站点都需要单独添加内容,还有站点必须静态化。如果你内容很多这些功能当然无…

Unity VisionOS开发流程

Unity开发环境 Unity Pro, Unity Enterprise and Unity Industry 国际版 Mac Unity Editor(Apple silicon) visionOS Build Support (experimental) 实验版 Unity 2022.3.11f1 NOTE: 国际版与国服版Pro账通用,需要激活Pro的许可证。官方模板v0.6.2,非Pro版本会打…

安科瑞智慧安全用电综合解决方案

概述 智慧用电管理云平台是智慧城市建设的延伸成果,将电力物联网技术与云平台的大数据分析功能相结合,实现用电信息的可视化管理,可帮助用户实现安全用电,节约用电,可靠用电。平台支持web,app,微…

【回眸】Tessy 单元测试软件使用指南(三)怎么打桩和指针赋值和测试

目录 前言 Tessy 如何进行打桩操作 普通桩 高级桩 手写桩 Tessy单元测试之指针相关测试注意事项 有类型的指针(非函数指针): 有类型的函数指针: void 类型的指针: 结语 前言 进行单元测试之后,但凡…

zookeeper面试题

文章目录 ZooKeeper 是什么?ZooKeeper 提供什么?1. 文件系统2. 通知机制 ZooKeeper 文件系统四种类型的 znode1. PERSISTENT (持久化目录节点)2. PERSISTENT_SEQUENTIAL (持久化顺序编号目录节点)3. EPHEMERAL (临时目录节点)4. EPHEMERAL_SEQUENTIAL (临…

C语言------指针(2)

前面已经向大家介绍了指针的一些基本内容,接下来,就在再我来先大家讲解一下指针的其他内容。 1. 数组名的理解 int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; 在学习数组的过程中,我们肯定会写过以上代码,我们知道 int 是该数组的数…

【C语言】C语言运算符优先级详解

文章目录 📝前言🌉运算符优先级简述 🌠逻辑与和逻辑或🌉赋值和逗号运算符 🌠位运算🌉条件表达式🌉位运算与算术运算结合🌉混合使用条件表达式和赋值运算符🌉 逗号运算符的…

UE5、CesiumForUnreal实现海量POI撒点显示与聚合功能

1.实现目标 POI是UE+GIS三维场景中经常需要展示的要素,在UE中常用的表示POI方法有两种。一种是Mesh,即空间的方式;另一种是Widget,即屏幕上的方式,本文这里使用的是Widget屏幕展示的形式来表示POI。 本文这里使用的POI点位数量共3.3w+,采用直接网格聚合算法,并进行性能优…

Chrome/Edge 使用 Markdown Viewer 查看 Markdown 格式文件

Chrome/Edge 使用 Markdown Viewer 查看 Markdown 格式文件 0. 引言1. 安装 Markdown Viewer 插件2. 使用 Markdown Viewer 阅读 Markdown 格式文件 0. 引言 大部分程序员都喜欢 Markdown 格式的文件,这时给一些没有在电脑上安装 Markdown 编辑器的同事分享资料时&…

苹果与百度合作,将在iPhone 16中使用生成式AI

3月25日,《科创板日报》消息,苹果将与百度进行技术合作,为今年即将发布的iPhone16、Mac系统和iOS 18提供生成式AI(AIGC)功能。 据悉,苹果曾与阿里巴巴以及另外一家国产大模型厂商进行了技术合作洽谈。最终…

[自研开源] 数据集成之分批传输 v0.7

开源地址:gitee | github 详细介绍:MyData 基于 Web API 的数据集成平台 部署文档:用 Docker 部署 MyData 使用手册:MyData 使用手册 试用体验:https://demo.mydata.work 交流Q群:430089673 介绍 本篇基于…

Hana数据库 No columns were bound prior to calling SQLFetch or SQLFetchScroll

在php调用hana数据库的一个sql时报错了&#xff0c;查表结构的sql&#xff1a; select * from sys.table_columns where table_name VBAP SQLSTATE[SL009]: <<Unknown error>>: 0 [unixODBC][Driver Manager]No columns were bound prior to calling SQLFetch …

55、Qt/事件机制相关学习20240326

一、代码实现设置闹钟&#xff0c;到时间后语音提醒用户。示意图如下&#xff1a; 代码&#xff1a; #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), speecher(new QTextToSpeech(t…

canvas跟随鼠标画有透明度的矩形边框

提示&#xff1a;canvas跟随鼠标画有透明度的矩形边框 文章目录 前言一、跟随鼠标画有透明度的矩形边框总结 前言 一、跟随鼠标画有透明度的矩形边框 test.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&…

【笔记】OpenHarmony设备开发:搭建开发环境(Ubuntu 20.04,VirtualBox 7.0.14)

参考&#xff1a;搭建开发环境&#xff08;HarmonyOS Device&#xff09; Note&#xff1a;Windows系统虚拟机中Ubuntu系统安装完成后&#xff0c;根据指导完成Ubuntu20.04基础环境配置&#xff08;HarmonyOS Connect 开发工具系列课&#xff09; 系统要求 Windows系统要求&…

Python包管理工具 pip 及其常用命令和参数用法

目录 PIP 主要功能 安装包 升级包 卸载包 列出包 检查依赖 pip的配置和环境 主要用法 1&#xff1a;版本 2&#xff1a;安装 Python 库 3&#xff1a;升级库 4&#xff1a;卸载库 5&#xff1a;搜索库 6&#xff1a;查看已安装库详细信息 7&#xff1a;只下载库…

MT6762_联发科MTK6762安卓核心板规格参数

MTK6762核心板是一款集成了蓝牙、fm、wlan和gps模块的高度集成基带平台&#xff0c;为LTE/LTE-A和C2K智能手机应用程序提供支持。该安卓核心板集成了ARM Cortex-A53处理器&#xff0c;工作频率可达2.0GHz&#xff0c;并且还集成了功能强大的多标准视频编解码器。除此之外&#…