<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 簡(jiǎn)易電壓表設計

簡(jiǎn)易電壓表設計

作者: 時(shí)間:2023-12-13 來(lái)源:電子森林 收藏

實(shí)驗任務(wù)

  • 任務(wù):基于核心板 和 底板 完成簡(jiǎn)易設計并觀(guān)察調試結果
  • 要求:通過(guò)底板上的串行模數轉換器ADC芯片測量可調電位計輸出電壓,并將電壓信息顯示在核心板的數碼管上。
  • 解析:通過(guò)編程驅動(dòng)串行ADC芯片,得到數字量化的電壓信息,將量化的數字信息轉換成BCD碼形式,同時(shí)驅動(dòng)獨立數碼管將電壓值顯示出來(lái)。

實(shí)驗目的

在基礎數字電路實(shí)驗部分我們已經(jīng)掌握了驅動(dòng)獨立數碼管的原理及方法,本實(shí)驗主要學(xué)習模數轉換器ADC的相關(guān)知識,串行(SPI接口)ADC芯片ADC081S101的驅動(dòng)設計,同時(shí)學(xué)習二進(jìn)制數轉換BCD碼的設計方法。

本文引用地址:http://dyxdggzs.com/article/202312/453845.htm
  • 學(xué)習模數轉換器ADC的相關(guān)知識
  • 串行(SPI接口)ADC芯片ADC081S101的驅動(dòng)設計
  • 學(xué)習二進(jìn)制數轉換BCD碼的設計方法
  • 完成簡(jiǎn)易設計實(shí)現

設計框圖

根據前面的實(shí)驗解析我們可以得知,該設計可以拆分成三個(gè)功能模塊實(shí)現,

  • ADC081S101driver: 驅動(dòng)SPI接口A(yíng)DC芯片實(shí)現模擬電壓信號采集。 * bintobcd:將二進(jìn)制數據轉換成BCD碼的方法。 * Segmentled:通過(guò)驅動(dòng)獨立式數碼管將電壓數據顯示出來(lái)。

Top-Down層次設計

 

模塊結構設計

實(shí)驗原理

ADC介紹

數字系統,是用數字信號完成對數字量進(jìn)行算術(shù)運算和邏輯運算的電路稱(chēng)為數字電路,或數字系統。而我們生活的世界是模擬的,想要讓數字系統幫我們處理我們模擬世界的問(wèn)題,就需要一個(gè)橋梁來(lái)溝通數字系統和模擬系統。

模擬數字系統通信

模數轉換器即A/D轉換器,或簡(jiǎn)稱(chēng)ADC,通常是指一個(gè)將模擬信號轉變?yōu)閿底中盘柕碾娮釉?。通常的模數轉換器是將一個(gè)輸入電壓信號轉換為一個(gè)輸出的數字信號。由于數字信號本身不具有實(shí)際意義,僅僅表示一個(gè)相對大小。故任何一個(gè)模數轉換器都需要一個(gè)參考模擬量作為轉換的標準,比較常見(jiàn)的參考標準為最大的可轉換信號大小。而輸出的數字量則表示輸入信號相對于參考信號的大小。

數模轉換器,又稱(chēng)D/A轉換器,簡(jiǎn)稱(chēng)DAC,它是把數字量轉變成模擬的器件。D/A轉換器基本上由4個(gè)部分組成,即權電阻網(wǎng)絡(luò )、運算放大器、基準電源和模擬開(kāi)關(guān)。模數轉換器中一般都要用到數模轉換器,模數轉換器即A/D轉換器,簡(jiǎn)稱(chēng)ADC,它是把連續的模擬信號轉變?yōu)殡x散的數字信號的器件。

作為模擬系統與數字系統轉換的橋梁,ADC和DAC有很多參數指標來(lái)標識其性能:

  • 分辨率(轉換精度):指ADC或DAC能夠采集或輸出最小電壓與最大電壓之比,也是最小輸入數字量1與最大輸入數字量2n-1之比。分辨率通常用數字量的位數表示,一般為8位、12位、16位等,N位的ADC或DAC的分辨率為2的N次方。
  • 量程(滿(mǎn)刻度范圍 FSR):指ADC或DAC能夠輸入或輸出模擬電壓的變化范圍。
  • 建立時(shí)間:建立時(shí)間是衡量DAC輸出達到最終值所需的時(shí)間,指接收到要求輸出的命令至輸出建立到一定精度范圍內(通常是0.5LSB、1LSB、2LSB)的時(shí)間。
  • 轉換時(shí)間:指ADC從發(fā)出轉換指令開(kāi)始到獲得穩定的二進(jìn)制代碼所需要的時(shí)間,轉換時(shí)間與ADC的類(lèi)型、原理和位數有關(guān)。

