我們都知道微控制器只能處理數字值,但在現實世界中我們必須處理模擬信號。這就是為什么ADC(模數轉換器)可以將現實世界的模擬值轉換為數字形式,以便微控制器可以處理信號。但是,如果我們需要來自數字值的模擬信號怎么辦,那么就來了DAC(數模轉換器)。
數模轉換器的一個簡單示例是在錄音室錄制歌曲,藝術家歌手正在使用麥克風唱歌。這些模擬聲波被轉換為數字形式,然后存儲在數字格式文件中,當使用存儲的數字文件播放歌曲時,這些數字值被轉換為模擬信號用于揚聲器輸出。所以在這個系統中使用了 DAC。
DAC 可用于許多應用,例如電機控制、控制 LED 燈的亮度、音頻放大器、視頻編碼器、數據采集系統等。
在許多微控制器中,都有一個可用于產生模擬輸出的內部 DAC。但是 ATmega328/ATmega168 等 Arduino 處理器沒有內置 DAC。Arduino 具有 ADC 功能(模數轉換器),但它沒有 DAC(數模轉換器)。它在內部 ADC 中有一個 10 位 DAC,但該 DAC 不能單獨使用。所以在這個 Arduino DAC 教程中,我們使用了一個名為MCP4725 DAC 模塊的附加板和 Arduino。
MCP4725 DAC 模塊(數模轉換器)
MCP4725 IC 是一款12 位數模轉換器模塊,用于生成(0 至 5V)的輸出模擬電壓,并通過I2C 通信進行控制。它還帶有板載非易失性存儲器 EEPROM。
該 IC 具有 12 位分辨率。這意味著我們使用(0 到 4096)作為輸入來提供相對于參考電壓的電壓輸出。最大參考電壓為 5V。
計算輸出電壓的公式
O/P 電壓 = (參考電壓/分辨率) x 數字值
例如,如果我們使用 5V 作為參考電壓,假設數字值為 2048。因此要計算 DAC 輸出。
O/P 電壓 = (5/ 4096) x 2048 = 2.5V
MCP4725的引腳排列
下面是 MCP4725 的圖像,清楚地標明了引腳名稱。
MCP4725 DAC 中的 I2C 通信
該 DAC IC 可通過 I2C 通信與任何微控制器連接。I2C 通信只需要兩條線 SCL 和 SDA。默認情況下,MCP4725 的 I2C 地址為 0x60 或 0x61 或 0x62。對我來說它是 0x61。使用 I2C 總線,我們可以連接多個 MCP4725 DAC IC。唯一的事情是我們需要更改 IC 的 I2C 地址。Arduino中的 I2C 通信已在之前的教程中詳細解釋過。
在本教程中,我們將MCP4725 DAC IC 與 Arduino Uno 連接,并使用電位計為 Arduino 引腳 A0 提供模擬輸入值。然后ADC將用于將模擬值轉換為數字形式。之后,這些數字值通過 I2C 總線發送到 MCP4725,以使用 DAC MCP4725 IC 轉換為模擬信號。Arduino 引腳 A1 用于從引腳 OUT 檢查 MCP4725 的模擬輸出,最后在16x2 LCD 顯示屏上顯示 ADC 和 DAC 值和電壓。
所需組件
Arduino Nano / Arduino Uno
16x2液晶顯示模塊
MCP4725 DAC集成電路
10k 電位器
面包板
跳線
電路原理圖
下表顯示了 MCP4725 DAC IC、Arduino Nano 和萬用表之間的連接
16x2 LCD 和 Arduino Nano 之間的連接
使用電位器,中心引腳連接到 Arduino Nano 的 A0 模擬輸入,左側引腳連接到 GND,最右側引腳連接到 Arduino 的 5V。
DAC Arduino 編程
DAC 教程的完整 Arduino 代碼在最后附有演示視頻。這里我們逐行解釋了代碼。
首先,使用wire.h和liquidcrystal.h庫包含I2C 和LCD庫。
#include#include
接下來根據我們與 Arduino Nano 連接的引腳定義和初始化 LCD 引腳
液晶液晶(2,3,4,5,6,7); //定義LCD顯示引腳RS,E,D4,D5,D6,D7
接下來定義 MCP4725 DAC IC 的 I2C 地址
#define MCP4725 0x61
在 void setup()
首先在 Arduino Nano 的引腳 A4 (SDA) 和 A5 (SCL) 開始 I2C 通信
Wire.begin(); //開始I2C通信
接下來將 LCD 顯示屏設置為 16x2 模式并顯示歡迎信息。
lcd.開始(16,2);//將 LCD 設置為 16X2 模式 lcd.print("CIRCUIT DIGEST"); 延遲(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Arduino"); lcd.setCursor(0,1); lcd.print("帶有 MCP4725 的 DAC"); 延遲(2000); lcd.clear();
在無效循環()
1.首先在buffer[0]中放入控制字節值(0b01000000)
(010-將 MCP4725 設置為寫模式)
緩沖區[0] = 0b01000000;
2. 以下語句從引腳 A0 讀取模擬值并將其轉換為數字值(0-1023)。Arduino ADC 是 10 位分辨率,因此將其乘以 4 得出:0-4096,因為 DAC 是 12 位分辨率。
adc = 模擬讀取(A0)* 4;
3.此語句是從ADC輸入值(0到4096)和參考電壓為5V求電壓
浮動 ipvolt = (5.0/4096.0)* adc;
4. 第一行下方通過在 ADC 變量中向右移動 4 位將最高有效位值放入緩沖區 [1],第二行通過在 ADC 變量中向左移動 4 位將最低有效位值放入緩沖區 [2]。
緩沖區[1] = adc >> 4; 緩沖區[2] = adc << 4;
5. 以下語句從作為 DAC 輸出(MCP4725 DAC IC 的 OUTPUT 引腳)的 A1 讀取模擬電壓。該引腳也可以連接到萬用表以檢查輸出電壓。在此處了解如何使用萬用表。
無符號 int 類比讀取 = 類比讀取(A1)*4 ;
6. 此外,變量analogread的電壓值使用以下公式計算
浮動 opvolt = (5.0/4096.0)* 模擬讀數;
7. 以下語句用于開始使用 MCP4725 進行傳輸
Wire.beginTransmission(MCP4725);
將控制字節發送到 I2C
Wire.write(buffer[0]);
將 MSB 發送到 I2C
Wire.write(buffer[1]);
將 LSB 發送到 I2C
Wire.write(buffer[2]);
結束傳輸
Wire.endTransmission();
現在最后使用 lcd.print() 在 LCD 16x2 顯示器中顯示這些結果
lcd.setCursor(0,0); lcd.print("A IP:"); lcd.print(adc); lcd.setCursor(10,0); lcd.print("V:"); lcd.print(ipvolt); lcd.setCursor(0,1); lcd.print("D OP:"); lcd.print(模擬讀取); lcd.setCursor(10,1); lcd.print("V:"); lcd.print(opvolt); 延遲(500); lcd.clear();
使用 MCP4725 和 Arduino 進行數模轉換
完成所有電路連接并將代碼上傳到 Arduino 后,改變電位器并觀察 LCD 上的輸出。LCD 第一行顯示輸入 ADC 值和電壓,第二行顯示輸出 DAC 值和電壓。
您還可以通過將萬用表連接到 MCP4725 的 OUT 和 GND 引腳來檢查輸出電壓。
#include
#include
#define MCP4725 0x61 //MCP4725 地址為 0x61 相應地更改你
的 LiquidCrystal lcd(2,3,4,5,6,7); //定義LCD顯示引腳RS,E,D4,D5,D6,D7
unsigned int adc;
字節緩沖區[3];
void setup()
{
Wire.begin(); //開始 I2C 通信
lcd.begin(16,2); //將 LCD 設置為 16X2 模式
lcd.print("CIRCUIT DIGEST");
延遲(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Arduino");
lcd.setCursor(0,1);
lcd.print("帶有 MCP4725 的 DAC");
延遲(2000);
lcd.clear();
}
無效循環()
{
緩沖區[0] = 0b01000000;//使用控制字節設置緩沖區0(010-設置為寫入模式)
adc = analogRead(A0) * 4; //從引腳 A0 讀取模擬值并轉換為數字 (0-1023) 乘以 4 得到 (0-4096)
float ipvolt = (5.0/4096.0)* adc; //求電壓公式(A0)
buffer[1] = adc >> 4; //放置最高有效位值
buffer[2] = adc << 4; //輸入最低有效位值
unsigned int analogread = analogRead(A1)*4 ; //從 A1 讀取模擬電壓
float opvolt = (5.0/4096.0)* analogread; //求電壓公式 (A1)
Wire.beginTransmission(MCP4725); //通過地址為0x61的MCP4725加入I2C總線
Wire.write(buffer[0]); //發送控制字節到I2C
Wire.write(buffer[1]); //將 MSB 發送到 I2C
Wire.write(buffer[2]); //發送LSB到I2C
Wire.endTransmission(); //結束傳輸
lcd.setCursor(0,0);
lcd.print("A IP:");
lcd.print(adc); //從A0打印ADC值
lcd.setCursor(10,0);
lcd.print("V:"); //在 A0 打印輸入電壓
lcd.print(ipvolt);
lcd.setCursor(0,1);
lcd.print("D OP:");
lcd.print(模擬讀取);//從 A1 (From DAC) 打印 ADC 值
lcd.setCursor(10,1);
lcd.print("V:");
lcd.print(opvolt);
//在 A1(來自 DAC)延遲(500)處打印輸入電壓;
lcd.clear();
}
-
adc
+關注
關注
98文章
6514瀏覽量
545049 -
模數轉換器
+關注
關注
26文章
3209瀏覽量
126887 -
Arduino
+關注
關注
188文章
6472瀏覽量
187352
發布評論請先 登錄
相關推薦
評論