【STC8A8K64D4开发板】第2-17讲:PCA实现数模转换(DAC)

news2024/9/22 23:24:04

第2-17讲:PCA实现数模转换(DAC)

    1. 学习目的
  1. 了解DAC数模转换原理及RC积分电路原理。
  2. 掌握STC8A8K64D4系列单片机实现DAC功能的硬件和软件设计。
    1. DAC简介

DAC (全称是Digital to Analog Convertor)数模转换器是一种将数字信号转换为模拟信号(以电流、电压或)的设备或电路。在很多数字系统中(例如计算机、单片机),信号以数字方式(0或者1)存储和传输,而数模转换器DAC可以将这样的信号转换为模拟信号,从而使得他们能够被外界(人或其他非数字系统)识别。数模转换器DAC的常见用法是在音乐播放器中将数字形式存储的音频信号输出为模拟的声音。

T型电阻网络方式是一种常见的DAC实现方法,由T型电阻网络和运算放大器组成,下图是8位DAC的原理示意图。输入数字量中的每位都按其权值分别转换为模拟量,之后通过运算放大器求和相加。

图1:T型电阻网络示意图

上图中,由于运算放大器的反相输入端为“虚地”,所以无论模拟开关连接到“0”还是 “1”,从T形电阻网络节点对“地”往右看的等效电阻均为R,由此可计算出基准电流I=VREF/R。再根据电流可计算出流过各个分支的电流从右向左(I0~I7)依次是I/2、I/4、I/8、I/16、I/32、I/64、I/128和、I/256。

由此,每一位数字量都发挥了有效的位权,流向运算放大器反相输入端的总电流如下: 

该电流经过运算放大器换成模拟电压输出,从而实现由数字信号到模拟信号的转换。这里以8位DAC示例,输出电压有256种变化,当然,这种T形电阻网络的转换原理可以推广到n位,实现n位DAC。

市面上很多单片机片内集成了DAC外设,并且也有专用独立DAC芯片供用户选择使用,那为什么还需要使用PWM实现DAC?

这是因为虽然市面上很多集成了DAC的单片机和独立DAC芯片,他们使用起来更方便,并且精度也高,但是很多时候,我们并不需要很高的精度,我们选择使用的单片机可能没有DAC外设,但是一般都有PWM,因此,出于对成本的考虑,我们会使用PWM实现DAC,从而节省成本。

    1. 硬件电路设计

STC8A8K64D4系列单片机片内没有集成DAC外设,因此,IK-64D4开发板通过PCA工作于PWM模式输出高速PWM脉冲配合RC滤波电路实现DAC功能。

实现DAC转换是基于将高速PWM信号通过RC电路整合成比较平缓的电压信号作为模拟输出,通过改变高速PWM信号的占空比达到改变输出电平信号幅度的目的。为了达到比较理想的电压信号输出,P7.0口输出的PWM信号经二阶RC滤波电路整合,如下图所示。

图2:PWM实现DAC电路

  • 注:开发板J27端子需使用短路帽短接P06和DAC_O以及P70和DAC_I,并且将J27端子的P06和ADC以及P70和DHT11的短路帽去掉。

    1. 软件设计
      1. PWM实现DAC实验
  • 注:本节的实验是在“实验2-11-1:ADC采样电位器电压(查询方式)”的基础上修改,本节对应的实验源码是:“实验2-17-1: PWM实现DAC实验”。
  • 关于PWM的内容,读者可以参阅《第2-16讲:可编程计数器阵列PCA》中的PCA实现PWM部分的内容。
        1. 实验内容

配置PCA模块0工作于PWM模式, PCA配置如下:

  1. 系统时钟:24MHz。
  2. PCA时钟源:系统时钟= 24Mhz。
  3. 功能引脚:P7.0。
  4. 中断:不开启中断。
  5. PWM位数:8位。

程序运行后,在主循环中不断改变PWM的占空比,从而改变P7.0输出的电压值。实验中为了方便观察实验现象,配置P0.6为ADC功能引脚,并通过跳线帽将其连接到DAC电路的输出端,这样,就可以实时获取DAC输出的电压值并通过串口输出,以便于我们观察实验现象(DAC输出电压值的改变)。

        1. 代码编写
  1. 新建一个名称为“pca.c”的文件及其头文件“pca.h”并保存到工程的“Source”文件夹,并将“pca.c”加入到Keil工程中的“SOURCE”组。
  2. 引用头文件

因为在“pca.c”文件中使用了“pca.c”文件中的函数,所以需要引用下面的头文件“pca.h”。

代码清单:引用头文件

  1. //引用pca的头文件  
  2. #include   " pca.h"  
  1. PCA初始化