并行ADC和串行ADC模型

上圖兩個(gè)都是8位ADC模型,分辨率為 2的8次方等于256,即將Vref分成256份,能夠分辨的模擬步進(jìn)為Vref / 256,量化數據N = 256 * Vin / Vref 。

  • 并行ADC與數字電路接口包含一根clk和8根data管腳,clk為芯片時(shí)鐘管腳,data為芯片數據管腳,每個(gè)clk周期從data管腳采集8bit的數據,完成一次模數轉換,所以clk頻率等于采樣率。
  • 串行ADC(以ADC081S101為例)與數字電路接口為三根線(xiàn)(cs,clk,din),兼容三線(xiàn)SPI總線(xiàn),cs為芯片使能管腳,clk為芯片時(shí)鐘管腳,din為芯片數據管腳,當ADC芯片使能時(shí)每個(gè)clk周期從din采集1bit的數據,但是根據ADC081S101的時(shí)序,需要16個(gè)clk完成一次采樣,所以clk頻率至少等于采樣率的16倍。
ADC模塊電路連接

這里我們以底板上的ADC模塊電路,其電路圖如下:

ADC模塊電路

如ADC模塊電路所示,直接連接ADC081S101芯片的控制端,ADC有6個(gè)管腳,3腳Vin為VCC和Vref功能復用,即Vin = VCC = Vref。ADC前端是運放電路LMV721,運放模塊為電壓跟隨電路,再往前端是一個(gè)跳冒排針,用來(lái)選擇ADC采樣信號的來(lái)源,當短路帽將1、2腳短路時(shí),ADC采集電位計電壓,當短路帽將2、3腳短路時(shí),ADC采射頻端子或P4排針信號。本設計我們是采樣旋轉編碼器的電壓,所以需要用短路帽將1、2腳短路。

ADC模塊驅動(dòng)設計

前面我們了解ADC081S101芯片和FPGA之間連接有三根線(xiàn)(cs、clk、din),兼容SPI總線(xiàn),SPI是串行外設接口(Serial Peripheral Interface)的縮寫(xiě)。SPI是一種高速的,全雙工,同步的通信總線(xiàn),并且在芯片的管腳上只占用四根線(xiàn)(cs、sck、mosi、miso),事實(shí)上3根也可以(單向傳輸時(shí)),占用管腳少節約了芯片的管腳,同時(shí)為PCB的布局上節省空間,正是出于這種簡(jiǎn)單易用的特性,如今越來(lái)越多的芯片集成這種通信協(xié)議。

SPI設備分為主設備和從設備,設備之間共用sck、mosi和miso,另外每個(gè)從設備有一根cs線(xiàn)(不共用),通信在主設備和從設備之間進(jìn)行,從設備與從設備之間無(wú)法直接通信,主設備可以同時(shí)連接多個(gè)從設備,當主設備和某個(gè)從設備通信時(shí),先控制該從設備cs信號拉低,然后通過(guò)sck、mosi和miso進(jìn)行數據傳輸。

多設備SPI總線(xiàn)連接

為了讓SPI總線(xiàn)更加靈活應用,SPI總線(xiàn)分為4種模式,由兩個(gè)參數控制:

  • CPOL:時(shí)鐘極性選擇,為0時(shí)SCK空閑為低電平,為1時(shí)SCK空閑為高電平
  • CPHA:時(shí)鐘相位選擇,為0時(shí)在SCK第一個(gè)跳變沿采樣,為1時(shí)在SCK第二個(gè)跳變沿采樣
MODE0MODE1
MODE2MODE3

