我們都知道微控制器只能處理數字值,但在現實世界中我們必須處理模擬信號。這就是為什么 ADC(模數轉換器) 可以將現實世界的模擬值轉換為數字形式,以便微控制器可以處理信號。但是,如果我們需要來自數字值的模擬信號怎么辦,那么就來了 DAC(數模轉換器)。
數模轉換器的一個簡單示例 是在錄音室錄制歌曲,藝術家歌手正在使用麥克風唱歌。這些模擬聲波被轉換為數字形式,然后存儲在數字格式文件中,當使用存儲的數字文件播放歌曲時,這些數字值被轉換為模擬信號用于揚聲器輸出。所以在這個系統中使用了 DAC。
DAC 可用于許多應用 ,例如電機控制、控制 LED 燈的亮度、 音頻放大器、視頻編碼器、數據采集系統等。
我們已經將 MCP4725 DAC 模塊與 Arduino連接起來。今天我們將使用相同的 MCP4725 DAC IC 來設計一個使用 STM32F103C8 微控制器的數模轉換器。
所需組件
STM32F103C8
MCP4725 DAC集成電路
10k 電位器
16x2 液晶顯示器
面包板
連接電線
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 中的 I2C 通信
該 DAC IC 可通過 I2C 通信與任何微控制器連接。I2C 通信只需要兩條線 SCL 和 SDA。默認情況下,MCP4725 的 I2C 地址為 0x60。點擊鏈接了解更多關于STM32F103C8 中 I2C 通信的信息。
STM32F103C8 中的 I2C 引腳:
SDA: PB7 或 PB9、PB11。
SCL : PB6 或 PB8, PB10。
電路圖及說明
STM32F103C8 和 16x2 LCD 之間的連接
MCP4725 DAC IC和STM32F103C8之間的連接
還連接了一個電位器,中心引腳連接到 STM32F10C8 的 PA1 模擬輸入 (ADC),左側引腳連接到 GND,最右側引腳連接到 STM32F103C8 的 3.3V。
在本教程中,我們將MCP4725 DAC IC 與 STM32 連接,并使用 10k 電位器為 STM32 ADC 引腳 PA0 提供模擬輸入值。然后使用ADC將模擬值轉換為數字形式。之后通過 I2C 總線將這些數字值發送到 MCP4725。然后使用 DAC MCP4725 IC 將這些數字值轉換為模擬值,然后使用 STM32 的另一個 ADC 引腳 PA1 從引腳 OUT 檢查 MCP4725 的模擬輸出。最后在16x2 LCD 顯示屏上顯示ADC 和 DAC 的電壓值。
對 STM32F103C8 進行數模轉換編程
現在不需要 FTDI 程序員將代碼上傳到 STM32F103C8。只需通過 STM32 的 USB 端口將其連接到 PC 并開始使用ARDUINO IDE進行編程。訪問此鏈接以了解有關在 Arduino IDE 中對 STM32 進行編程的更多信息。 最后給出了這個STM32 DAC教程的完整程序。
首先使用wire.h、SoftWire.h和liquidcrystal.h庫包含I2C 和LCD庫。在此處了解有關STM32 微控制器中 I2C 的更多信息。
?
#include#include #include
?
接下來根據與STM32F103C8連接的LCD引腳定義并初始化LCD引腳
?
const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14; LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
?
然后定義 MCP4725 DAC IC 的 I2C 地址。MCP4725 DAC 默認 I2C 地址為 0x60
?
#define MCP4725 0x60
?
在 void setup()
首先在 STM32F103C8 的引腳 PB7 (SDA) 和 PB6 (SCL) 處開始 I2C 通信。
?
Wire.begin(); //開始I2C通信
?
接下來將 LCD 顯示屏設置為 16x2 模式并顯示歡迎信息。
?
lcd.開始(16,2); lcd.print("電路文摘"); 延遲(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print("STM32F103C8"); lcd.setCursor(0,1); lcd.print("帶有 MCP4725 的 DAC"); 延遲(2000); lcd.clear();
?
在無效循環()
1.首先在緩沖區[0]中放入控制字節值(0b01000000)。
?
(010-將 MCP4725 設置為寫模式) 緩沖區[0] = 0b01000000;
?
2. 以下語句從引腳 PA0 讀取模擬值并將其轉換為 0 到 4096 范圍內的數字值,因為 ADC 是 12 位分辨率并存儲在變量adc中。
?
adc = 模擬讀?。≒A0);
?
3. 以下語句是用于計算 ADC 輸入值(0 到 4096)的電壓的公式,參考電壓為 3.3V。
?
浮動 ipvolt = (3.3/4096.0)* adc;
?
4. 通過在 ADC 變量中右移 4 位將最高有效位值放入緩沖區[1],通過在adc變量中左移 4 位將最低有效位值放入緩沖區[2]。
?
緩沖區[1] = adc >> 4; 緩沖區[2] = adc << 4;
?
5. 以下語句從 STM32 的 ADC 引腳 PA1 讀取模擬值,即 DAC 輸出(MCP4725 DAC IC 的 OUTPUT 引腳)。該引腳也可以連接到萬用表以檢查輸出電壓。
?
無符號整數模擬讀取 = 模擬讀?。≒A1);
?
6. 此外,來自變量analogread的電壓值使用帶有以下語句的公式計算。
?
浮動 opvolt = (3.3/4096.0)* 模擬讀數;
?
7. 在同一個void loop()中還有一些其他語句,下面解釋
使用 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();
?
使用 STM32 測試 DAC
當我們通過旋轉電位器改變輸入 ADC 值和電壓時,輸出 DAC 值和電壓也會發生變化。此處輸入值顯示在液晶顯示屏的第一行,輸出值顯示在第二行。萬用表也連接到 MCP4725 輸出引腳以驗證模擬電壓。
#include
#include
#include
#define MCP4725 0x60 //MCP4725 地址為 0x60 相應地改變你的
const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
無符號整數 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("STM32F103C8");
lcd.setCursor(0,1);
lcd.print("帶有 MCP4725 的 DAC");
延遲(2000);
lcd.clear();
}
無效循環()
{
緩沖區[0] = 0b01000000;//使用控制字節設置緩沖區0(010-設置為寫入模式)
adc = analogRead(PA0); //從引腳 PA0 讀取模擬值
float ipvolt = (3.3/4096.0)* adc; //求電壓公式
buffer[1] = adc >> 4; //放置最高有效位值
buffer[2] = adc << 4; //輸入最低有效位值
unsigned int analogread = analogRead(PA1) ; //從 PA1 讀取模擬值
float opvolt = (3.3/4096.0)* analogread; //尋找電壓公式
Wire.beginTransmission(MCP4725); //通過地址為0x60的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); //打印來自 PA0 的 ADC 值
lcd.setCursor(10,0);
lcd.print("V:"); //在 PA0 打印輸入電壓
lcd.print(ipvolt);
lcd.setCursor(0,1);
lcd.print("D OP:");
lcd.print(模擬讀取);//打印來自 PA1 (From DAC) 的 ADC 值
lcd.setCursor(10,1);
lcd.print("V:");
lcd.print(opvolt);
//在 PA1(來自 DAC)延遲(500)處打印輸入電壓;
lcd.clear();
}
評論
查看更多