第一篇:基于FPGA的電壓表
FPGA控制的數(shù)字電壓表電路設(shè)計(jì)
李培
(河南科技大學(xué)電子信息工程學(xué)院 河南洛陽(yáng) 471003)
摘 要:介紹數(shù)字電壓表的組成及工作原理,論述了基于VHDL語(yǔ)言和FPGA芯片的數(shù)字系統(tǒng)的設(shè)計(jì)思想和實(shí)現(xiàn)過(guò)程。
關(guān)鍵詞:數(shù)字電壓表;VHDL語(yǔ)言;FPGA
VHDL Realization of Digital Voltmeter
Abstract: The composition and working principle of digital voltm eter were introduced in this paper, the designing idea and implementation proces s based on VHDL and FPGA were also described.Key words: digital voltmeter;VHDL;FPGA 引言
在硬件電子電路設(shè)計(jì)領(lǐng)域中,電子設(shè)計(jì)自動(dòng)化(EDA)工具已成為主要的設(shè)計(jì)手段,而VHDL語(yǔ)言則是EDA的關(guān)鍵技術(shù)之一,它采用自頂向下的設(shè)計(jì)方法,即從系統(tǒng)總體要求出發(fā),自上至下地將設(shè)計(jì)任務(wù)分解為不同的功能模塊,最后將各功能模塊連接形成頂層模塊,完成系統(tǒng)硬件的整體設(shè)計(jì)。本文用FPGA芯片和VHDL語(yǔ)言設(shè)計(jì)了一個(gè)數(shù)字電壓表,舉例說(shuō)明了利用VHDL語(yǔ)言實(shí)現(xiàn)數(shù)字系統(tǒng)的過(guò)程。
1.系統(tǒng)組成及工作原理
整個(gè)數(shù)字電壓表的硬件結(jié)構(gòu)如圖1所示。
系統(tǒng)的核心電路由FPGA完成,本設(shè)計(jì)選用了Altera公司的EPlKl00QC208-3芯片,用VHDL語(yǔ)言對(duì)它進(jìn)行設(shè)計(jì),實(shí)現(xiàn)三大功能模塊:(1)控制模塊,激活A(yù)/D轉(zhuǎn)換器動(dòng)作、接收A/D轉(zhuǎn)換器傳遞過(guò)來(lái)的數(shù)字轉(zhuǎn)換值;(2)數(shù)據(jù)處理模塊,將接收到的轉(zhuǎn)換值調(diào)整成對(duì)應(yīng)的數(shù)字信號(hào);(3)掃描、顯示模塊,產(chǎn)生數(shù)碼管的片選信號(hào),并將數(shù)值處理模塊輸出的BCD碼譯成相應(yīng)的7段數(shù)碼驅(qū)動(dòng)值。
工作時(shí),系統(tǒng)按一定的速率采集輸入的模擬電壓,經(jīng)ADC0804轉(zhuǎn)換為8位數(shù)字量,此8位數(shù)字量經(jīng)FPGA處理得到模擬電壓的數(shù)字碼,再輸入數(shù)碼管獲得被測(cè)電壓的數(shù)字顯示。
此電壓表的測(cè)量范圍:0~5V,三位數(shù)碼管顯示。
2.FPGA功能模塊的設(shè)計(jì)
數(shù)字電壓表的三大模塊都是用VHDL語(yǔ)言編程實(shí)現(xiàn)的。2.1控制模塊
用狀態(tài)機(jī)作法,產(chǎn)生ADC0804的片選信號(hào)、讀/寫(xiě)控制信號(hào),通過(guò)狀態(tài)信號(hào)INTR判斷轉(zhuǎn)換是否結(jié)束;轉(zhuǎn)換結(jié)束后將轉(zhuǎn)換數(shù)據(jù)鎖存并輸出。其狀態(tài)轉(zhuǎn)換圖如圖2所示。
State machine viewer
A/D模塊如下:
2.2數(shù)據(jù)處理模塊
ADC0804是8位模數(shù)轉(zhuǎn)換器,它的輸出狀態(tài)共有28=256種,如果輸入信號(hào)Vin為0~5V電壓范圍,則每?jī)蓚€(gè)狀態(tài)值為5/(256-1),約為0.0196V,故測(cè)量分辨率為0.02V。常用測(cè)量方法是:當(dāng)讀取到DB7~DB0轉(zhuǎn)換值是XXH時(shí),電壓測(cè)量值為U≈XXH×0.02V;考慮到直接使用乘法計(jì)算對(duì)應(yīng)的電壓值將耗用大量的FPGA內(nèi)部組件,本設(shè)計(jì)用查表命令來(lái)得到正確的電壓值。
在讀取到ADC0804的轉(zhuǎn)換數(shù)據(jù)后,先用查表指令算出高、低4位的兩個(gè)電壓值,并分別用12位BCD碼表示;接著設(shè)計(jì)12位的BCD碼加法,如果每4位相加結(jié)果超過(guò)9需進(jìn)行加6調(diào)整。這樣得到模擬電壓的BCD碼。
CBD模塊如下:
本模塊的功能仿真結(jié)果如圖3所示;當(dāng)轉(zhuǎn)換數(shù)據(jù)為00010101,通過(guò)查表高4位0001是0.32V,而低4位0101是0.1V,最后的電壓輸出結(jié)果是0.32V+0.1V=0.42V,它的BCD碼表示為000001000010,仿真結(jié)果正確。2.3掃描、顯示模塊
如圖4所示,CLK是掃描時(shí)鐘,其頻率為1kHz,由給定的40MHz時(shí)鐘分頻得到;DATAIN是數(shù)據(jù)處理模塊輸出的電壓值的BCD碼;SEL是數(shù)碼管的片選信號(hào);POINT是數(shù)碼管小數(shù)點(diǎn)驅(qū)動(dòng);通過(guò)掃描分別輸出3位電壓值的BCD碼DATAOUT,并通過(guò)DISP將BCD碼譯成相應(yīng)的7段數(shù)碼驅(qū)動(dòng)值,送數(shù)碼管顯示。
2.4 3選1 數(shù)據(jù)選擇器模塊
下圖是3選1 數(shù)據(jù)選擇器模塊,由sel來(lái)選擇數(shù)據(jù)輸出,sel的三個(gè)狀態(tài)分別對(duì)應(yīng)選中三個(gè)數(shù)據(jù)A,B,C,同時(shí)將選中的數(shù)據(jù)輸出。
2.5位選信號(hào)產(chǎn)生器(3進(jìn)制計(jì)數(shù)器)
位選信號(hào)產(chǎn)生器,實(shí)際上時(shí)一個(gè)3進(jìn)制計(jì)數(shù)器,隨著時(shí)鐘的上升沿的到來(lái),它始終在0,1,2之間來(lái)回的循環(huán),它的輸出作為3選1 數(shù)據(jù)選擇器模塊和小數(shù)點(diǎn)產(chǎn)生器的輸入。以下是仿真和模塊。
位選信號(hào)產(chǎn)生器的模塊:
2.6 7段譯碼
將輸入的數(shù)據(jù)通過(guò)譯碼電路在數(shù)碼管上顯示出來(lái) 7段譯碼的模塊:
2.7小數(shù)點(diǎn)產(chǎn)生器
當(dāng)if selDP=“10” then DPout<='0';
elsif
selDP=“01” then DPout<='0';elsif
selDP=“00” then DPout<='1';只有當(dāng)它等于1的時(shí)候,小數(shù)點(diǎn)才起作用,也就是說(shuō),只有當(dāng)高四位有數(shù)值的時(shí)候,必須需要小數(shù)點(diǎn)來(lái)確定數(shù)值。下面仿真波形中,黑色的部分就是小數(shù)點(diǎn)顯示的時(shí)候和部分,可以很清楚地看出,當(dāng)輸出等于3的時(shí)候,就是顯示小數(shù)點(diǎn)。
小數(shù)點(diǎn)產(chǎn)生器模塊:
3.頂層文件的模塊如下圖:
4.仿真結(jié)果
在Quartus II 8.0中,仿真波形如圖所示:
5.心得體會(huì)
從這次的課程設(shè)計(jì)中,我受益匪淺。電壓表的設(shè)計(jì),用EDA仿真工具Quartus II 8.0,用vhdl語(yǔ)言設(shè)計(jì),這些對(duì)于我們初學(xué)者來(lái)說(shuō),并不是件容易的事情,但是同時(shí)鞏固了我們對(duì)知識(shí)的深刻理解。為以后的FPGA設(shè)計(jì)打下了堅(jiān)實(shí)的基礎(chǔ)。所以,總的來(lái)說(shuō),過(guò)程是困難的,不容易的,結(jié)果卻是很滿意的,獲得了很寶貴的知識(shí)和經(jīng)驗(yàn)!
6.結(jié)束語(yǔ)
本文設(shè)計(jì)的VHDL語(yǔ)言程序已在Quartus II 8.0工具軟件上進(jìn)行了編譯、仿真和調(diào)試。經(jīng)過(guò)實(shí)驗(yàn)驗(yàn)證,本設(shè)計(jì)是正確的,其電壓顯示值誤差沒(méi)有超過(guò)量化臺(tái)階上限(0.02V)。本文給出的設(shè)計(jì)思想也適用于其他基于PLD芯片的系統(tǒng)設(shè)計(jì)。
參考文獻(xiàn)
[1]潘松 EDA技術(shù)實(shí)用教程[M]。北京:科學(xué)出版社,2003.[2]盧毅 VHDL與數(shù)字電路設(shè)計(jì)[M]。北京:科學(xué)出版社,2001.[3]林敏 VHDL數(shù)字系統(tǒng)設(shè)計(jì)與高層次綜合[M]。北京:電子工業(yè)出版社,2001.[ 4 ] http://004km.cn:process(c_state,eoc)begin
case c_state is
when st0=>ale<='0';sta<='0';oe<='0';lock<='0';
n_state<=st1;
when st1=>ale<='1';sta<='0';oe<='0';lock<='0';
n_state<=st2;
when st2=>ale<='0';sta<='1';oe<='0';lock<='0';
n_state<=st3;
when st3=>ale<='0';sta<='0';oe<='0';lock<='0';
if(eoc='1')then n_state<=st4;
else n_state<=st3;
――eoc為‘1’轉(zhuǎn)換結(jié)束 進(jìn)入下一狀態(tài)
end if;
――否則 繼續(xù)轉(zhuǎn)換
when st4=>ale<='0';sta<='0';oe<='1';lock<='0';
n_state<=st5;
when st5=>ale<='0';sta<='0';oe<='0';lock<='1';
n_state<=st6;
when st6=>ale<='0';sta<='0';oe<='0';lock<='1';
n_state<=st0;
when others=>n_state<=st0;
end case;end process com;reg:process(st)
begin
if(st'event and st='1')then
c_state<=n_state;
end if;end process reg;lo:process(lock)
--鎖存 begin
if(lock'event and lock='1')then
regl<=d;
end if;end process lo;
q<=regl;
end a;
BCD 8位轉(zhuǎn)12 LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY BCD IS PORT(V:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
HB,LB:BUFFER STD_LOGIC_VECTOR(11 DOWNTO 0);
BVALUE:BUFFER STD_LOGIC_VECTOR(11 DOWNTO 0);
BCD_L,BCD_M,BCD_H:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));END BCD;ARCHITECTURE A OF BCD IS BEGIN P1:PROCESS(V(7 DOWNTO 4))
BEGIN
--A/D輸出高4位轉(zhuǎn)換
分辨率0.32V
IF V(7 DOWNTO 4)=“1111” THEN HB<=“010010000000”;
--4.80V
ELSIF V(7 DOWNTO 4)= “1110” THEN HB<=“010001001000”;--4.48V
ELSIF V(7 DOWNTO 4)= “1101” THEN HB<=“010000010110”;--4.16V
ELSIF V(7 DOWNTO 4)= “1100” THEN HB<=“001110000100”;--3.84V
ELSIF V(7 DOWNTO 4)= “1011” THEN HB<=“001101010010”;--3.52V
ELSIF V(7 DOWNTO 4)= “1010” THEN HB<=“001100100000”;--3.20V
ELSIF V(7 DOWNTO 4)= “1001” THEN HB<=“001010001000”;--2.88V
ELSIF V(7 DOWNTO 4)= “1000” THEN HB<=“001001010110”;--2.56V
ELSIF V(7 DOWNTO 4)= “0111” THEN HB<=“001000100100”;--2.24V
ELSIF V(7 DOWNTO 4)= “0110” THEN HB<=“000110010010”;--1.92V
ELSIF V(7 DOWNTO 4)= “0101” THEN HB<=“000101100000”;--1.60V
ELSIF V(7 DOWNTO 4)= “0100” THEN HB<=“000100101000”;--1.28V
ELSIF V(7 DOWNTO 4)= “0011” THEN HB<=“000010010110”;--0.96V
ELSIF V(7 DOWNTO 4)= “0010” THEN HB<=“000001100100”;--0.64V
ELSIF V(7 DOWNTO 4)= “0001” THEN HB<=“000000110010”;--0.32V
ELSIF V(7 DOWNTO 4)= “0000” THEN HB<=“000000000000”;--0.00V
ELSE HB<=“000000000000”;
--0.00V
END IF;
END PROCESS P1;P2:PROCESS(V(3 DOWNTO 0))
BEGIN
--A/D輸出低4位轉(zhuǎn)換 分辨率0.02V
IF V(3 DOWNTO 0)= “1111” THEN LB<=“000000110000”;
--0.30V
ELSIF V(3 DOWNTO 0)= “1110” THEN LB<=“000000101000”;--0.28V
ELSIF V(3 DOWNTO 0)= “1101” THEN LB<=“000000100110”;--0.26V
ELSIF V(3 DOWNTO 0)= “1100” THEN LB<=“000000100100”;--0.24V
ELSIF V(3 DOWNTO 0)= “1011” THEN LB<=“000000100010”;--0.22V
ELSIF V(3 DOWNTO 0)= “1010” THEN LB<=“000000100000”;--0.20V
ELSIF V(3 DOWNTO 0)= “1001” THEN LB<=“000000011000”;--0.18V
ELSIF V(3 DOWNTO 0)= “1000” THEN LB<=“000000010110”;--0.16V
ELSIF V(3 DOWNTO 0)= “0111” THEN LB<=“000000010100”;--0.14V
ELSIF V(3 DOWNTO 0)= “0110” THEN LB<=“000000010010”;--0.12V
ELSIF V(3 DOWNTO 0)= “0101” THEN LB<=“000000010000”;--0.10V
ELSIF V(3 DOWNTO 0)= “0100” THEN LB<=“000000001000”;--0.08V
ELSIF V(3 DOWNTO 0)= “0011” THEN LB<=“000000000110”;--0.06V
ELSIF V(3 DOWNTO 0)= “0010” THEN LB<=“000000000100”;--0.04V
ELSIF V(3 DOWNTO 0)= “0001” THEN LB<=“000000000010”;--0.02V
ELSIF V(3 DOWNTO 0)= “0000” THEN LB<=“000000000000”;--0.00V
ELSE LB<=“000000000000”;
--0V
END IF;END PROCESS P2;
BVALUE<=HB+LB;P3:PROCESS(BVALUE)VARIABLE JJ:STD_LOGIC_VECTOR(11 DOWNTO 0);
BEGIN
JJ:=BVALUE;
IF(JJ(3 DOWNTO 0)>“1001”)THEN
――如果12位結(jié)果中,低4位
JJ:=JJ+“000000000110”;
――大于9 則低4位加6
END IF;
IF(JJ(7 DOWNTO 4)>“1001”)THEN
――如果中間的4位大于9
JJ:=JJ+“000001100000”;
――則中4位加6
END IF;BCD_L<=JJ(3 DOWNTO 0);
BCD_M<=JJ(7 DOWNTO 4);BCD_H<=JJ(11 DOWNTO 8);END PROCESS P3;END A;
3選1 數(shù)據(jù)選擇器
LIBRARY ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity mux3_1 is port(sel:in std_logic_vector(1 downto 0);A,B,C:in std_logic_vector(3 downto 0);Mselout:out std_logic_vector(3 downto 0));end mux3_1;architecture a of mux3_1 is begin
process(sel)begin
if
sel=“10” then Mselout<=A;
elsif
sel=“01” then Mselout<=B;
elsif
sel=“00” then Mselout<=C;
else null;
end if;end process;end a;
位選信號(hào)產(chǎn)生器(3進(jìn)制計(jì)數(shù)器)
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity c3 is
port(clk,clr:in std_logic;
qout:buffer std_logic_vector(1 downto 0));end c3;architecture behave of c3 is begin
process(clk,clr)begin if(clr='0')then qout<=“00”;elsif(clk'event and clk='1')then
qout<=qout+1;
if(qout=2)then qout<=“00”;
end if;end if;end process;end behave;
7段譯碼
LIBRARY ieee;USE ieee.std_logic_1164.all;USE ieee.std_logic_unsigned.all;ENTITY del7 IS PORT(input : IN STD_LOGIC_vector(3 downto 0);
output : OUT
STD_LOGIC_vector(6 downto 0));END del7;ARCHITECTURE a OF del7 IS
BEGIN PROCESS(input)BEGIN
CASE input IS
WHEN “0000” =>output<=“1111110”;
WHEN “0001” =>output<=“0110000”;
WHEN “0010” =>output<=“1101101”;
WHEN “0011” =>output<=“1111001”;
WHEN “0100” =>output<=“0110011”;
WHEN “0101” =>output<=“1011011”;
WHEN “0110” =>output<=“1011111”;
WHEN “0111” =>output<=“1110000”;
WHEN “1000” =>output<=“1111111”;
WHEN “1001” =>output<=“1111011”;
WHEN OTHERS=>NULL;
END CASE;end process;
END a;
小數(shù)點(diǎn)產(chǎn)生器
LIBRARY ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity DP is port(SELDP:in std_logic_vector(1 downto 0);
DPout:out std_logic);end DP;architecture a of DP is begin
process(selDP)begin
if
selDP=“10” then DPout<='0';
elsif
selDP=“01” then DPout<='0';
elsif
selDP=“00” then DPout<='1';――在高4位整數(shù)輸出時(shí),輸出
else null;
――小數(shù)點(diǎn)DP
end if;end process;end a;
頂層文件
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity V_WATCH is
port(clkK,EOCC:in std_logic;
DD:IN std_logic_vector(7 downto 0);
clk3,CLR3:IN STD_LOGIC;
OEE,START,ALEE,ADDAA:OUT STD_LOGIC;
DPOUT:OUT STD_LOGIC;
Qoutput:out std_logic_vector(6 downto 0);
Qselout:out std_logic_vector(1 downto 0));end V_WATCH;architecture a of V_WATCH is
――元件例化 COMPONENT DP port(SELDP:in std_logic_vector(1 downto 0);
DPout:out std_logic);END COMPONENT;COMPONENT del7 PORT(input : IN STD_LOGIC_vector(3 downto 0);
output
: OUT STD_LOGIC_vector(6 downto 0));END COMPONENT;COMPONENT mux3_1 port(sel:in std_logic_vector(1 downto 0);A,B,C:in std_logic_vector(3 downto 0);Mselout:out std_logic_vector(3 downto 0));END COMPONENT;COMPONENT ad port(st,eoc:in std_logic;
d:in std_logic_vector(7 downto 0);
oe,sta,ale,adda:out std_logic;
q:out std_logic_vector(7 downto 0));END COMPONENT;COMPONENT C3 PORT(clk,clr: IN STD_LOGIC;
qout: OUT std_logic_vector(1 downto 0));END COMPONENT;COMPONENT BCD PORT(V:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
HB,LB:BUFFER STD_LOGIC_VECTOR(11 DOWNTO 0);
BVALUE:BUFFER STD_LOGIC_VECTOR(11 DOWNTO 0);
BCD_L,BCD_M,BCD_H:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));END COMPONENT;signal a:
std_logic_vector(1 downto 0);SIGNAL SBCD_L,SBCD_M,SBCD_H: STD_LOGIC_VECTOR(3 DOWNTO 0);SIGNAL b:
STD_LOGIC_VECTOR(3 DOWNTO 0);SIGNAL q:
STD_LOGIC_VECTOR(7 DOWNTO 0);SIGNAL BBCD:
STD_LOGIC_VECTOR(11 DOWNTO 0);
BEGIN U1:AD
PORT MAP(CLKK,EOCC,DD,OEE,START,ALEE,ADDAA, q);U2:BCD
PORT MAP(q,BCD_L=>SBCD_L,BCD_M=>SBCD_M,BCD_H=>SBCD_H);U3:C3
PORT MAP(CLK3,CLR3,a);
U4:MUX3_1 PORT MAP(SELOUT,SBCD_L,SBCD_M,SBCD_H,DI);U5:DEL7
PORT MAP(b, Qoutput);U6:DP
PORT MAP(a,DPOUT);QSELOUT<=a;end a;
第二篇:電壓表主程序模塊
/**電壓表主程序模塊*/
#include
#define uchar unsigned char #define uint unsigned int void result(uchar);uchar value=0;#include“adc0809.h” #include“l(fā)cd1602.h” uchar str[5];uchar volt[7];
uchar a=0+0x30;uchar str1[11]=“tanxiaopin”;sbit CLK=P0^7;uint n;
void main(){
//uint i;ADC0809_init();lcd_init();while(1){
lcd_zifu(str1,0x01);
value=AD();//原值
str[0]=value/100+0x30;
str[1]=value%100/10+0x30;
str[2]=value%10+0x30;
result(value);
lcd_data(str,0x40);
lcd_data(volt,0x46);
} while(1);}
void result(uchar v)//轉(zhuǎn)換成電壓值 { float a;a=(v/255.0)*500.0;volt[0]=((int)a)/100+0x30;volt[1]='.';volt[2]=((int)a)%100/10+0x30;volt[3]=((int)a)%10+0x30;volt[4]=' ';volt[5]='V';} void t1(void)interrupt 3
{
CLK=~CLK;
}
/*ADC0809程序模塊*/
#include
sbit ST=P0^4;sbit EOC=P0^5;sbit OE=P0^6;//sbit CLK=P0^7;sbit ADDA=P0^0;sbit ADDB=P0^1;sbit ADDC=P0^2;
sbit ALE=P0^3;
uchar v;//保存IN0和經(jīng)AD轉(zhuǎn)換后的數(shù)據(jù) /*非精確演示函數(shù)*/ void delay(ms){ uint i,j;
for(i=ms;i>0;i--)
for(j=125;j>0;j--);}
void ADC0809_init(){ TMOD=0x20;TH1=(255-250);TL1=(255-250);EA=1;//開(kāi)總中斷
ET1=1;//開(kāi)定時(shí)器1中斷
TR1=1;//啟動(dòng)定時(shí)器1
ST=0;
OE=0;ALE=0;} /*用中斷做一個(gè)500K HZ的時(shí)鐘信號(hào)*/
/******AD轉(zhuǎn)換函數(shù)*******/ uchar AD(){ uchar temp=0;ST=0;//EOC=1;// ALE=1;ADDA=0;ADDB=0;ADDC=0;
delay(1);// ALE=0;
//OE=0;
ST=0;
ALE=1;
ST=1;
ALE=0;
ST=0;
delay(2);
while(EOC==0);
OE=1;
temp=P2;
delay(2);
OE=0;
return temp;}
/*ADC0809 模塊封裝頭文件*/ void ADC0809_init();uchar AD();
/*LCD1602液晶顯示模塊*/ #include
void lcd_1602(uchar comm);void lcd_write(uchar dat);
bit lcd_busy();sbit busy=P3^7;extern void delay(uint);
/***************************** 1602液晶寫(xiě)命令函數(shù) 參數(shù): 返回值:無(wú)
******************************/ void lcd_1602(uchar comm){ while(lcd_busy());//查忙
rs = 0;rw = 0;en = 0;
_nop_();P3 = comm;_nop_();en = 1;_nop_();_nop_();en = 0;} /***************************** 1602液晶寫(xiě)數(shù)據(jù)函數(shù) 參數(shù): 返回值:無(wú)
******************************/ void lcd_write(uchar dat){ while(lcd_busy());//查忙
rs = 1;
rw = 0;
en = 0;
_nop_();
P3 = dat;
_nop_();
_nop_();
en = 1;
_nop_();
_nop_();
en = 0;}
/***************************** 1602液晶初始化函數(shù) 參數(shù):無(wú) 返回值:無(wú)
******************************/ void lcd_init(){
delay(15);lcd_1602(0x38);delay(3);lcd_1602(0x38);
delay(3);lcd_1602(0x38);delay(3);lcd_1602(0x08);lcd_1602(0x01);delay(3);lcd_1602(0x06);lcd_1602(0x0c);} /***************************** 1602液晶讀忙標(biāo)志 參數(shù):無(wú) 返回值:無(wú)
******************************/ bit lcd_busy(){
bit result;rs = 0;rw = 1;en = 1;delay(2);result = busy;en = 0;return result;}
/***************************** 1602液晶寫(xiě)字符 參數(shù): 返回值:無(wú)
******************************/ void lcd_zifu(uchar *p,uchar wei){ uchar temp;lcd_1602(0x80+wei);/*temp= *p;while(temp!='