本例中,我们配置PCA模块0工作于PWM模式,PCA时钟源使用系统时钟(24Mhz),功能引脚为P7.0,代码清单如下。

代码清单:PCA初始化

  1.  /*************************************************************************** 
  2.  * 描  述 : PCA初始化 
  3.  * 入  参 : 无 
  4.  * 返回值 : 无 
  5.  **************************************************************************/  
  6. void pca_init(void)  
  7. {  
  8.    CCON = 0x00;        //CF、CR、CCF1、CCF0位均清零  
  9.        
  10.    P_SW1 &= 0xEF;      //PCA模块0功能引脚选择P7.0              
  11.    P_SW1 |= 0x20;                    
  12.    /*--------------------PCA模式寄存器CMOD配置--------------------------- 
  13.      位7  位6  位5  位4   位3~位1    位0 
  14.      CIDL   x    x    x    CPS[2~0]    BCF 
  15.       0     x    x    x      100       0 
  16.      
  17.     CIDL=0:空闲模式下仍然计数 
  18.     CPS[2~0]=100:PCA时钟源选择:系统时钟 
  19.     BCF=0:禁止PCA计数器溢出中断 
  20.    -----------------------------END------------------------------------*/  
  21.    CMOD = 0x08;   
  22.    CL = 0x00;          //PCA计数器赋初值  
  23.    CH = 0x00;          //PCA计数器赋初值  
  24.       
  25.    IP &= ~0x02;        //中断优先级配置为2(较高优先级)    
  26.    IPH |= 0x02;  
  27.     /*------------------PCA模块0模式控制寄存器CCAPM0配置------------------ 
  28.     位7   位6    位5    位4     位3    位2   位1    位0 
  29.      x   ECOM0  CCAPP0  CCAPN0   MAT0   TOG0  PWM0   ECCF0 
  30.      x     0      0       0       0      0     1       0  
  31.      
  32.     ECOM0=0:关闭PCA模块0的比较功能 
  33.     CCAPP0=0:关闭PCA模块0的上升沿捕获 
  34.     CCAPN0=0:关闭PCA模块0的下降沿捕获 
  35.     MAT0=0:关闭PCA模块0的匹配功能 
  36.     TOG0=0:关闭PCA模块0的高速脉冲输出功能 
  37.     PWM0=1:开启PCA模块0的脉宽调制输出功能 
  38.     ECCF0=0:禁止PCA模块0的匹配/捕获中断 
  39.    -----------------------------END------------------------------------*/
  40.    CCAPM0 = 0x02;
  41.       
  42.    PCA_PWM0 &= 0x3F;               //PCA模块0工作于8位PWM功能  
  43.    PCA_PWM0 &= 0xFC;               //EPC0H位和EPC0L位置0  
  44.    CCAP0L = 0x00;            //PCA比较值寄存器赋初值        
  45.    CCAP0H = 0x00;            //PCA比较值寄存器赋初值   
  46.    CR = 1;                   //启动PCA计数器阵列计数    
  47. }  
  1. 主函数

主函数中初始化PCA和ADC,PCA计数启动后,在主循环中不断改变PWM的占空比,使得DAC输出不同的电压。

ADC采样DAC输出的电压值后,通过串口输出采样值及其对应的电压值,代码清单如下。

代码清单:主函数

  1. /*************************************************************************** 
  2.  * 描  述 : 主函数 
  3.  * 入  参 : 无 
  4.  * 返回值 : 无 
  5.  **************************************************************************/  
  6. int main(void)  
  7. {  
  8.    u16 adc_value;  //存放ADC采样值  
  9.    float voltage;  //存放ADC采样值计算后的电压值  
  10.    u16 TempData;  
  11.       
  12.    P2M1 &= 0xBF;   P2M0 &= 0xBF;     //设置P2.6为准双向口(LED1)  
  13.    P3M1 &= 0xFE;   P3M0 &= 0xFE;     //设置P3.0为准双向口(串口1的RxD)  
  14.    P3M1 &= 0xFD;   P3M0 |= 0x02;     //设置P3.1为推挽输出(串口1的TxD)  
  15.    P7M1 &= 0xFE;   P7M0 |= 0x01;     //设置P7.0为推挽输出  
  16.       
  17.    pca_init();  
  18.    uart1_init();                 //串口1初始化  
  19.    adc_config();                 //初始化ADC    
  20.    EA = 1;                       //使能总中断  
  21.       
  22.    while(1)  
  23.    {  
  24.       TempData++;  
  25.       CCAP0H = (u8)(256 - TempData);      //P7.0引脚输出频率不变但占空比不断变化的脉冲信号  
  26.       if(TempData>138)TempData=1;          //占空比达到很大时重新设定占空比
  27.       delay_ms(5);   
  28.       adc_value = get_adc_value();                  //读取ADC采样值  
  29.       voltage   = (2.5*adc_value)/4096;               //将ADC采样值转换为电压(单位V)  
  30.       printf("ADC采样值: %d\r\n",adc_value);       //串口打印上传的采集的原始值  
  31.       printf("采样值对应的电压:%.2fV\r\n",voltage);//串口打印ADC采样电压  
  32.       delay_ms(200);                                //延时200ms,方便观察数据  
  33.       led_toggle(LED_1);  //翻转指示灯D1状态,指示一次ADC采样完成  
  34.    }  
  35. }  
        1. 硬件连接

