ADC模-数转换原理与实现

1.  今日摸鱼计划

今天来学习一下ADC的原理,然后把ADC给实现

ADC芯片:ADC128S102

视频:

18A_基于SPI接口的ADC芯片功能和接口时序介绍_哔哩哔哩_bilibili

18B_使用线性序列机思路分析SPI接口的ADC芯片接口时序_哔哩哔哩_bilibili

18C_基于线性序列机的SPI接口ADC控制逻辑设计_哔哩哔哩_bilibili

2. ADC指标参数

3. ADC128S102

        在 ACZ702 EDA 扩展板上使用的模数转换器为逐次逼近型的低功耗芯片ADC128S102,其具有 8 通道以及 12 位的分辨率。电源采用独立的模拟供电以及数字供电,其中模拟电源 VA输入范围为 2.7V~5.25V,数字电源 VD输入范围为 2.7V~VA。其与外部通信支持多种接口如:SPIQSPIMICROWIRE以及通用的 DSP 接口。转换速度在 500 kps~1 Mkps,典型情况下当 3V 供电时功耗为2.3mW5V 供电时为 10.7mW,如下图为该 ADC 芯片的内部结构图。

芯片引脚功能如下:

ADC128S102通过 SPI接口与控制器进行通信的时序图如下图所示:

四线SPI分析:

CS

片选信号(本摸鱼怪不会加横线)

CS拉低,表示通信的开始,CS拉高表示通信结束

SCLK
CS 为高时 SCLK 默认高
一帧包含 16 个上升沿 SCLK
DIN

SCLK的上升沿,DIN上的信号要保持稳定,此时ADC芯片会对DIN上的信号采样

DOUT
CS 为高时代表空闲状态,当为低时为传输状态

4.  线性序列机实现ADC

