單片機第一季:零基礎13——AD和DA轉換

1,AD轉換基本概念

51 單片機系統內部運算時用的全部是數字量,即0 和1,因此對單片機系統而言,無法直接操作模擬量,必須將模擬量轉換成數字量。所謂數字量,就是用一系列0 和1 組成的二進制代碼表示某個信號大小的量。用數字量表示同一個模擬量時,數字位數可以多也可以少,位數越多則表示的精度越高,位數越少表示的精度就越低。?

ADC(analog to digital converter)也稱為模數轉換器,是指一個將模擬信號轉變為數字信號。單片機在采集模擬信號時,通常都需要在前端加上A/D 芯片。?

?A(A,analog,模擬的,D,digital,數字的)現實世界是模擬的,連續分布的,無法被分成有限份;計算機世界是數字的,離散分布的,是可以被分成有限份的;AD轉換就是把一個物理量從模擬的轉換成數字的。

AD轉換中的主要概念:
(1)位數,AD轉換后轉出來的二進制數由幾位二進制來表示。位數越多,越細膩;
(2)量程,AD轉換器可以接受的模擬量的范圍;
(3)精度,簡單理解就是轉出來到底有多準;
(4)分辨率,AD轉換器轉出來的二進制數,每一格表示多少;
(5)轉換速率(轉換時間);?

例:輸入電壓范圍0-5V,AD轉換輸出位數是10,精度是0.01V,則:量程為0-5V,分辨率為:(5-0)/2exp(10)=0.00488V,譬如一次AD轉換后得到的數據是1010101010,則對應的電壓值為:3.328V,考慮精度后為3.33V?。

AD轉換在系統中存在的方式:
(1)CPU外部擴展專用AD芯片;
(2)CPU內部集成AD模塊(內部外設);?

電池單體的電壓采集芯片有一種叫AFE的(Anlog Front End),即是一種AD轉換模塊,采集單體的電壓轉換為數字量發給MCU。?

2,AD轉換原理圖和數據手冊?

?ET2046 AD轉換模塊通過AIN0/AIN1/AIN2分別連接滑線變阻器、熱敏電阻、光敏電阻。與單片機連接的接口為CS(使能接口,低有效)、CLK(時鐘信號)、DI(數據輸入,從單片機到AD轉換模塊)、DO(數據輸出、從AD轉換模塊到單片機)。

X+、Y+、VBAT?和AUX 模擬信號經過片內的控制寄存器選擇后進入ADC,ADC 可以配置為單端或差分模式。選擇VBAT和AUX 時應該配置為單端模式;作為觸摸屏應用時,應該配置為差分模式。

單片機在對AD轉換模塊進行控制時,控制字節由DIN 輸入的控制字命令格式如下所示:

Bit7為開始位,為1表示一個新的控制字節到來,為0則忽略PIN引腳上的數據;

A2-A0為通道選擇位,表示選擇哪個通道的輸入電壓進行AD轉換;

MODE為12/8位轉換分辨率選擇位,為1選擇8位轉換分辨率,為0選擇12位分辨率;

SER/DFR:單端輸入方式/差分輸入方式選擇,為1是單端輸入方式,為0是差分輸入方式;

PD1-PD0為低功耗模式選擇位,若為11,器件總處于供電狀態,若為00,器件在轉換之間處于低功耗模式。

單端模式時采集通道的選擇如下表所示(通過上述控制字節的A2-A1進行選擇):?

選擇X+通道、12位分辨率、單端模式、低功耗模式的控制字節命令:0b1001 0100 = 0x94。?

AD轉換模塊的時序圖如下所示:?

從時序圖上可見,轉換模塊進入工作狀態時,CS為低,DCLK為低,DIN和DOUT不用關注;首先通過DIN數據線從單片機發送控制字節到AD轉換模塊,在DCLK的上升沿AD轉換模塊讀入數據(從高到低進行讀入),當8位控制字節命令發送完成后,轉換模塊進入busy狀態,即轉換模塊開始進行AD轉換,此時間可從數據手冊獲取,一般程序中通過延遲一段時間來進行處理;然后單片機在DOUT數據線讀取轉換模塊發出的數據,每個DCLK的下降沿轉換模塊會將一位數據發送到DOUT數據線上,仍然是從高到低的順序。