本实验通过P7.0输出PWM信号实现DAC输出,P0.6配置为ADC用于采样DAC电路输出的电压,按照下图所示连接跳线帽。

图3:硬件连接

        1. 实验步骤
  1. 解压“…\第3部分:配套例程源码”目录下的压缩文件“实验2-17-1: PWM实现DAC实验”,将解压后得到的文件夹拷贝到合适的目录,如“D\STC8”(这样做的目的是为了防止中文路径或者工程存放的路径过深导致打开工程出现问题)。
  2. 双击“…\pca_dac\project”目录下的工程文件“pca_dac.uvproj”。
  3. 点击编译按钮编译工程,编译成功后生成的HEX文件“pca_dac.hex”位于工程的“…\pca_dac\Project\Object”目录下。
  4. 打开STC-ISP软件下载程序,下载使用内部IRC时钟,IRC频率选择:24MHz。
  5. 电脑上打开串口调试助手,选择开发板对应的串口号,将波特率设置为9600bps。程序运行后,在串口接收窗口可以看到开发板上报的ADC采样值及其对应的电压值,如下图所示。

图4:串口调试助手中观察电压值

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

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

相关文章

vue3+threejs新手从零开发卡牌游戏(七):创建卡组

在开始前先优化下之前的代码: 在之前hand/p1.vue中为了定位 utils文件夹下新建common.ts,将一些公用方法提取出来放在这里: 在game/Cards.ts中,我们调整下卡牌的厚度,由原来的0.02改为0.005,原因是之前的…

ZHUTI主提2024夏季系列 —「逐·行」

ZHUTI主提全新发布2024夏季「逐行」系列,聚焦当下人与自然的关系,以衣为载体,秉承东方哲学的艺术理念,将美学艺术与主流时尚设计融合,赋予当代时装表达新方向,共创现代女性之美。 取自然之意境&#xff0c…

开发调试、远程访问、内网穿透解决方案集合

开发调试、远程访问、内网穿透解决方案集合 前言Cpolar下载安装配置与使用 Ngrok购买隧道下客户端配置与使用 ZeroTier注册与安装创建虚拟网络加入虚拟网络配置授权 花生壳Centos系统Ubuntu系统使用花生壳控制台SN码登录添加映射 Loophole通过CLI方式安装登录与注销简单使用身份…

数据结构--链表刷题(一)快慢指针

1.快慢指针 先看一道简单的题目:返回中间结点 这道题有一个最朴素的做法就是先遍历一边链表,设置计数器求出链表长度,再重新走1/2的链表长度,即可返回中间节点 // 第二种解法 //这种解法需要遍历两次链表ListNode cur1 head;int…

适用于vue3的vant4组件 没有日期时间选择器

项目中需要用到日期和时间一同选择的场景 本来想用 如下代码 van-datetime-picker 发现咋整也不好使 刚开始还以为是引入的问题 后来发现是vant4根本就没这玩应了… <van-datetime-pickerv-model"currentDate"type"datetime"title"选择完整时间&q…

PagePlug多条件查询方案