module adc128s102(
                input Clk,
                input Reset_n ,
                
                input Conv_Go,//使能信号
                input [2:0]Addr,
                
                output reg Conv_Done,
                output reg[11:0]Data,
                
                output reg ADC_SCLK,
                output reg ADC_CS_N,
                output reg ADC_DIN,
                input ADC_DOUT
            );

    
    
    parameter CLOCK_FREQ = 50_000_000;
    parameter SCLK_FREQ = 12_500_000;
    parameter MCNT_DIV_CNT = CLOCK_FREQ/(SCLK_FREQ * 2) - 1;

    reg[7:0]DIV_CNT;
    
    reg [5:0]LSM_CNT;

    reg [11:0]Data_r;
    
    reg [2:0]r_Addr;
    
    always@(posedge Clk)
    if(Conv_Go)    
        r_Addr <= Addr;
    else
        r_Addr <= r_Addr;
    
    reg Conv_En; //转换使能
    
    always@(posedge Clk or negedge Reset_n )
    if(!Reset_n )
        Conv_En <= 1'd0;
    else if(Conv_Go)
        Conv_En <= 1'd1;
    else if((LSM_CNT == 6'd34) && (DIV_CNT == MCNT_DIV_CNT))
        Conv_En <= 1'd0;
    else
        Conv_En <= Conv_En;
    
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        DIV_CNT <= 0;
    else if(Conv_En)begin
        if(DIV_CNT == MCNT_DIV_CNT)
            DIV_CNT <= 0;
        else    
            DIV_CNT <= DIV_CNT + 1'd1;
    end
    else
        DIV_CNT <= 0;

    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        LSM_CNT <= 6'd0;
    else if(DIV_CNT == MCNT_DIV_CNT)begin
        if(LSM_CNT == 6'd34)
            LSM_CNT <= 6'd0;
        else
            LSM_CNT <= LSM_CNT + 1'd1; 
    end
    else
        LSM_CNT <= LSM_CNT;


    always@(posedge Clk or negedge Reset_n )
    if(!Reset_n )begin
        Data_r <= 12'd0;
        ADC_SCLK <= 1'd1;
        ADC_DIN <= 1'd1;
        ADC_CS_N <= 1'd1;
    end
    else if(DIV_CNT == MCNT_DIV_CNT)begin
        case(LSM_CNT)
            0 : begin ADC_CS_N <= 1'd1; ADC_SCLK <= 1'd1;end
            1 : begin ADC_CS_N <= 1'd0;end
            2 : begin ADC_SCLK <= 1'd0;end
            3 : begin ADC_SCLK <= 1'd1;end
            4 : begin ADC_SCLK <= 1'd0;end
            5 : begin ADC_SCLK <= 1'd1;end    
            6 : begin ADC_SCLK <= 1'd0;ADC_DIN <= r_Addr[2]; end
            7 : begin ADC_SCLK <= 1'd1;end    
            8 : begin ADC_SCLK <= 1'd0;ADC_DIN <= r_Addr[1]; end
            9 : begin ADC_SCLK <= 1'd1;end    
            10 :begin ADC_SCLK <= 1'd0;ADC_DIN <= r_Addr[0]; end
            11: begin ADC_SCLK <= 1'd1;Data_r[11] <= ADC_DOUT; end
            12: begin ADC_SCLK <= 1'd0;end
            13: begin ADC_SCLK <= 1'd1;Data_r[10] <= ADC_DOUT; end
            14: begin ADC_SCLK <= 1'd0;end    
            15: begin ADC_SCLK <= 1'd1;Data_r[9] <= ADC_DOUT; end
            16: begin ADC_SCLK <= 1'd0;end
            17: begin ADC_SCLK <= 1'd1;Data_r[8] <= ADC_DOUT; end
            18: begin ADC_SCLK <= 1'd0;end    
            19: begin ADC_SCLK <= 1'd1;Data_r[7] <= ADC_DOUT; end
            20: begin ADC_SCLK <= 1'd0;end
            21: begin ADC_SCLK <= 1'd1;Data_r[6] <= ADC_DOUT; end
            22: begin ADC_SCLK <= 1'd0;end    
            23: begin ADC_SCLK <= 1'd1;Data_r[5] <= ADC_DOUT; end
            24: begin ADC_SCLK <= 1'd0;end
            25: begin ADC_SCLK <= 1'd1;Data_r[4] <= ADC_DOUT; end
            26: begin ADC_SCLK <= 1'd0;end    
            27: begin ADC_SCLK <= 1'd1;Data_r[3] <= ADC_DOUT; end
            28: begin ADC_SCLK <= 1'd0;end
            29: begin ADC_SCLK <= 1'd1;Data_r[2] <= ADC_DOUT; end
            30: begin ADC_SCLK <= 1'd0;end    
            31: begin ADC_SCLK <= 1'd1;Data_r[1] <= ADC_DOUT; end
            32: begin ADC_SCLK <= 1'd0;end
            33: begin ADC_SCLK <= 1'd1;Data_r[0] <= ADC_DOUT; end
            34: begin ADC_SCLK <= 1'd1;ADC_CS_N <= 1'd1; end
            default: ADC_CS_N <= 1'd1; 
        endcase
    end

    always@(posedge Clk or negedge Reset_n )
    if(!Reset_n )begin
        Data <= 12'd0;
        Conv_Done <= 0;
    end
    else if((LSM_CNT == 34) && (DIV_CNT == MCNT_DIV_CNT))begin
        Conv_Done <= 1'd1;
        Data <= Data_r;
    end
    else begin
        Conv_Done <= 1'd0;
        Data <= Data;
    end

endmodule

5.  adc128s102_tb

`timescale 1ns/1ns

module adc128s102_tb;

    reg clk;
    reg reset_n;
    
    reg Conv_Go;
    reg [2:0]Addr;
    
    wire Conv_Done;
    wire[11:0]Data;
    
    wire ADC_SCLK;
    wire ADC_CS_N;
    wire ADC_DIN;
    reg ADC_DOUT;

    adc128s102 adc128s102(
        .Clk(clk),
        .Reset_n(reset_n),
        .Conv_Go(Conv_Go),
        .Addr(Addr),

        .Conv_Done(Conv_Done),
        .Data(Data),
        .ADC_SCLK(ADC_SCLK),
        .ADC_CS_N(ADC_CS_N),
        .ADC_DIN(ADC_DIN),
        .ADC_DOUT(ADC_DOUT)
    );
    
    initial clk = 1;
    always #10 clk = ~clk;
    
    initial begin
        reset_n = 0;
        Conv_Go = 0;
        Addr = 0;
        #201;
        reset_n = 1;
        #200;
        Conv_Go = 1;
        Addr = 3;
        #20;
        Conv_Go  = 0;
        wait(!ADC_CS_N);
        //16'h0A58
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB15 
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB14 
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB13        
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB12        
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB11          
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB10         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB9         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB8         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB7         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB6         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB5         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB4        
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB3         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB2        
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB1         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB0      
        wait(ADC_CS_N);
        #2000;   
             
        Conv_Go = 1;
        Addr = 7;
        #20;
        Conv_Go  = 0;        
        wait(!ADC_CS_N);
        //16'h0893
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;        
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;        
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;          
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;       
        wait(ADC_CS_N);
        #200;    
        #2000;
        $stop;
    end
endmodule

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

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

相关文章

neo4j-5.11.0安装APOC插件or配置允许使用过程的权限

在已经安装好neo4j和jdk的情况下安装apoc组件&#xff0c;之前使用neo4j-community-4.4.30&#xff0c;可以找到配置apoc-4.4.0.22-all.jar&#xff0c;但是高版本neo4j对应没有apoc-X.X.X-all.jar。解决如下所示&#xff1a; 1.安装好JDK与neo4j 已经安装对应版本的JDK 17.0…

MySQL数据库及数据表的创建

1.创建一个名叫 db_classes 的数据库&#xff1a; 创建一个叫 db_classes 的数据库MySQL命令&#xff1a; create database db_classes; 运行效果&#xff1a; 创建数据库后查看该数据库基本信息MySQL命令&#xff1a; show create database db_classes; 运行效果&#xff…

力扣刷题--数组--第三天

今天再做两道二分查找的题目&#xff0c;关于二分查找的知识可看我前两篇博客。话不多说&#xff0c;直接开干&#xff01; 题目1&#xff1a;69.x 的平方根 题目详情&#xff1a;   给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。由于返回类型是整数&#…

VScode通过ssh远程连接服务器被拒绝:permission denied, please try again

使用场景&#xff1a; 使用windows系统下的vscode远程连接服务器的linux系统&#xff0c;终端提示permission denied, please try again,但是使用cmd是可以远程登录的。 解决办法&#xff1a; 前提条件windows端的vscode安装了ssh远程连接的相关插件Remote - SSH&#xff0c;…

Django之rest_framework(六)

一、GenericViewSet类的使用 继承自GenericAPIView,作用也与GenericAPIVIew类似,提供了get_object、get_queryset等方法便于视图的开发 1.1、代码 from rest_framework.viewsets import GenericViewSet from rest_framework.response import Response from rest_framework …

Duplicate File Finder Pro for Mac激活版:重复文件清理软件

在繁杂的文件管理中&#xff0c;你是否曾为重复文件而烦恼&#xff1f;Duplicate File Finder Pro for Mac&#xff0c;正是你不可或缺的得力助手。这款专业级工具&#xff0c;能够迅速扫描并定位Mac系统中的重复文件&#xff0c;让你的存储空间恢复清爽。 通过强大的算法支持&…

[C/C++] -- 代理模式

代理模式是一种结构型设计模式&#xff0c;允许一个对象&#xff08;代理&#xff09;控制另一个对象的访问。代理对象通常充当客户端和实际目标对象之间的中间人&#xff0c;从而控制对目标对象的访问&#xff0c;可以在访问前后进行一些额外的处理。 代理模式的优点包括&…

《铁路出行更便捷:火车票预定审批系统的设计与应用》

在现代化的铁路交通管理中&#xff0c;火车票预定审批系统扮演着至关重要的角色。它不仅能够有效管理员工出差、培训等需要乘坐火车的行程&#xff0c;还能够提高审批效率&#xff0c;减少人力成本&#xff0c;确保出行安全。本文将探讨火车票预定审批系统的设计原则和应用场景…

图片压缩和尺寸调节工具@图像压缩@分辨率调节@降低图片文件体积和磁盘占用

文章目录 abstract降低图片文件大小的方式相关原理 跨平台免费的压缩工具离线运行的软件在线工具&#x1f47a;windows 系统上的压缩方法windows 照片程序(photo)powertoys image-resizer(分辨率/尺寸调整) windows mspaint(画图工具调整分辨率) abstract 提到图片压缩时&#…

一款支持几分钟视频生成,免费无限制AI视频生成网站

前言 AI可以生成原创中视频了&#xff01; 不是4秒&#xff0c;而是最长达6分钟&#xff0c;官方名为白日梦&#xff0c;将白日梦变成现实&#xff01; 他不是简单的文生图/图生视频 而是将文生图、图生视频、配音字幕、后期剪辑等&#xff0c;打包封装成一条AI视频生产工作…

Axure PR 10 下拉三级菜单设计图

在线预览地址&#xff1a;Untitled Document 程序员必备资源网站&#xff1a;天梦星服务平台 (tmxkj.top) 需要源码设计图联系我wx:19948765606,3块钱拿走

Maven+Junit5 + Allure +Jenkins 搭建 UI 自动化测试实战

文章目录 效果展示Junit 5Junit 5 介绍Junit 5 与 Junit 4 对比PageFactory 模式编写自动化代码公共方法提取测试用例参数化Jenkins 搭建及配置参数化执行生成 Allure 报告Maven 常用命令介绍POM 文件效果展示 本 chat 介绍 UI 自动化测试框架的搭建: 运用 page factory 模式…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《基于V2G潜力模糊评估与移动储能协调调度的灾后供电恢复策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

第12章 软件测试基础(第三部分)测试类型、测试工具

七、测试类型&#xff08;按工程阶段划分&#xff09; 单集系确收 &#xff08;一&#xff09;单元测试 1、单元测试/模块测试 单元就是软件中最小单位&#xff08;或模块&#xff09;。可以是一个函数、一个过程、一个类。主要依据是模块的详细设计文档。价值在于尽早发现…

spring模块(六)spring监听器(1)ApplicationListener

一、介绍 1、简介 当某个事件触发的时候&#xff0c;就会执行的方法块。 当然&#xff0c;springboot很贴心地提供了一个 EventListener 注解来实现监听。 2、源码&#xff1a; package org.springframework.context;import java.util.EventListener; import java.util.fu…

游戏理解入门:Rust+Bracket开发一个小游戏

1. Game loop 使用game loop可以使得游戏运行更加流畅和顺滑&#xff0c;它可以&#xff1a; 初始化窗口、图形和其他资源&#xff1b;每当屏幕刷新他都会运行(通常是每秒30,60 )&#xff1b;每次通过循环&#xff0c;他都会调用游戏的tick()函数。 大致的原理流程如下&…

如何查看公网IP开放端口?

在计算机网络中&#xff0c;公网IP是指能够直接访问互联网的IP地址&#xff0c;而开放端口则是指外部网络可以访问的服务端口。查看公网IP开放端口可以帮助我们了解当前网络环境中哪些服务可以被外部网络访问&#xff0c;对于网络安全和远程连接非常重要。 天联组网 天联组网是…

2024蓝桥杯网络安全部分赛题wp

爬虫协议 题目给了提示访问robots.txt 会出三个目录 访问最后一个 点进去就flag{22560c15-577c-4c8b-9944-815473758bad} packet 下载附件&#xff0c;这个是流量包 放wireshark流量分析 搜http协议 发现有cat flag命令&#xff0c;直接看他返回的流量 最后base64解码即可…

Linux-笔记 i2c-tools

1、i2c-tools介绍 1、在日常linux开发中&#xff0c;有时候需要确认i2c硬件是否正常连接&#xff0c;设备是否正常工作&#xff0c;设备的地址是多少等等&#xff0c;这里我们就需要使用一个用于测试I2C总线的工具——i2c-tools&#xff0c;i2c-tools原理是通过操作/dev 路径 …

存储大作战:探索Local Storage与Session Storage的奥秘

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 存储大作战&#xff1a;探索Local Storage与Session Storage的奥秘 前言Local Storage与Session Storage简介数据存储生命周期容量限制安全性 前言 在Web的世界里&#xff0c;数据就像是一群流浪者&a…