基于FPGA的LM75A温度传感器VHDL.docx
《基于FPGA的LM75A温度传感器VHDL.docx》由会员分享,可在线阅读,更多相关《基于FPGA的LM75A温度传感器VHDL.docx(28页珍藏版)》请在冰点文库上搜索。
基于FPGA的LM75A温度传感器VHDL
1.编写的程序
(一)功能模块:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
--实体--
entityat24c08is
port(
clk:
instd_logic;--时钟信号
rst:
instd_logic;--复位信号
scl:
outstd_logic;--i2c时钟线
sda:
inoutstd_logic;--i2c数据线
urv_1:
instd_logic;--上限值1
urv_2:
instd_logic;--上限值2
sel:
outstd_logic_vector(3downto0);
seg:
outstd_logic_vector(7downto0);
beep:
outstd_logic--蜂鸣器输出信号线
);
endat24c08;
--结构体--
architecturearch_at24c08ofat24c08is
signalclk_sslow:
std_logic;
signalcounter:
std_logic_vector(23downto0);
signalreaddata_reg_buf:
std_logic_vector(15downto0);
signalreaddata_ten:
integerrange0to24564;
signalreaddata_std:
std_logic_vector(15downto0);
signalqian:
std_logic_vector(3downto0);
signalbai:
std_logic_vector(3downto0);
signalshi:
std_logic_vector(3downto0);
signalge:
std_logic_vector(3downto0);
signalqian_0:
integerrange0to10;
signalbai_0:
integerrange0to10;
signalshi_0:
integerrange0to10;
signalge_0:
integerrange0to10;
--数码管部分信号
signalsel_0:
std_logic_vector(3downto0);
signalseg_0:
std_logic_vector(7downto0);
signalcount:
std_logic_vector(13downto0);
signalclk_slow:
std_logic;
signalscan_num:
std_logic_vector(1downto0);
signalseg_data_buf:
std_logic_vector(3downto0);
--i2c部分信号
signalsda_buf:
std_logic;--i2c输入/输出数据寄存器
signallink:
std_logic;--sda输入输出方向寄存器
signalreaddata_reg:
std_logic_vector(15downto0);--i2c读回的数据寄存器
signalsda_0:
std_logic;--与sda端口连接信号
signalscl_0:
std_logic;--与scl端口连接信号
--按键消抖部分信号
signaldelay_cnt:
std_logic_vector(19downto0);--消抖延时计数器
signalstart_delay:
std_logic;--按键延时开始
--分频部分信号
signalclk_div:
std_logic_vector(12downto0);--分频计数器,5000分频,10khz
--蜂鸣器部分信号
signalbeep_en:
std_logic;--蜂鸣器使能信号
signalbeep_buf:
std_logic;--与beep端口连接的信号
--时钟部分信号
signallevel_high:
std_logic;--高电平中间值,1249
signallevel_low:
std_logic;--低电平中间值,3749
signallevel_hig_edge:
std_logic;--上升沿,4999
signallevel_low_edge:
std_logic;--下降沿,2499
--状态机部分信号
signalmain_state:
std_logic_vector(1downto0);--状态机主状态
signali2c_state:
std_logic_vector(2downto0);--i2c状态
signali2c_per_state:
std_logic_vector(3downto0);--i2c每一步状态
--分频部分常量
constantdiv_parameter:
std_logic_vector(12downto0):
="1001110001000";--分频系数,500
--状态机部分常量
--操作状态常量
constantread_init:
std_logic_vector(2downto0):
="000";--EEPORM初始化
constantread_high:
std_logic_vector(2downto0):
="001";--读高位数据状态
constantread_low:
std_logic_vector(2downto0):
="010";--读低位数据状态
--i2c每一步状态常量
constantstart:
std_logic_vector(3downto0):
="0000";
--开始位
constantfirst:
std_logic_vector(3downto0):
="0001";
--数据第一位
constantsecond:
std_logic_vector(3downto0):
="0010";
--数据第二位
constantthird:
std_logic_vector(3downto0):
="0011";
--数据第三位
constantfourth:
std_logic_vector(3downto0):
="0100";
--数据第四位
constantfifth:
std_logic_vector(3downto0):
="0101";
--数据第五位
constantsixth:
std_logic_vector(3downto0):
="0110";
--数据第六位
constantseventh:
std_logic_vector(3downto0):
="0111";
--数据第七位
constanteighth:
std_logic_vector(3downto0):
="1000";
--数据第八位
constantack:
std_logic_vector(3downto0):
="1001";
--应答位
constantstop:
std_logic_vector(3downto0):
="1010";
--停止位
--结构体开始
begin
scl<=scl_0;
seg<=seg_0;
sda_0<=sda_bufwhen(link)='1'else'Z';
sda<=sda_0;
sel<=sel_0;
beep<=beep_buf;
--按键消抖
key:
process(clk,rst)
begin
if(notrst='1')then
delay_cnt<=(others=>'0');
elsif(clk'eventandclk='1')then
ifstart_delay='1'then
if(delay_cnt/="11110100001001000000")then--20ms延时
delay_cnt<=delay_cnt+'1';
else
delay_cnt<=(others=>'0');
endif;
endif;
endif;
endprocesskey;
--分频部分
div:
process(rst,clk)
begin
if(notrst='1')then
clk_div<="0000000000000";
level_high<='0';
level_low<='0';
level_hig_edge<='0';
level_low_edge<='0';
elsif(clk'eventandclk='1')then
if(clk_div/=div_parameter-'1')then
clk_div<=clk_div+'1';
else
clk_div<="0000000000000";
endif;
if(level_high='1')then
level_high<='0';
else
if(clk_div="10011100001")then
level_high<='1';
endif;
endif;
if(level_low_edge='1')then
level_low_edge<='0';
else
if(clk_div="100111000011")then
level_low_edge<='1';
endif;
endif;
if(level_low='1')then
level_low<='0';
else
if(clk_div="111010100101")then
level_low<='1';
endif;
endif;
if(level_hig_edge='1')then
level_hig_edge<='0';
else
if(clk_div="1001110000111")then
level_hig_edge<='1';
endif;
endif;
endif;
endprocessdiv;
--EEPROM操作部分
state:
process(clk,rst)
begin
if(notrst='1')then
start_delay<='0';
scl_0<='1';
sda_buf<='1';
link<='0';
readdata_reg<="0000000000000000";
main_state<="00";
i2c_state<=read_init;
i2c_per_state<=start;
elsif(clk'eventandclk='1')then
casemain_stateis
--初始化EEPROM
when"00"=>--等待读写要求
scl_0<='1';
sda_buf<='1';
link<='0';
i2c_state<=read_init;
i2c_per_state<=start;
main_state<="10";
--读取EEPRO数据
when"10"=>
if(level_hig_edge='1')then
scl_0<='1';
else
if(level_low_edge='1')then
scl_0<='0';
endif;
endif;
casei2c_stateis
whenread_init=>--读命令地址
casei2c_per_stateis
whenstart=>
if(level_high='1')then
sda_buf<='0';
link<='1';
endif;
if((level_lowandlink)='1')then
link<='1';
sda_buf<='1';
i2c_per_state<=first;
endif;
whenfirst=>
if(level_low='1')then
sda_buf<='0';
link<='1';
i2c_per_state<=second;
endif;
whensecond=>
if(level_low='1')then
sda_buf<='0';
link<='1';
i2c_per_state<=third;
endif;
whenthird=>
if(level_low='1')then
sda_buf<='1';
link<='1';
i2c_per_state<=fourth;
endif;
whenfourth=>
if(level_low='1')then
sda_buf<='0';
link<='1';
i2c_per_state<=fifth;
endif;
whenfifth=>
if(level_low='1')then
sda_buf<='0';
link<='1';
i2c_per_state<=sixth;
endif;
whensixth=>
if(level_low='1')then
sda_buf<='0';
link<='1';
i2c_per_state<=seventh;
endif;
whenseventh=>
if(level_low='1')then
sda_buf<='1';
link<='1';
i2c_per_state<=eighth;
endif;
wheneighth=>
if(level_low='1')then
link<='0';
i2c_per_state<=ack;
endif;
whenack=>
if(level_hig_edge='1')then
sda_buf<=sda;
endif;
if(level_high='1')then
if(sda_buf='1')then
main_state<="00";
endif;
endif;
if(level_low='1')then
link<='0';
i2c_state<=read_high;
i2c_per_state<=first;
endif;
whenothers=>null;
endcase;
whenread_high=>--读回数据
casei2c_per_stateis
whenfirst=>
if(level_hig_edge='1')then
sda_buf<=sda;
endif;
if(level_high='1')then
readdata_reg(15downto9)<=readdata_reg(14downto8);
readdata_reg(8)<=sda;
endif;
if(level_low='1')then
i2c_per_state<=second;
endif;
whensecond=>
if(level_hig_edge='1')then
sda_buf<=sda;
endif;
if(level_high='1')then
readdata_reg(15downto9)<=readdata_reg(14downto8);
readdata_reg(8)<=sda;
endif;
if(level_low='1')then
i2c_per_state<=third;
endif;
whenthird=>
if(level_hig_edge='1')then
sda_buf<=sda;
endif;
if(level_high='1')then
readdata_reg(15downto9)<=readdata_reg(14downto8);
readdata_reg(8)<=sda;
endif;
if(level_low='1')then
i2c_per_state<=fourth;
endif;
whenfourth=>
if(level_hig_edge='1')then
sda_buf<=sda;
endif;
if(level_high='1')then
readdata_reg(15downto9)<=readdata_reg(14downto8);
readdata_reg(8)<=sda;
endif;
if(level_low='1')then
i2c_per_state<=fifth;
endif;
whenfifth=>
if(level_hig_edge='1')then
sda_buf<=sda;
endif;
if(level_high='1')then
readdata_reg(15downto9)<=readdata_reg(14downto8);
readdata_reg(8)<=sda;
endif;
if(level_low='1')then
i2c_per_state<=sixth;
endif;
whensixth=>
if(level_hig_edge='1')then
sda_buf<=sda;
endif;
if(level_high='1')then
readdata_reg(15downto9)<=readdata_reg(14downto8);
readdat