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