基于FPGA+XADC读取温度(附代码)

好久没有写文章了,这会正在跑工程,我顺便写一下这两天调的一个功能。这个功能实现的目的是获取FPGA内核温度,并将内核温度进行输出显示。那么,怎么去实现这个功能呢?主要分以下几步:一、配置XADC IP核;二、编写读温度时序逻辑;三、温度解算。下面将展开说明。

一、配置XADC IP核

①在Vivado软件 IP Catalog中搜索“XADC”,打开XADC Wizard,如下图所示;

②根据下图进行配置。

二、编写读温度时序逻辑

在编程代码之前需要知道DRP接口的时序关系,如下图所示。

FPGA读时序代码如下:

	process(clk,rst)
	begin
		if rst = '1' then
			di_in		<=	(others => '0');
			daddr_in	<=	(others => '0');	--XADC温度传感器数据读取寄存器地址
			den_in		<=	'0';
			dwe_in		<=	'0';			
		elsif rising_edge (clk) then
			
			if cnt_time = 999999 then				--采样频率设置为100Hz,模块时钟100MHz
				cnt_time 	<= 	(others => '0');
				daddr_in	<=	(others => '0');	--XADC温度传感器数据读取寄存器地址
				den_in		<=	'1';
				dwe_in		<=	'0';
			else
				cnt_time	<=	cnt_time + 1;
				den_in		<=	'0';
				dwe_in		<=	'0';			
			end if;
		end if;
	end process;

 XADC例化如下:

	u_xadc : xadc
	port map(
				di_in 					=>	di_in		,
				daddr_in 				=>	daddr_in	,
				den_in 					=>	den_in		,
				dwe_in 					=>	dwe_in		,
				dclk_in 				=>	clk			,
				reset_in 				=>	rst			,
				vp_in 					=>	'0'			,
				vn_in 					=>	'0'			,
				
				drdy_out 				=>	drdy_out	,
				do_out 					=>	do_out		,
				channel_out 			=>	open		,
				eoc_out 				=>	open		,
				alarm_out 				=>	open		,
				eos_out 				=>	open		,
				busy_out 				=>	open		
	);

 三、温度解算

温度解算的方法如下:

 需要注意将输出的do_out取值为高12bit

 Note: The ADCs always produce a 16-bit conversion result. The 12-bit data correspond to the 12 MSBs (most significant) in the 16-bit status registers.

温度解算代码如下:

	process(clk,rst)
	begin
		if rst = '1' then
			data_out			<=	(others => '0');
			temp_polarity_flag	<=	'1';
		elsif rising_edge (clk) then			
			if drdy_out = '1' then
				if do_out(15 downto 4) >= 2219 and do_out(15 downto 4) <= 3250 then	
					data_out <= ("000" & do_out(15 downto 4) & "000000000") - ("000000000" & do_out(15 downto 4) & "000");	
					temp_polarity_flag	<= '1';
				elsif do_out(15 downto 4) >= 1186 and do_out(15 downto 4) < 2219 then	
					data_out <= ("000" & do_out(15 downto 4) & "000000000") - ("000000000" & do_out(15 downto 4) & "000");	
					temp_polarity_flag	<= '0';
				else
					data_out <= conv_std_logic_vector(3251,24);		
				end if;
			else
				data_out	<=	data_out;
			end if;
		end if;
	end process;
	
	process(clk,rst)
	begin
		if rst = '1' then
			temp_data	<=	(others => '0');
			drdy_out_r0 <=	'0';			
		elsif rising_edge (clk) then
			drdy_out_r0	<=	drdy_out;

			if drdy_out_r0 = '1' and temp_polarity_flag = '1' then
				temp_data <=  (x"000" & data_out(23 downto 12)) - 273;	
			elsif drdy_out_r0 = '1' and temp_polarity_flag = '0' then
				temp_data <=  273 - (x"000" & data_out(23 downto 12));	
			end if;
		end if;
	end process;
	
	process(clk,rst)
	begin
		if rst = '1' then
			xadc_temp_data	<= (others => '0');		
		elsif rising_edge (clk) then
			if temp_polarity_flag = '1' then	--温度为正
				xadc_temp_data <= '0' & temp_data(6 downto 0);	--b7为0表示正,b7为1表示负
			else								--温度为负
				xadc_temp_data <= '1' & temp_data(6 downto 0);
			end if;
		end if;
	end process;

 四、实际效果

五、总结

以上几步可以正确的解析出FPGA核温,方法简单,无需进行乘除运算,降低资源开销。但会损失温度小数点精度。 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值