SPI總線(xiàn)協(xié)議4種模式

  • 模式1:CPOL=0,CPHA=0:此時(shí)空閑態(tài)時(shí),SCLK處于低電平,數據采樣是在第1個(gè)邊沿,也就是 SCLK由低電平到高電平的跳變,所以數據采樣是在上升沿,數據發(fā)送是在下降沿。
  • 模式2:CPOL=0,CPHA=1:此時(shí)空閑態(tài)時(shí),SCLK處于低電平,數據發(fā)送是在第1個(gè)邊沿,也就是 SCLK由低電平到高電平的跳變,所以數據采樣是在下降沿,數據發(fā)送是在上升沿。
  • 模式3:CPOL=1,CPHA=0:此時(shí)空閑態(tài)時(shí),SCLK處于高電平,數據采集是在第1個(gè)邊沿,也就是 SCLK由高電平到低電平的跳變,所以數據采集是在下降沿,數據發(fā)送是在上升沿。
  • 模式4:CPOL=1,CPHA=1:此時(shí)空閑態(tài)時(shí),SCLK處于高電平,數據發(fā)送是在第1個(gè)邊沿,也就是 SCLK由高電平到低電平的跳變,所以數據采集是在上升沿,數據發(fā)送是在下降沿。

ADC081S101管腳說(shuō)明表:

ADC081S101管腳說(shuō)明

注:SDATA信號在SCLK的節拍下傳輸數據,當SCLK下降沿時(shí)SDATA更新數據輸出,當驅動(dòng)程序編程時(shí)我們要在上升沿采樣數據可以得到穩定的輸出。

ADC081S101串行通信時(shí)序如下圖:

ADC081S101通信時(shí)序

注:

  1. SCLK空閑時(shí)為高電平,CPOL = 1,上升沿(第二個(gè)邊沿)采樣,CPHA = 1,如果例化通用SPI核完成設計,需要采用SPI的第四種工作模式。
  2. CS信號拉低有效,經(jīng)過(guò)16個(gè)時(shí)鐘完成一次ADC轉換并采樣,采樣回來(lái)的數據前3位無(wú)效,接下來(lái)為DB7~DB0(有效數據),再接下來(lái)為無(wú)效數據。

針對ADC081S101時(shí)序,我們用Verilog設計一個(gè)計數器,當計數器值不同時(shí)完成不同操作,實(shí)現一次ADC采樣,程序實(shí)現如下:

