ds18B20FPGAVHDL语言.docx
《ds18B20FPGAVHDL语言.docx》由会员分享,可在线阅读,更多相关《ds18B20FPGAVHDL语言.docx(12页珍藏版)》请在冰点文库上搜索。
ds18B20FPGAVHDL语言
----------VHDL语言编写DS18B20温度传感器程序
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entityds18B20is
port(clk:
instd_logic;---50MHz
dq:
inoutstd_logic;
rst:
instd_logic;
LED:
outstd_logic;
LED2:
outstd_logic;
LED3:
outstd_logic;
dataout1,dataout2,dataout3:
outstd_logic_vector(6downto0));--数
endds18B20;
architectureBehavioralofds18B20is
TYPESTATE_TYPEis(RESET,CMD_CC,WRITE_BYTE,WRITE_LOW,WRITE_HIGH,READ_BIT,
CMD_44,CMD_BE,WAIT800MS,GET_TMP,WAIT4MS);
signalSTATE:
STATE_TYPE:
=RESET;
signalclk_temp:
std_logic:
='0';
signalclk1m:
std_logic;--分频后得到的1M时钟
signalcp:
std_logic;--1ms时钟
signalw:
integerrange0to2:
=0;---xianshishunxu
signalwrite_temp:
std_logic_vector(7downto0):
="00000000";
signalTMP:
std_logic_vector(11downto0);
signaltmp_bit:
std_logic;
signalWRITE_BYTE_CNT:
integerrange0to8:
=0;
signalWRITE_LOW_CNT:
integerrange0to2:
=0;
signalWRITE_HIGH_CNT:
integerrange0to2:
=0;
signalREAD_BIT_CNT:
integerrange0to3:
=0;
signalGET_TMP_CNT:
integerrange0to13:
=0;
signalcnt:
integerrange0to100_001:
=0;
----------******************************
signalcnt2:
integerrange0to4000001:
=0;
signaltemp:
std_logic;
signaldata_temp0:
std_logic_vector(15downto0);
signaldecimal0:
std_logic_vector(15downto0);
signaldecimal1:
std_logic_vector(15downto0);
signaldecimal2:
std_logic_vector(15downto0);
signaldecimal3:
std_logic_vector(15downto0);
signaldata_temp1:
std_logic_vector(7downto0);
signalinteger0:
std_logic_vector(7downto0);
signalinteger1:
std_logic_vector(7downto0);
signalinteger2:
std_logic_vector(7downto0);
signalinteger3:
std_logic_vector(7downto0);
signalinteger4:
std_logic_vector(7downto0);
signalinteger5:
std_logic_vector(7downto0);
signalinteger6:
std_logic_vector(7downto0);
signalsign:
std_logic_vector(7downto0);
signalcount:
integerrange0to51:
=0;
signalWRITE_BYTE_FLAG:
integerrange0to4:
=0;
functiondis(num:
std_logic_vector)returnstd_logic_vectoris
begin
casenumis
when"0000"=>return"1000000";--0
when"0001"=>return"1111001";--1
when"0010"=>return"0100100";--2
when"0011"=>return"0110000";--3
when"0100"=>return"0011001";--4
when"0101"=>return"0010010";--5
when"0110"=>return"0000010";--6
when"0111"=>return"1111000";--7
when"1000"=>return"0000000";--8
when"1001"=>return"0010000";--9
when"1010"=>return"0001000";--A
when"1011"=>return"0000011";--b
when"1100"=>return"1000110";--C
when"1101"=>return"0100001";--d
when"1110"=>return"0000110";--E
when"1111"=>return"0001110";--F
whenothers=>return"1111111";--mie
endcase;
enddis;
begin
----------@@@@@@@@@@@@@----------------
ClkDivider:
process(clk,clk_temp)
begin
ifrising_edge(clk)then
if(count=24)then
count<=0;
clk_temp<=notclk_temp;
else
count<=count+1;
endif;
endif;
clk1m<=clk_temp;
endProcess;
----------@@@@@@@@@@@@@----------------
process(clk1m)
variablen:
integerrange0to12000:
=0;
begin-----cp1ms
ifrising_edge(clk1m)then
n:
=n+1;
if(n>12000)thenn:
=0;cp<=notcp;endif;
endif;
endProcess;
STATE_TRANSITION:
process(STATE,clk1m)
begin
ifrising_edge(clk1m)then
if(rst='0')then
STATE<=RESET;
else
caseSTATEis
whenRESET=>
--**********
LED2<='0';--*************-
LED3<='0';
--*********
if(cnt>=0andcnt<500)then--500μs的复位低电平
dq<='0';--dq作为输出
cnt<=cnt+1;
STATE<=RESET;
elsif(cnt>=500andcnt<510)then--高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,高阻态可以应用在inout端口里面,这样在inout没有输出的时候就弄个高阻态,这样就其电平就可以由外面的输入信号决定了
dq<='Z';
cnt<=cnt+1;
STATE<=RESET;--拉高dq
elsif(cnt>=510andcnt<750)then--240μs
temp<=dq;--dq作为输入
if(cnt=580)then
temp<=dq;
if(temp='1')then
LED<='0';
elseLED<='1';
endif;
endif;
cnt<=cnt+1;
STATE<=RESET;
elsif(cnt>=750)then
cnt<=0;--计数器清零
STATE<=CMD_CC;--复位过程伴随着跳跃rom指令“CC”
endif;
whenCMD_CC=>--跳跃rom指令“CC”
LED2<='1';
LED3<='0';
write_temp<="11001100";
STATE<=WRITE_BYTE;
whenWRITE_BYTE=>
caseWRITE_BYTE_CNTis
when0to7=>
if(write_temp(WRITE_BYTE_CNT)='0')then
STATE<=WRITE_LOW;
LED3<='1';
else
STATE<=WRITE_HIGH;
endif;
WRITE_BYTE_CNT<=WRITE_BYTE_CNT+1;
when8=>
if(WRITE_BYTE_FLAG=0)then--第一次写0XCC完毕
STATE<=CMD_44;
WRITE_BYTE_FLAG<=1;
elsif(WRITE_BYTE_FLAG=1)then--写0X44完毕(写温度转换指令后没有读数据?
)
STATE<=RESET;
WRITE_BYTE_FLAG<=2;
elsif(WRITE_BYTE_FLAG=2)then--第二次写0XCC完毕
STATE<=CMD_BE;
WRITE_BYTE_FLAG<=3;
elsif(WRITE_BYTE_FLAG=3)then--写0XBE完毕
STATE<=GET_TMP;
WRITE_BYTE_FLAG<=0;
endif;
WRITE_BYTE_CNT<=0;
whenothers=>STATE<=RESET;
endcase;
whenWRITE_LOW=>
LED3<='1';
caseWRITE_LOW_CNTis
when0=>
dq<='0';
if(cnt=70)then
cnt<=0;
WRITE_LOW_CNT<=1;
else
cnt<=cnt+1;
endif;
when1=>
dq<='Z';
if(cnt=5)then
cnt<=0;
WRITE_LOW_CNT<=2;
else
cnt<=cnt+1;
endif;
when2=>
STATE<=WRITE_BYTE;
WRITE_LOW_CNT<=0;
whenothers=>WRITE_LOW_CNT<=0;
endcase;
whenWRITE_HIGH=>
caseWRITE_HIGH_CNTis
when0=>
dq<='0';
if(cnt=8)then
cnt<=0;
WRITE_HIGH_CNT<=1;
else
cnt<=cnt+1;
endif;
when1=>
dq<='Z';
if(cnt=72)then
cnt<=0;
WRITE_HIGH_CNT<=2;
else
cnt<=cnt+1;
endif;
when2=>
STATE<=WRITE_BYTE;
WRITE_HIGH_CNT<=0;
whenothers=>WRITE_HIGH_CNT<=0;
endcase;
whenCMD_44=>
write_temp<="01000100";
STATE<=WRITE_BYTE;
whenCMD_BE=>
write_temp<="10111110";
STATE<=WRITE_BYTE;
----------------------------------
whenREAD_BIT=>
caseREAD_BIT_CNTis
when0=>
dq<='0';--4μs的低电平
if(cnt=4)then
READ_BIT_CNT<=1;
cnt<=0;
else
cnt<=cnt+1;
endif;
when1=>
dq<='Z';--4μs的高电平
if(cnt=4)then
READ_BIT_CNT<=2;
cnt<=0;
else
cnt<=cnt+1;
endif;
when2=>
dq<='Z';
TMP_BIT<=dq;--12μs读出数据,就是最后一次赋值的结果。
if(cnt=4)then
READ_BIT_CNT<=3;
cnt<=0;
else
cnt<=cnt+1;
endif;
when3=>
---------------------
dq<='Z';--控制器拉高总线
---------------------
if(cnt=50)then--读出数据后,等待50us
cnt<=0;
READ_BIT_CNT<=0;
STATE<=GET_TMP;
else
cnt<=cnt+1;
endif;
whenothers=>READ_BIT_CNT<=0;
endcase;
-------#################--------------
whenGET_TMP=>
caseGET_TMP_CNTis
when0=>
STATE<=READ_BIT;
GET_TMP_CNT<=GET_TMP_CNT+1;
when1to12=>
STATE<=READ_BIT;
TMP(GET_TMP_CNT-1)<=TMP_BIT;--将读出的每一位数据按顺序存进TMP(0to11)里面
GET_TMP_CNT<=GET_TMP_CNT+1;--存的是读出的0到11位,第十二位没有存
when13=>
GET_TMP_CNT<=0;
STATE<=WAIT4MS;
endcase;
whenWAIT4MS=>
if(cnt>=4000)then
--STATE<=WAIT4MS;
STATE<=RESET;
cnt<=0;
else
cnt<=cnt+1;
STATE<=WAIT4MS;
endif;
whenothers=>STATE<=RESET;
LED<='0';
LED2<='0';
LED3<='0';
endcase;
endif;
endif;
endprocess;
-----------------------------------------------
DISPLAY:
process(cp)--------数码管动态显示温度值
variabletemp:
std_logic_vector(3downto0);
begin
casewis
when0=>temp:
=TMP(3downto0);dataout1<=dis(temp);w<=1;
when1=>temp:
=TMP(7downto4);dataout2<=dis(temp);w<=2;
when2=>temp:
=TMP(11downto8);dataout3<=dis(temp);w<=0;
endcase;
endprocess;
endBehavioral;