可見AD轉換和單片機的通訊方式類似于SPI通訊。?

3,AD轉換代碼?

AD采樣轉換代碼包括單片機和AD轉換模塊寫入命令和讀取數據的底層時序代碼,通過串口顯示采樣數據代碼,以及main文件。

ET2046.c底層時序代碼:?

#include "ET2046.h"
#include <intrins.h>void delay10us(void)   //誤差 0us
{unsigned char a,b;for(b=1;b>0;b--)for(a=2;a>0;a--);
}unsigned int read_AD_value(unsigned char cmd)
{unsigned char i = 0;unsigned int AD_Value = 0;CS = 0;SCLK = 0;for(i = 0;i < 8;i++){DIN = cmd >> 7;cmd <<= 1;   //注意將一個數據移位后再賦給本身的運算符位 <<=SCLK = 1;_nop_();SCLK = 0;_nop_();}delay10us();SCLK = 1;	  			//發送一個時鐘周期,清除BUSY_nop_();_nop_();SCLK = 0;_nop_();_nop_();for(i = 0;i<12;i++){AD_Value <<= 1;SCLK = 1;_nop_();SCLK = 0;_nop_();AD_Value |= DOUT;}CS = 1;return AD_Value;}

ET2046.h?


#ifndef __ET2046_H__
#define __ET2046_H__#include <reg51.h>sbit SCLK = P1^0;
sbit CS = P1^1;sbit DIN = P1^2;
sbit DOUT = P1^3;unsigned int read_AD_value(unsigned char cmd);#endif

串口調試代碼:?

#include "uart.h"// 串口設置為: 波特率9600、數據位8、停止位1、奇偶校驗無
// 使用的晶振是11.0592MHz的,注意12MHz和24MHz的不行
void uart_init(void)
{// 波特率9600SCON = 0x50;   	// 串口工作在模式1(8位串口)、允許接收PCON = 0x00;	// 波特率不加倍// 通信波特率相關的設置TMOD = 0x20;	// 設置T1為模式2TH1 = 253;TL1 = 253;	   	// 8位自動重裝,意思就是TH1用完了之后下一個周期TL1會// 自動重裝到TH1去TR1 = 1;		// 開啟T1讓它開始工作
//	ES = 1;
//	EA = 1;
}// 通過串口發送1個字節出去
void uart_send_byte(unsigned char c)
{// 第1步,發送一個字節SBUF = c;// 第2步,先確認串口發送部分沒有在忙while (!TI);// 第3步,軟件復位TI標志位TI = 0;
}void uart_send_adVal(unsigned int val)
{uart_send_byte(val>>8);   //AD采樣的數據為12位的,首先左移8位串口輸出高4位uart_send_byte(val);	   //再輸出低8位
}

注意:因為AD采樣的數據是12位的數據,串口每次只能發送8位數據,需要分兩次將12位數據進行發送;?

#ifndef __UART_H__
#define __UART_H__#include <reg51.h>void uart_init(void);
void uart_send_byte(unsigned char c);
void uart_send_adVal(unsigned int val);#endif

main.c函數?

#include "ET2046.h"
#include "uart.h"#define AIN0 0x94	  //滑動變阻器
#define AIN1 0xd4	  //熱敏電阻
#define AIN2 0xa4	  //光敏電阻void delay1s(void)   //誤差 0us
{unsigned char a,b,c;for(c=167;c>0;c--)for(b=171;b>0;b--)for(a=16;a>0;a--);
}void main()
{unsigned int ad_val = 0;uart_init();//uart_send_adVal(0xabc);	  //測試代碼//uart_send_byte(0x0d);//uart_send_byte(0x0a);//while(1);while(1){ad_val= read_AD_value(AIN2);uart_send_adVal(ad_val);uart_send_byte(0);      	//發送數據0區分每次采樣數值delay1s();				  //如何實現在串口調試助手中發送一次采樣數據后換行?}}

思考:上述代碼中,main函數是通過while()不斷采樣和發送AD轉換的數據,如何通過中斷來采樣和發送AD轉換數據??

4,AD轉換代碼-直接在串口顯示電壓值?

串口助手中看到的數據以16進制顯示或以對應字符形式來顯示,因此在顯示AD轉換的電壓時不直觀,為了直觀顯示采集到的電壓值,通過對采集到的電壓值根據ASCii表對每一個十進制數轉化為對應的數字符號,如下圖所示,入藥顯示電壓值中的數字5,只需要發送5+48的十進制數,在串口助手中就可以看到對應的符號5。

代碼如下:?

5,DA轉換?

待完善?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40009.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40009.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40009.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux -- 進階 Autofs自動掛載服務 實驗詳解

服務端創建共享目錄&#xff0c; 客戶端實現自動掛載 第一步 &#xff1a; 客戶端&#xff0c;服務端 均關閉安全軟件 [rootserver ~]# setenforce 0 [rootserver ~]# systemctl stop firewalld [rootnode1 ~]# setenforce 0 [rootnode1 ~]# systemctl stop firewalld 第二…

在K8s上處理nginx

基本說明 創建一個名為ssl的TLS類型的Secret對象&#xff0c;用于存儲證書和密鑰信息。 kubectl create secret tls ssl --certserver.crt --keyserver.key配置Nginx的events塊&#xff0c;設置worker連接數為1024。 events {worker_connections 1024; }配置Nginx的http塊&a…

MyBaits(單獨使用,與整合無關)小白版

文章目錄 概述比較配置寫xml加載上面配置并執行加載配置的方法方式一 執行方法方式一方式二(MyBatis映射器) 寫配置文件的映射文件設置對象的別名&#xff08;簡寫&#xff09;獲取自動生成的主鍵 查詢結果和java的映射規則基本類型映射&#xff1a;簡單對象映射&#xff1a;嵌…

加鹽加密算法

MD5加密加鹽加密項目密碼升級 MD5加密 MD5一系列公式進行復雜數學運算&#xff1b;特點&#xff1a;&#xff08;用途校驗和、計算hash值方式、加密&#xff09; 1&#xff1a;定長&#xff1b;無論原始數據多長&#xff1b;算出的結果都是4或者8字節的版本。 2&#xff1a;沖…

Java多線程實戰

Java多線程實戰 java多線程&#xff08;超詳細&#xff09; java自定義線程池總結 Java創建線程方式 方法1&#xff0c;繼承Thread類 方法2&#xff0c;實現Runable接口 方法2-2&#xff0c;匿名內部類形式lambda表達式 方法3&#xff0c;實現Callable接口&#xff0c;允許…

【深入理解Linux內核鎖】三、原子操作

我的圈子: 高級工程師聚集地 我是董哥,高級嵌入式軟件開發工程師,從事嵌入式Linux驅動開發和系統開發,曾就職于世界500強企業! 創作理念:專注分享高質量嵌入式文章,讓大家讀有所得! 文章目錄 1、原子操作思想2、整型變量原子操作2.1 API接口2.2 API實現2.2.1 原子變量結…

Shell 函數

Shell 函數 linux shell 可以用戶定義函數&#xff0c;然后在shell腳本中可以隨便調用。 shell中函數的定義格式如下&#xff1a; [ function ] funname [()] { action; [return int;] } 說明&#xff1a; 1、可以帶function fun() 定義&#xff0c;也可以直接fun…

log4j:WARN No appenders could be found for logger問題

本文將idea場景下的使用。 IDEA中&#xff0c;將配置文件命名為log4j.properties&#xff08;該命名才會被自動加載&#xff09;&#xff0c; 并放到某個目錄下&#xff08;通常放到resources目錄&#xff09;&#xff0c;并在resources上右鍵&#xff0c;找到Mark Directory a…

微信程序 自定義遮罩層遮不住底部tabbar解決

一、先上效果 二 方法 1、自定義底部tabbar 實現&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html 官網去抄 簡單寫下&#xff1a;在代碼根目錄下添加入口文件 除了js 文件的list 需要調整 其他原封不動 代碼&#xf…

Hadoop數據遷移distcp

Hadoop數據遷移distcp 準備工作 確認源集群&#xff08;a&#xff09;,目標集群&#xff08;b&#xff09;確認a集群的主節點和b集群的主節點確認兩個集群的網絡相通確認遷移模式&#xff08;全量遷移還是增量遷移&#xff09;&#xff0c;這里選擇全量遷移 遷移文件 遷移t…

【路由協議】使用按需路由協議和數據包注入的即時網絡模擬傳遞率(PDR)、總消耗能量和節點消耗能量以及延遲研究(Matlab代碼實現)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;歡迎來到本博客????&#x1f4a5;&#x1f4a5; &#x1f3c6;博主優勢&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客內容盡量做到思維縝密&#xff0c;邏輯清晰&#xff0c;為了方便讀者。 ??座右銘&a…

斯坦福「小鎮」開源AI智能體;小米應用商店將要求AI應用符合資質標準

&#x1f989; AI新聞 &#x1f680; 斯坦福「小鎮」開源AI智能體 摘要:斯坦福研究人員開源了一個類似《西部世界》的數字化「小鎮」,里面有25個AI智能體可以生活、工作、社交。這項研究被視為AGI的重要開端,可能會改變游戲、企業應用領域。網友期待這項技術改善游戲NPC的交互…

PyMuPDF`庫實現PDF旋轉功能

本文介紹了一個簡單的Python應用程序&#xff0c;用于將PDF文件轉換為旋轉90度的PDF文件。主要用于csdn網站中導出的博客pdf是橫向的&#xff0c;看起來不是很方便&#xff0c;才想到用python編制一個將pdf從橫向轉為縱向的功能。 功能 該PDF轉換工具具有以下功能&#xff1a…

信息安全:防火墻技術原理與應用.

信息安全&#xff1a;防火墻技術原理與應用. 防火墻是網絡安全區域邊界保護的重要技術。為了應對網絡威脅&#xff0c;聯網的機構或公司將自己的網絡與公共的不可信任的網絡進行隔離&#xff0c;其方法是根據網絡的安全信任程度和需要保護的對象&#xff0c;人為地劃分若干安全…

C#工程建立后修改工程文件名與命名空間

使用之前的項目做二次開發&#xff0c;項目快結束的時候&#xff0c;需要把主項目的名稱修改成我們想要的。 之前從來沒有這么干過&#xff0c;記錄一下。 步驟如下&#xff1a; 1&#xff1a;打開vs2010項目解決方案&#xff0c;重命名&#xff0c;如下圖所示&#xff1a; …

SDP協議是什么,詳解SDP協議

一、SDP協議簡介 SDP&#xff08;Session Description Protocol&#xff09;是一種會話描述協議&#xff0c;用于描述多媒體會話的參數。它是一種文本協議&#xff0c;通常用于VoIP&#xff08;Voice over Internet Protocol&#xff09;和視頻會議等應用中。SDP協議定義了一種…

Vue項目(購物車)

目錄 購物車效果展示&#xff1a; 購物車代碼&#xff1a; 購物車效果展示&#xff1a; 此項目添加、修改、刪除數據的地方都寫了瀏覽器都會把它存儲起來 下次運行項目時會把瀏覽器數據拿出來并在頁面展示 Video_20230816145047 購物車代碼&#xff1a; 復制完代碼&#xff0…

leetcode每日一題_2682.找出轉圈游戲輸家

2682.找出轉圈游戲輸家 題目: n 個朋友在玩游戲。這些朋友坐成一個圈&#xff0c;按 順時針方向 從 1 到 n 編號。從第 i 個朋友的位置開始順時針移動 1 步會到達第 (i 1) 個朋友的位置&#xff08;1 < i < n&#xff09;&#xff0c;而從第 n 個朋友的位置開始順時針移…

設計模式之原型模式Prototype的C++實現

1、原型模式提出 在軟件功能設計中&#xff0c;經常面臨著“某些結構復雜的對象”的創建工作&#xff0c;且創建的對象想擁有其他對象在某一刻的狀態&#xff0c;則可以使用原型模型。原型模型是通過拷貝構造函數來創建對象&#xff0c;并且該對象擁有其他對象在某一刻的狀態。…

Docker基礎入門:鏡像、容器導入導出與私有倉庫搭建

Docker基礎入門&#xff1a;鏡像導入導出與私有倉庫搭建 一、 Docker鏡像、容器的導入和導出1.1、Docker鏡像的導出1.2、Docker鏡像的載入1.3、Docker容器的導出1.4、Docker容器的導入 二、 鏡像和容器導出和導入的區別:三、commit操作_本地鏡像發布到阿里云3.1、commit操作有關…