reg [7:0] cnt; //計數器
always @(posedge clk or negedge rst_n)
	if(!rst_n) cnt <= 1'b0;
	else if(cnt >= 8'd34) cnt <= 1'b0;
	else cnt <= cnt + 1'b1;
	reg [7:0] data;always @(posedge clk or negedge rst_n)
	if(!rst_n) begin
		adc_cs <= HIGH; adc_clk <= HIGH;
	end else case(cnt)
		8'd0 :  begin adc_cs <= HIGH; 
		adc_clk <= HIGH; end
		8'd1 :  begin adc_cs <= LOW;  
		adc_clk <= HIGH; end
		8'd2,8'd4,8'd6,8'd8,8'd10,8'd12,8'd14,8'd16,
		8'd18,8'd20,8'd22,8'd24,8'd26,8'd28,8'd30,8'd32:	
				begin adc_cs <= LOW;  
				adc_clk <= LOW;  
				end
		8'd3 :  begin adc_cs <= LOW;  
		adc_clk <= HIGH; 
		end //0
		8'd5 :  begin adc_cs <= LOW;  
		adc_clk <= HIGH; 
		end //1
		8'd7 :  begin adc_cs <= LOW;  
		adc_clk <= HIGH; 
		end //2
		8'd9 :  begin adc_cs <= LOW;  
		adc_clk <= HIGH; 
		data[7] <= adc_dat; 
		end //3
		8'd11 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; data[6] <= adc_dat; 
		end //4
		8'd13 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; data[5] <= adc_dat; 
		end //5
		8'd15 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; 
		data[4] <= adc_dat; 
		end //6
		8'd17 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; data[3] <= adc_dat; 
		end //7
		8'd19 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; data[2] <= adc_dat; 
		end //8
		8'd21 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; 
		data[1] <= adc_dat; 
		end //9
		8'd23 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; data[0] <= adc_dat; 
		end //10
		8'd25 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; adc_data <= data; 
		end //11
		8'd27 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; adc_done <= HIGH; 
		end //12
		8'd29 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; adc_done <= LOW; 
		end //13
		8'd31 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; 
		end //14
		8'd33 : begin adc_cs <= LOW;  
		adc_clk <= HIGH; 
		end //15
		8'd34 : begin adc_cs <= HIGH;  
		adc_clk <= HIGH; 
		end
		default : begin adc_cs <= HIGH;  
		adc_clk <= HIGH;  
		end
	endcase

到這我們就完成了串行ADC芯片ADC081S101的驅動(dòng)設計,整個(gè)采樣周期用了35個(gè)系統時(shí)鐘,如果我們采用12MHz時(shí)鐘作為該模塊系統時(shí)鐘,采樣率Fs = 12M/35 = 343Ksps,ADC主頻Fsclk = 12 MHz /2 = 6MHz。

ADC081S101主頻及采樣率要求如下,按照要求我們當前的主頻和采樣率不足,所以在使用該模塊時(shí),可以使用更高的時(shí)鐘(比如24MHz)以達到芯片的要求

ADC081S101速度

注:時(shí)鐘頻率Fsclk,最小值為10MHz,最大值為20MHz,采樣率在500Ksps~1Msps

模塊接口如下:clk和rstn為系統時(shí)鐘及復位,adccs,adcclk和adcdat為ADC控制管腳,adcdata為ADC采樣數據,adcdone產(chǎn)生一個(gè)脈沖對應adc_data得到一個(gè)有效數據

module ADC081S101_driver
(
input				clk,		//系統時(shí)鐘
input				rst_n,  	//系統復位,低有效
output	reg			adc_cs,		//SPI總線(xiàn)CS
output	reg			adc_clk,	//SPI總線(xiàn)SCK
input				adc_dat,	//SPI總線(xiàn)SDA
output	reg			adc_done,	//ADC采樣完成標志
output	reg [7:0]		adc_data	//ADC采樣數據
);
系統總體實(shí)現

因為需要更高的時(shí)鐘供ADC模塊使用,我們例化pll核得到24MHz時(shí)鐘,例化PLL的方法我們在基礎數字電路實(shí)驗部分已經(jīng)練習過(guò),這里就簡(jiǎn)單描述一下過(guò)程

打開(kāi)Tools菜單下的IP Catalog工具,依次找到Libraty → Basic Functions → Clocks; PLLs and Resets → PLL → ALTPLL,打開(kāi)ALTPLL彈出配置界面,配置inclk0輸入為12MHz,配置c0的時(shí)鐘輸出為24MHz,其他所有選項全部默認,點(diǎn)擊Finish完成pll的IP核例化。

在頂層模塊VoltageMeas中,同時(shí)例化pll模塊和ADC081S101driver模塊,并將pll的c0輸出與ADC081S101_driver模塊的clk連線(xiàn)。

PLL

 

PLL

Pll模塊和ADC081S101_driver模塊的連接程序實(shí)現如下:

wire clk_24mhz,locked;
pll u1
(
.areset				(!rst_n			), //pll模塊的復位為高有效
.inclk0				(clk			), //12MHz系統時(shí)鐘輸入
.c0					(clk_24mhz		), //24MHz時(shí)鐘輸出
.locked				(locked			)  //pll lock信號輸出
); 
wire adc_done;
wire [7:0] adc_data;//使用I2C總線(xiàn)驅動(dòng)PCF8591的ADC功能,例化
ADC081S101_driver u2(.clk				(clk_24mhz		),	//系統時(shí)鐘
.rst_n				(rst_n			),	//系統復位,低有效
.adc_cs				(adc_cs			),	//SPI總線(xiàn)CS
.adc_clk			(adc_clk		),	//SPI總線(xiàn)SCK
.adc_dat			(adc_dat		),	//SPI總線(xiàn)SDA
.adc_done			(adc_done		),	//ADC采樣完成標志
.adc_data			(adc_data		)	//ADC采樣數據
);

現在可以得到ADC采樣數據了,假設ADC模擬輸入電壓為3.3V,理論上我們得到的采樣數據adc_data應該為8’hff,而最終顯示在數碼管上的數據應該為3.3,我們如何將8’hff轉換成可以顯示的3.3數據呢?這就設計到ADC量化數據的逆向運算了,

我們知道量化運算 N = 256 * Vin / Vref,

那么逆向運算為Vin = N * Vref / 256,其中Vref = 3.3V,所以Vin = N * 0.0129

所以我們需要用FPGA計算adc_data * 0.0129的結果,然后為了使用十進(jìn)制的顯示,先將結果進(jìn)行BCD轉碼,然后顯示在數碼管上。

將ADC采樣數據按規則轉換為電壓數據(乘以0.0129),這里我們直接乘以129,得到的數據經(jīng)過(guò)BCD轉碼后小數點(diǎn)左移4位即可,程序實(shí)現如下:

wire [15:0] bin_code = adc_data * 16'd129;

將二進(jìn)制數轉換成BCD碼的形式,采用左移加三的算法(以8’hff為例): 1、左移要轉換的二進(jìn)制碼1位 2、左移之后,BCD碼分別置于百位、十位、個(gè)位 3、如果移位后所在的BCD碼列大于或等于5,則對該值加3 4、繼續左移的過(guò)程直至全部移位完成

Bin to BCD

二進(jìn)制轉BCD碼程序實(shí)現如下:

reg		[35:0]		shift_reg; 
always@(bin_code or rst_n)begin
	shift_reg = {20'h0,bin_code};
	if(!rst_n) bcd_code = 0; 
	else begin 
		repeat(16) begin //循環(huán)16次  
			//BCD碼各位數據作滿(mǎn)5加3操作,
			if (shift_reg[19:16] >= 5) shift_reg[19:16] = shift_reg[19:16] + 2'b11;
			if (shift_reg[23:20] >= 5) shift_reg[23:20] = shift_reg[23:20] + 2'b11;
			if (shift_reg[27:24] >= 5) shift_reg[27:24] = shift_reg[27:24] + 2'b11;
			if (shift_reg[31:28] >= 5) shift_reg[31:28] = shift_reg[31:28] + 2'b11;
			if (shift_reg[35:32] >= 5) shift_reg[35:32] = shift_reg[35:32] + 2'b11;
			shift_reg = shift_reg << 1; 
		end
		bcd_code = shift_reg[35:16];   
	end 
	end

最后得到20位的數據輸出,每4位表示一個(gè)BCD碼,所以有5位有效數據,這里我們還需要將小數點(diǎn)左移4位,計算出來(lái)的數應該是X.XXXX伏特,1個(gè)整數位和4個(gè)小數位,核心板上只有兩個(gè)數碼管,取最高的兩個(gè)BCD碼顯示到數碼管X.X伏特,個(gè)位小數點(diǎn)點(diǎn)亮,分位小數點(diǎn)熄滅,程序實(shí)現如下:

//個(gè)位數碼管模塊例化	Segment_led u4(.seg_dot			(1'b1			),	//seg_dot input
.seg_data			(bcd_code[19:16]),	//seg_data input
.segment_led		(seg_1			)	//MSB~LSB = SEG,DP,G,F,E,D,C,B,A
); //分位數碼管模塊例化
Segment_led u5(.seg_dot			(1'b0			),	//seg_dot input
.seg_data			(bcd_code[15:12]),	//seg_data input
.segment_led		(seg_2			)	//MSB~LSB = SEG,DP,G,F,E,D,C,B,A
);

綜合后的設計框圖如下:

RTL設計框圖

實(shí)驗步驟

  1. 雙擊打開(kāi)Quartus Prime工具軟件;
  2. 新建工程:File → New Project Wizard(工程命名,工程目錄選擇,設備型號選擇,EDA工具選擇);
  3. 新建文件:File → New → Verilog HDL File,鍵入設計代碼并保存;
  4. 設計綜合:雙擊Tasks窗口頁(yè)面下的Analysis & Synthesis對代碼進(jìn)行綜合;
  5. 管腳約束:Assignments → Assignment Editor,根據項目需求分配管腳;
  6. 設計編譯:雙擊Tasks窗口頁(yè)面下的Compile Design對設計進(jìn)行整體編譯并生成配置文件;
  7. 程序燒錄:點(diǎn)擊Tools → Programmer打開(kāi)配置工具,Program進(jìn)行下載;
  8. 觀(guān)察設計運行結果。

實(shí)驗現象

將程序下載到FPGA中,P3接口用短路帽將1、2腳短路,旋轉底板右上角的電位計,觀(guān)察核心板數碼管變化,如果有萬(wàn)用表可以測量P3短路處的電壓,與數碼管顯示對比。



評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>