正确实现 使用Case When来编写查询条件 SELECT * FROM pc_ticket_tax_cloud WHERE 11 AND (CASE WHEN {{data_table.searchText ! }} THEN xsddm like {{data_table.searchText || ""}}%ELSE 11 END ) AND (CASE WHEN {{doc_code_input.text ! }} THEN doc_code li…

程序猿成长之路之番外篇——矩阵算法

今天在复习线性代数知识的过程中&#xff0c;用java语言简单实现了一下矩阵算法。 数学知识回顾 1.什么是矩阵 在数学领域&#xff0c;矩阵就像一个表格&#xff0c;将数据排放进去&#xff0c;形成一个矩形。我们习惯用一个大括号把矩阵内的数据包括进来。 1.矩阵 在数学领域…

superset 二开增加 flink 数据源连接通过flink sql 查询数据

前言 superset 目前还不支持 flink 的数据源连接&#xff0c;目前我们公司在探索使用数据湖那一套东西&#xff1a; 使用 flink 作为计算引擎使用 paimon oss对象存储对接 flink 作为底层存储使用 superset 通过 flink gateway 查询 paimon 数据形成报表 增加flink数据源 …

Linux--进程(1)

目录 前言 1.冯诺依曼体系结构 2. 操作系统(Operator System)--第一个被加载的软件 3.进程 3.1基本概念 3.2Linux中的PCB 3.3通过系统调用创建子进程-fork初识 fork&#xff1a;创建一个子进程 为什么要创建子进程&#xff1f; fork的原理&#xff1a; 进一步了解fo…

黄仁勋对话Transformer七位作者:今天发生的一切都可以追溯到那一刻

关注文章底部的公众号,获取每日AI最新新闻 获取每日资讯 本周三,关于Transformer神经网络架构的开创性研究论文《Attention Is All You Need》作者们在GTC上齐聚一堂。 在GTC的900多个会议中,最受欢迎的是由NVIDIA创始人兼首席执行官黄仁勋主持的与传奇论文七位作者的交流。…

手上积累了一些企业目录,但是没有电话,在企XX天X查也没找到咋办?如何快速精准批量查询其他平台上查不到的企业电话?

在B端业务场景中&#xff0c;长期需要进行拓客。有时候是企业提供客户的联系方式&#xff0c;有时候是销售利用自己的人脉资源&#xff0c;对于资源不多的销售就需要查找到目标客户的联系方式。长期来说&#xff0c;销售都需要进行拓客&#xff0c;自己通过社交&#xff0c;网络…

ATA-5310前置微小信号放大器在红外线传感器中的应用

当涉及到红外线传感器时&#xff0c;前置微小信号放大器扮演着关键的角色。红外线传感器是一种用于探测和测量红外辐射的设备&#xff0c;它们通常用于热成像、物体检测、温度测量、动作检测等应用中。前置微小信号放大器在红外线传感器中的应用具有重要意义&#xff0c;下面将…

Vue js封装接口

天梦星服务平台 (tmxkj.top)https://tmxkj.top/#/ 1.安装axios npm install axios -g 2.在src下新建一个Api文件夹,再创建一个js文件 import axios from axios let configuration {url:"http://localhost:9090" } /*** 请求项目数据的请求体*/ async function h…

从错误中进行上下文学习

1、写作动机&#xff1a; 在上下文学习中&#xff0c;也称为少样本提示&#xff08;ICL&#xff09;&#xff0c;一直是调整LLM适应下游任务的标准方法&#xff0c;通过从少量输入-输出示例中学习。然而&#xff0c;所有基于ICL的方法都只从正确的输入-输出对中学习。 2、主要…

C++的内存管理

目录 1. C/C内存分布 2. C语言中动态内存管理方式 3. C内存管理方式 3.1 new/delete操作内置类型 4. operator new与operator delete函数 4.1 连续开辟空间(尽力了解) 5. new和delete的实现原理 5.1 内置类型 5.2 自定义类型 6. 深入理解 6.1malloc/free和new/delete的区…

探索多视角驱动的层次内容感知网络用于指静脉识别

文章目录 探索多视角驱动的层次内容感知网络用于指静脉识别总结摘要介绍相关工作多视角方法长短时记忆基于视角的目标表达 方法全局主干网络局部感知模块损失函数 实验和分析数据库实验设置和训练策略消融实验视角一致性的效果 参考文献 论文: Exploiting Multiperspective Dr…

小米相册提取表格选项消失解决方法

小米相册这次的提取表格选项消失 故障原因&#xff1a; 因为部分用户将小爱视觉&#xff08;原名扫一扫&#xff09;这个应用给卸载了导致 解决方法 应用商店下载 小爱视觉 安装后授权即可使用 注意&#xff1a;系统最好为最新的 Xiaomi HyperOS系统

抖音小店保证金是多少?怎么缴纳?最全的解答来了!

大家好&#xff0c;我是电商糖果 关于抖音小店的保证金&#xff0c;很多人并不太了解。 再加上保证金每年都会有变动&#xff0c;造成很多想开店的商家完全不懂&#xff0c;应该准备多少钱&#xff0c;以及如何缴纳&#xff1f; 这里糖果就给大家总结一下&#xff0c;想开店…

基于SSM+Jsp+Mysql的高校二手交易平台

基于SSMJspMysql的高校二手交易平台 基于SSMJspMysql的高校二手交易平台的设计与实现 开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff0…

JetBrains全家桶激活,分享 GoLand 2024 激活的方案

大家好&#xff0c;欢迎来到金榜探云手&#xff01; GoLand 公司简介 JetBrains 是一家专注于开发工具的软件公司&#xff0c;总部位于捷克。他们以提供强大的集成开发环境&#xff08;IDE&#xff09;而闻名&#xff0c;如 IntelliJ IDEA、PyCharm、和 GoLand等。这些工具被…