基于FPGA的 LCD1602显示控制器设计
LCD1602显示控制器设计

LCD1602显示控制器设计一、LCD1602显示控制器的基本原理1. LCD1602显示屏通过16个引脚与Arduino开发板相连接,其中8个引脚用于数据通信,另外8个引脚包括RS、RW和E等信号引脚,用于控制显示模式和数据写入。
2.通过设置每个引脚的高低电平状态,可以实现对LCD1602显示屏的各种操作,例如清屏、光标位置设置、字符显示和图标显示等。
二、LCD1602显示控制器的硬件设计1. Arduino开发板的选择在设计LCD1602显示控制器时,首先需要选择一个合适的Arduino开发板,常用的有Arduino Uno、Arduino Nano等。
这些开发板一般都提供了多个IO口,可以满足与LCD1602显示屏的连接需求。
2.连接电路设计根据LCD1602显示屏和Arduino开发板的引脚对应关系,设计连接电路。
一般情况下,将LCD1602显示屏的VSS引脚与Arduino开发板的GND引脚相连接,将VDD引脚与5V电源引脚相连接。
将LCD1602显示屏的RS、RW和E等信号引脚与Arduino开发板的相应IO口相连接。
将LCD1602显示屏的D0-D7引脚与Arduino开发板的相应IO口相连接。
三、LCD1602显示控制器的软件设计1. 引入LiquidCrystal库在Arduino的开发环境中,打开“Sketch”菜单,选择“包含库”,再选择“添加库”,“LiquidCrystal”,将其添加到项目中。
然后在代码中引入LiquidCrystal库,以便使用其提供的函数和方法。
2. 初始化LiquidCrystal对象初始化一个LiquidCrystal对象,指定其构造函数的参数为相应的引脚号,表示与LCD1602显示屏的连接关系。
3.设置显示模式和光标位置使用LiquidCrystal对象的setCursor(函数设置光标的位置,使用display(函数打开显示,并使用noDisplay(函数关闭显示。
(完整word)基于FPGA的 LCD1602显示控制器设计

唐山学院《EDA技术》课程设计题目 LCD1602显示控制器设计系(部) 信息工程系班级 11电本3班姓名刘亮学号 4110218214指导教师郭耀华田丽欣柳延领2014 年6 月 30 日至 7月 4日共 1 周2014年 7月 4日课程设计成绩评定表目录1 引言 01.1 EDA技术的介绍 01。
2 EDA技术的发展 (1)2 VHDL/Quartus II简介 (2)2.1 VHDL语言介绍 (2)2。
2 界面介绍 (3)3 模块设计 (4)3。
1 LCD1602液晶模块 (4)3.2 矩阵键盘模块 (7)3。
3 设计思路 (8)4 系统设计方案一 (8)4.1 矩阵键盘模块设计 (9)4。
2 LCD1602液晶显示模块设计 (12)5 系统设计方案二 (14)5.1拨码开关控制的LCD1602显示模块 (14)5。
2拨码开关控制的LCD1602显示模块程序 (15)5。
3拨码开关控制的LCD1602显示模块仿真图 (18)6 设计总结 (18)参考文献 (19)1 引言1.1 EDA技术的介绍在电子设计自动化(英语:Electronic design automation,缩写:EDA)出现之前,设计人员必须手工完成集成电路的设计、布线等工作,这是因为当时所谓集成电路的复杂程度远不及现在.工业界开始使用几何学方法来制造用于电路光绘(photoplotter)的胶带.到了1970年代中期,开发人员尝试将整个设计过程自动化,而不仅仅满足于自动完成掩膜草图。
第一个电路布线、布局工具研发成功.设计自动化会议(Design Automation Conference)在这一时期被创立,旨在促进电子设计自动化的发展.电子设计自动化发展的下一个重要阶段以卡弗尔·米德(Carver Mead)和琳·康维于1980年发表的论文《超大规模集成电路系统导论》(Introduction to VLSI Systems)为标志。
基于FPGA的LCD1602动态显示

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity lcdplay isport(clk,reset,lcdopen:in std_logic;lcd_on,lcd_en,lcd_rw:out std_logic;LCD_Data:out std_logic_vector(8 downto 0));end lcdplay;architecture zw of lcdplay issignal clk1hz:std_logic;--signal cnt2:std_logic_vector(4 downto 0);type statetype is(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22,s23);signal pstate,nstate:statetype;beginlcd_on<=lcdopen;process(clk)variable cnt1:integer range 0 to 4999999;beginif rising_edge(clk) thenif cnt1=4999999 thencnt1:=0;elsecnt1:=cnt1+1;end if;if cnt1<2500000 thenclk1hz<='1';elseclk1hz<='0';end if;lcd_en<=clk1hz;end if;end process;--process(clk1hz)-- begin-- if Reset='0'then-- cnt2<="00000";--- elsif rising_edge(clk1hz) then-- if cnt2<"10000" then-- cnt2<=cnt2+1;-- else-- cnt2<="00000";--end if;--end process;process(pstate,reset)begin--lcd_en<=clk1hz;if reset='1' thennstate<=s0;LCD_Data<="000000001";elsecase pstate iswhen s0=>lcd_rw<='0';nstate<=s1;LCD_Data<="000111000";--/*设置8位格式,2行,5*7*/ ,顺序2,3的要求when s1=>nstate<=s2;LCD_Data<="000001100"; --/*整体显示,关光标,光标闪烁/ ,顺序4的要求when s2=>--lcd_rw<='0';nstate<=s3;LCD_Data<="000000001";--清屏,顺序5的要求when s3=>--lcd_rw<='0';nstate<=s4;LCD_Data<="000000110"; --/*显示移动格式,看最后两位,10表示光标右移,顺序6的要求when s4=>--lcd_rw<='0';nstate<=s5;LCD_Data<="010000100";--设定显示的位置在01H+80H,即显示屏第一行第01H个位置,顺序7的要求when s5=>nstate<=s6;LCD_Data<="101011010";--Zwhen s6=>--lcd_rw<='1';nstate<=s7;LCD_Data<="101101000";--上一步基础上地址加一,显示字符h when s7=>--lcd_rw<='1';nstate<=s8;LCD_Data<="101100001";--awhen s8=>nstate<=s9;LCD_Data<="101101110";--nwhen s9=>nstate<=s10;LCD_Data<="101100111";--gwhen s10=>nstate<=s11;LCD_Data<="101110111";--wwhen s11=>nstate<=s12;LCD_Data<="101100101";--ewhen s12=>nstate<=s13;LCD_Data<="101101001";--iwhen s13=>lcd_rw<='0';LCD_Data<="011000011";nstate<=s14;when s14=>nstate<=s15;LCD_Data<="100110010";--2when s15=>nstate<=s16;LCD_Data<="100110000";--0when s16=>nstate<=s17;LCD_Data<="100110001";--1when s17=>nstate<=s18;LCD_Data<="100110001";--1when s18=>nstate<=s19;LCD_Data<="100110001";--1when s19=>nstate<=s20;LCD_Data<="100110001";--1when s20=>nstate<=s21;LCD_Data<="100110001";--1when s21=>nstate<=s22;LCD_Data<="100110010";--2when s22=>nstate<=s23;LCD_Data<="100110000";--0when s23=>nstate<=s0;LCD_Data<="100111000";--0 end case;end if;end process;process(clk1hz,nstate)beginif clk1hz'event and clk1hz='1' thenpstate<=nstate;end if;end process;end zw;。
基于FPGA的电子钟设计--带1602液晶显示

基于FPGA的电子钟设计--带1602液晶显示2010-06-25 14:26----fenpin----library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity fenpin isport(clk :in std_logic;clk1hz :out std_logic;clk5khz :out std_logic);end fenpin;architecture bev of fenpin isbeginclk1hz_pro:process(clk)variable cnt1:integer range 0 to 50000000;beginif rising_edge(clk) thenif(cnt1<25000000) thenclk1hz<='0';cnt1:=cnt1+1;elsif(cnt1>=25000000 and cnt1<50000000) then clk1hz<='1';cnt1:=cnt1+1;else cnt1:=0;end if;end if;end process;clk5khz_pro:process(clk)variable cnt2:integer range 0 to 10000;beginif rising_edge(clk) thenif(cnt2<5000) thenclk5khz<='0';cnt2:=cnt2+1;elsif(cnt2>=5000 and cnt2<10000) thenclk5khz<='1';cnt2:=cnt2+1;else cnt2:=0;end if;end if;end process;end bev;----adjuster----library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity adjuster isport(clr :in std_logic;clk1hz :in std_logic;clock_mode :in std_logic; --时钟模式选择:00正常计时,01设置时间的“时”,10设置时间的“分”,11设置时间的“秒”alarm_mode :in std_logic; --闹钟模式选择:00不动,01设置闹钟的“时”,10设置闹钟的“分”,11设置闹钟的“秒”set_clk :in std_logic; --设置时的计时脉冲,由按键输入alarm_on_off :in std_logic; --闹钟的开关(1开,0关)m_enout :in std_logic; --正常计时,计数器中分的进位输出 s_enout :in std_logic; --正常计时,计数器中秒的进位输出reset :out std_logic;alarm_out :out std_logic;clk_clock :out std_logic; --正常计时由clk1hz提供计时脉冲,设置时由set_clk提供计时脉冲clock_hour_en :out std_logic; --时钟模式下计数器时、分、秒的使能clock_minute_en :out std_logic;clock_second_en :out std_logic;clk_alarm :out std_logic; --设置闹钟时由set_clk提供计时脉冲alarm_hour_en :out std_logic; --闹钟模式下计数器时、分、秒的使能alarm_minute_en :out std_logic);end adjuster;architecture behave of adjuster issignal clock_mode_cnt:std_logic_vector(1 downto 0);signal alarm_mode_cnt:std_logic_vector(1 downto 0);signal set:std_logic;signal alarm_out_reg:std_logic;signal clk_h_reg:std_logic;signal clk_m_reg:std_logic;signal clk_s_reg:std_logic;beginreset<=clr;--------------------------时钟模式-----------------------------------------------------------clock_pro:process(clr,clock_mode)beginif(clr='1') thenclock_mode_cnt<="00";elsif(clr='0') thenif rising_edge(clock_mode) thenif(clock_mode_cnt="11") thenclock_mode_cnt<="00";else clock_mode_cnt<=clock_mode_cnt+'1';end if;end if;end if;end process;u1:process(clock_mode_cnt)beginif(clock_mode_cnt="00") then --正常计时set<='1';clk_h_reg<='0';clk_m_reg<='0';clk_s_reg<='0';elsif(clock_mode_cnt="01") then --设置时间的“时”set<='0';clk_h_reg<='1';clk_m_reg<='0';clk_s_reg<='0';elsif(clock_mode_cnt="10") then --设置时间的“分”set<='0';clk_h_reg<='0';clk_m_reg<='1';clk_s_reg<='0';elsif(clock_mode_cnt="11") then --设置时间的“秒”set<='0';clk_h_reg<='0';clk_m_reg<='0';clk_s_reg<='1';elseset<='0';clk_h_reg<='0';clk_m_reg<='0';clk_s_reg<='0';end if;end process;u2:process(set,clk1hz,set_clk)beginif(set='1') then --正常计时,计数器的时钟及使能的选择clk_clock<=clk1hz;clock_hour_en <= m_enout;clock_minute_en <= s_enout;clock_second_en <= '1';elsif(set='0') then --设置时间,计数器的时钟及使能的选择clk_clock<=set_clk;clock_hour_en <= clk_h_reg;clock_minute_en <= clk_m_reg;clock_second_en <= clk_s_reg;elseclk_clock<=clk1hz;clock_hour_en <= m_enout;clock_minute_en <= s_enout;clock_second_en <= '1';end if;end process;-------------------------闹钟模式-------------------------------------------------------------------- alarm_on_pro:process(clr,alarm_on_off) --按键alarm_on_off按一下为1(闹钟开),再按一下为0(闹钟关)beginif(clr='1') thenalarm_out_reg<='0';elsif rising_edge(alarm_on_off) thenalarm_out_reg<= not alarm_out_reg;end if;end process;alarm_out<=alarm_out_reg;alarm_pro:process(clr,alarm_mode) --闹钟模式选择 beginif(clr='1') thenalarm_mode_cnt<="00";elsif(clr='0') thenif rising_edge(alarm_mode) thenif(alarm_mode_cnt="10") thenalarm_mode_cnt<="00";else alarm_mode_cnt<=alarm_mode_cnt+'1';end if;end if;end if;end process;u3:process(alarm_mode_cnt,set_clk)beginif(alarm_mode_cnt="00") thenalarm_hour_en<='0';alarm_minute_en<='0';clk_alarm<='0';elsif(alarm_mode_cnt="01") then --设置闹钟的“时” alarm_hour_en<='1';alarm_minute_en<='0';clk_alarm<=set_clk;elsif(alarm_mode_cnt="10") then --设置闹钟的“分” alarm_hour_en<='0';alarm_minute_en<='1';clk_alarm<=set_clk;elsealarm_hour_en<='0';alarm_minute_en<='0';clk_alarm<='0';end if;end process;end behave;----cmp----library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity cmp isport(clk1hz :in std_logic;alarm_in :in std_logic; --为1则闹钟开启,0则闹钟关闭hour :in std_logic_vector(7 downto 0);minute :in std_logic_vector(7 downto 0);second :in std_logic_vector(7 downto 0);alarm_h :in std_logic_vector(7 downto 0);alarm_m :in std_logic_vector(7 downto 0);speak :out std_logic; --为1则闹铃响low_beep :out std_logic; --低频声控制,分为59,秒为50,52,54,56,58,00时低频输出为1hign_beep :out std_logic --高频声控制,到达整点(00分00秒时)高频输出为1);end cmp;architecture bev of cmp isbegin------------------------------ -----闹钟模块------------------------------------------------------------------- cmp_pro:process(alarm_in,hour,minute,second,alarm_h,alarm_m)beginif(hour=alarm_h and minute=alarm_m ) thenif(second(3 downto 0)="0000" or second(3 downto 0)="0010" or second(3 downto 0)="0100" or second(3 downto 0)="0110" or second(3 downto 0)="1000") thenif(alarm_in='1') thenspeak<='1';end if;else speak<='0';end if;else speak<='0';end if;end process;-----------------------------------整点报时模块------------------------------------------------------------------ zheng_dian_bao_shi:process(clk1hz)beginif rising_edge(clk1hz) thenif(minute="01011001") then --分为59,秒为50,52,54,56,58,00时低频输出为1if(second(7 downto 4)="0101") thenif(second(3 downto 0)="0000" or second(3 downto0)="0010" or second(3 downto 0)="0100" or second(3 downto 0)="0110" or second(3 downto 0)="1000") thenlow_beep<='1';else low_beep<='0';end if;end if;end if;if(minute="00000000" and second="00000000") then --到达整点(00分00秒时)高频输出为1hign_beep<='1';else hign_beep<='0';end if;end if;end process;end bev;----1602 LCD----library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;library work;use work.ascii_table.all;entity lcd1602 isPort ( clk :in std_logic;reset :in std_logic;hour :in std_logic_vector(7 downto 0);minute :in std_logic_vector(7 downto 0);second :in std_logic_vector(7 downto 0);alarm_h :in std_logic_vector(7 downto 0);alarm_m :in std_logic_vector(7 downto 0);LCD_RS :out std_logic; --寄存器选择信号LCD_RW :out std_logic; --液晶读写信号LCD_EN :out std_logic; --液晶时钟信号LCD_Data :out std_logic_vector(7 downto 0)); --液晶数据信号end lcd1602;architecture bev of lcd1602 istype state is(set_clr,set_function,set_cursor,set_input_mode,write_cgram,set_ddram ,write_LCD_Data);signal current_state:state;type ram1 is array(0 to 31) of std_logic_vector(7 downto 0);signal cgram1 :ram1;signal clk1 : std_logic;signal clk_out : std_logic;signal lcd_clk : std_logic;beginLCD_EN <= clk_out;LCD_RW <= '0';process(clk) --分频,使时钟满足液晶的建立时间variable n1:integer range 0 to 999;beginif rising_edge(clk) thenif n1<999 thenn1:=n1+1;elsen1:=0;clk_out<=not clk_out;end if;end if;end process;lcd_clk <= clk_out;process(lcd_clk,reset,current_state)variable cnt1: std_logic_vector(4 downto 0);beginif reset='0' thencurrent_state<=set_clr; --清屏cnt1:="11110";LCD_RS<='0'; --RS='0',RS='0'=>指令寄存器写入 elsif rising_edge(lcd_clk)thencurrent_state <= current_state ;LCD_RS <= '0';case current_State iswhen set_clr=> --清屏cnt1:="00000";LCD_Data<="00000001";current_state<=set_function;when set_function=> --功能设置LCD_Data<="00111000";current_state<=set_cursor;when set_cursor=> --显示开关控制LCD_Data<="00001111";current_state<=set_input_mode;when set_input_mode=> --输入方式控制LCD_Data<="00000110";current_state<=write_cgram;when write_cgram=>LCD_RS<='1'; --RS='1',RW='0',数据寄存器写入 LCD_Data<=cgram1(conv_integer(cnt1));current_state<=set_ddram;when set_ddram=>if cnt1<"11111" thencnt1:=cnt1+1;elsecnt1:="00000";end if;case cnt1 is--第一行显示时钟when "00000"=>cgram1(conv_integer(cnt1))<=uT;when "00001"=>cgram1(conv_integer(cnt1))<=i;when "00010"=>cgram1(conv_integer(cnt1))<=X"6d"; when "00011"=>cgram1(conv_integer(cnt1))<=e;when "00100"=>cgram1(conv_integer(cnt1))<=sp;when "00101"=>cgram1(conv_integer(cnt1))<=maohao; when "00110"=>cgram1(conv_integer(cnt1))<=sp;when "00111"=>cgram1(conv_integer(cnt1))<=x"3" & hour(7 downto 4);when "01000"=>cgram1(conv_integer(cnt1))<=x"3" & hour(3 downto 0);when "01001"=>cgram1(conv_integer(cnt1))<=maohao; when "01010"=>cgram1(conv_integer(cnt1))<=x"3" & minute(7 downto 4);when "01011"=>cgram1(conv_integer(cnt1))<=x"3" & minute(3 downto 0);when "01100"=>cgram1(conv_integer(cnt1))<=maohao; when "01101"=>cgram1(conv_integer(cnt1))<=x"3" & second(7 downto 4);when "01110"=>cgram1(conv_integer(cnt1))<=x"3" & second(3 downto 0);--第二行显示闹钟when "10000"=>cgram1(conv_integer(cnt1))<=uA;when "10001"=>cgram1(conv_integer(cnt1))<=l;when "10010"=>cgram1(conv_integer(cnt1))<=aa;when "10011"=>cgram1(conv_integer(cnt1))<=r;when"10100"=>cgram1(conv_integer(cnt1))<=X"6d";when "10101"=>cgram1(conv_integer(cnt1))<=maohao; when "10110"=>cgram1(conv_integer(cnt1))<=sp;when "10111"=>cgram1(conv_integer(cnt1))<=x"3" & alarm_h(7 downto 4);when "11000"=>cgram1(conv_integer(cnt1))<=x"3" & alarm_h(3 downto 0);when "11001"=>cgram1(conv_integer(cnt1))<=maohao; when "11010"=>cgram1(conv_integer(cnt1))<=x"3" & alarm_m(7 downto 4);when "11011"=>cgram1(conv_integer(cnt1))<=x"3" & alarm_m(3 downto 0);when others=>cgram1(conv_integer(cnt1))<=sp;end case;if(cnt1<="01111") thenLCD_Data<="10000000"+cnt1;--80H-8fHelseLCD_Data<="11000000"+cnt1-"10000";--c0H-cfH end if;current_state<=write_LCD_Data;when write_LCD_Data=>LCD_Data<="00000000";current_state<=set_function;when others => null;end case;end if;end process;end bev;----counter24----library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity counter24 isport( clr :in std_logic;clk_in :in std_logic;en :in std_logic;co :out std_logic;c_out :out std_logic_vector(7 downto 0));end counter24;architecture bev of counter24 issignal h_reg:std_logic_vector(3 downto 0);signal l_reg:std_logic_vector(3 downto 0);beginprocess(clr,clk_in,en)beginif(clr='1') thenh_reg<="0000";l_reg<="0000";elsif(clr='0') thenif rising_edge(clk_in) thenif(en='1') thenif(h_reg="0010" and l_reg="0011") thenh_reg<="0000";l_reg<="0000";elsif(l_reg="1001" ) thenh_reg<=h_reg+1;l_reg<="0000";else l_reg<=l_reg+'1';end if;end if;end if;end if;end process;co<='1' when l_reg="0011" and h_reg="0010" else '0'; c_out<=h_reg & l_reg;end bev;----counter 60----library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity counter60 isport(clr :in std_logic;clk_in :in std_logic;en :in std_logic;co :out std_logic;c_out :out std_logic_vector(7 downto 0));end counter60;architecture bev of counter60 issignal hign_reg:std_logic_vector(3 downto 0);signal low_reg:std_logic_vector(3 downto 0);beginprocess(clr,clk_in,en)beginif(clr='1') thenhign_reg<="0000";low_reg<="0000";elsif(clr='0') thenif rising_edge(clk_in) thenif (en='1') thenif(hign_reg="0101" and low_reg="1001") thenhign_reg<="0000";low_reg<="0000";elsif(low_reg="1001") thenlow_reg<="0000";hign_reg<=hign_reg+'1';else low_reg<=low_reg+'1';end if;end if;end if;end if;end process;co<='1' when hign_reg="0101" and low_reg="1001" else '0'; c_out<=hign_reg&low_reg;end bev;。
基于FPGA的LCD显示控制系统的毕业设计

基于FPGA的LCD显示控制系统的毕业设计第一章绪论1.1选题的背景与意义液晶,是一种在一定温度范围内呈现既不同于固态、液态,又不同于气态的特殊物质态,它既具有各向异性的晶体所特有的双折射性,又具有液体的流动性。
一般可分热致液晶和溶致液晶两类。
在显示应用领域,使用的是热致液晶,超出一定温度范围,热致液晶就不再呈现液晶态,温度低了,出现结晶现象,温度升高了,就变成液体;液晶显示器件所标注的存储温度指的就是呈现液晶态的温度范围。
液晶由于它的各向异性而具有的电光效应,尤其扭曲向列效应和超扭曲效应,所以能制成不同类型的显示器件(Liquid Crystal Display 简称LCD)。
在平板显示器件领域,目前应用较广泛的有液晶(LCD)、电致发光显示(EL)、等离子体(PDP)、发光二极管(LED)、低压荧光显示器件(VFD)等。
液晶显示器件有以下一些特点①低压微功耗,②平板型结构,③被动显示型(无眩光,不刺激人眼,不会引起眼睛疲劳),④显示信息量大(因为像素可以做得很小),⑤易于彩色化(在色谱上可以非常准确的复现),⑥无电磁辐射(对人体安全,利于信息保密),⑦长寿命(这种器件几乎没有什么劣化问题,因此寿命极长,但是液晶背光寿命有限,不过背光部分可以更换)。
之前,一般流行采用单片机来控制驱动LCD。
采用单片机控制LCD的显示在设计上相对比较简单。
可以通过KEIL等软件的编写方便地控制LCD的图形以及字符的现实。
但是由于单片机的顺序执行结构。
决定了在现实图片或者字符的同时,单片机本身无法处理其他数据或者执行其他的运算命令。
这在某种程度上大大地降低了工作的效率。
而采用FPGA来控制LCD则不存在这个问题。
但是由于FPGA不像单片机,可以直接使用控制语句来方便地控制LCD。
因此需要编写大量的代码来控制LCD。
因为这个原因,采用FPGA的设计一般都会再一次通过单片机来驱动LCD的显示。
本课题主要任务是设计基于FPGA的LCD控制器,兼顾好程序的易用性,以方便之后模块的移植和应用。
用Verilog写LCD1602

最近用FPGA写了个LCD1602的程序,小有成就啊,分享一下。
在网上,很难找到关于FPGA用1602显示的程序,因为大家都认为,FPGA 来做液晶显示,是一件很麻烦的事,不过对我这个初学者来说,用数码管不能显示字符,用VGA太高档,咱不会用,也没东西。
呵呵,就考虑用LCD了。
在网上,你可以找到LCD1602的程序,但是我只看到直接把字符写进液晶的,这个根本不实用,平时要用的都是把获得的数据在液晶上显示,而我们FPGA得到的数据只是二进制数,那么我们就得想办法,把二进制数转化为字我们要的字符才行。
为此用到了单片机里转换的算法,即除以10的n次方,求余或取整。
废话不多说见程序。
说明:我这是一个用于频率计显示的程序,频率值有32位,小数1位,也就是精度是0.1HZ ,最后一个块里,有两个写状态,一个是显示频率的,另一个是显示幅度的,我的本意是做一个FFT的显示,幅度的显示,先就放在那了,没有作用,不过这也是个双行的显示了,不要的可以删掉,要的,只要修改一下就好了。
频率显示已经做好的,没有问题。
修改的时候一定要注意状态的调整。
module LCD1602(clk,rst_n ,rs,rw,en,dat);input clk;input rst_n ;output rs,rw,en;output [7:0] dat;reg rs,rw;wire en;wire [31:0] fre_data ; //频率值wire [9:0] fre[3:0] ;wire [7:0] fre_unit ; //频率的单位reg [7:0] dat;reg [3:0] counter;reg [1:0] state;reg [15:0] count;reg clkr;parameter init=2'd0,write_data_1=2'd1 ,write_data_2=2'd2 ;assign en = clkr;assign fre_data = 32'd123_9 ;reg [9:0] data_flag ;reg [1:0] flag ;reg [7:0] chara[3:0] ;//----------分解频率值,MHz,KHz,Hz----------------assign fre[3] = fre_data / 10000000 ; //MHz的位数assign fre[2] = (fre_data % 10000000) / 10000 ; //KHz的位数assign fre[1] = (fre_data % 10000) /10 ; //Hz的位数assign fre[0] = fre_data % 10 ; //0.1Hz的位数assign fre_unit = (fre[3] > 0) ? "M" : ((fre[2] > 0) ? "K" : " ") ; //上面一句是判断频率级别,给定单位//---------获取字符串,在液晶上显示-----------------always @(posedge clk , negedge rst_n)if(!rst_n)begindata_flag <= 4'b0 ;flag <= 2'b0 ;endelsebeginif( fre[3] > 0 ) //MHz分解beginflag = flag + 2'd1 ;if( flag == 2'd1 )data_flag = fre[3] / 100 ;if( flag == 2'd2 )data_flag =( fre[3] % 100 )/10 ;if( flag == 2'd3 )data_flag = fre[3] % 10 ;if( flag == 2'd0 )data_flag = fre[2] / 100 ;endelse if( fre[2] > 0 ) //KHz分解beginflag = flag + 2'd1 ;if( flag == 2'd1 )data_flag = fre[2] / 100 ;if( flag == 2'd2 )data_flag =( fre[2] % 100 )/10 ; if( flag == 2'd3 )data_flag = fre[2] % 10 ;if( flag == 2'd0 )data_flag = fre[1] / 100 ;endelse //Hz分解beginflag = flag + 2'd1 ;if( flag == 2'd1 )data_flag = fre[1] / 100 ;if( flag == 2'd2 )data_flag =( fre[1] % 100 )/10 ; if( flag == 2'd3 )data_flag = fre[1] % 10 ;if( flag == 2'd0 )data_flag = fre[0] ;endendalways @(posedge clk ) //获取字符begincase(data_flag)4'd0 : chara[flag] = "0" ;4'd1 : chara[flag] = "1" ;4'd2 : chara[flag] = "2" ;4'd3 : chara[flag] = "3" ;4'd4 : chara[flag] = "4" ;4'd5 : chara[flag] = "5" ;4'd6 : chara[flag] = "6" ;4'd7 : chara[flag] = "7" ;4'd8 : chara[flag] = "8" ;4'd9 : chara[flag] = "9" ; endcaseend//--------------液晶读写时钟-----------------always @(posedge clk)begincount=count+16'd1;if(count==16'h000f)clkr=~clkr;end//------------液晶初始化及写数据------------------- always @(posedge clkr)begincase(state)init: //LCD1602初始化beginrs=0;rw=0;counter=counter+4'd1;case(counter)1:dat=8'h38; //显示模式设置2:dat=8'h08; //光标设计,08代表关闭光标3:dat=8'h01; //显示清屏4:dat=8'h06; //显示光标移动设置5:dat=8'h0c; //显示开及光标设置6:begindat=8'h80; //写光标地址state=write_data_1;counter=4'd0;enddefault: counter=4'd0;endcaseendwrite_data_1: //写数据beginrs=1;case(counter)0:dat="f";1:dat="r";2:dat="e";3:dat=":";4:dat=" ";5:dat=chara[1];6:dat=chara[2];7:dat=chara[3];8:dat=".";9:dat=chara[0];10:dat=fre_unit;11:dat="H";12:dat="z";13:dat=" ";14:beginrs=0; dat=8'hc0;enddefault: counter=0;endcaseif(counter==14)begincounter=0;state=write_data_2;endelse counter=counter+4'd1;endwrite_data_2: //写数据beginrs=1;case(counter)0:dat="a";1:dat="m";2:dat="p";3:dat=":";4:dat=" ";5:dat=chara[1];6:dat=chara[2];7:dat=chara[3];8:dat="m";9:dat="V";10:dat=" ";11:dat=" ";12:beginrs=0; dat=8'h80;enddefault: counter=0;endcaseif(counter==12)begincounter=0;state=write_data_1;endelse counter=counter+4'd1; enddefault: state=init;endcaseendendmodule。
单片机课程设计(论文)-基于LCD1602液晶显示器课程设计

摘要在日常生活中,我们对液晶显示(LCD)并不陌生LCD智能显示模块不但可以显示字符,汉字和图形,同时具有可编程功能,且与单片机接口比较方便,如液晶显示模块已作为很多电子产品的通用器件,如在计算器,万用表,电子表及很多家用电子产品中都可以看到,显示的主要是数字,专用符号和图形。
在单片机系统中应用中用液晶显示作为输出器件有很多优点,如显示质量高,不闪烁;数字接口式,使得和单片机的接口更加简单可靠,操作方便;体积小,重量轻;而且相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动TC上,因而耗电量比其它显示器要少得多。
关键字:单片机专用字符液晶显示器(LCD1602)目录摘要....................................................................................................................... 错误!未定义书签。
第一章绪论 .................................................................................................... 错误!未定义书签。
1.1 课题背景 (2)1.2课题设计目标 (2)1.3课题设计的主要工作 (3)第二章硬件设计 (4)2.1LCD1602简介 (5)2.1.1 LCD1602引脚功能 (7)2.2 IIC总线 (10)2.2.1 IIC总线的特点 (11)2.2.2 IIC协议总线信号时序 (9)2.2.3 IIC总线器件寻址方式 (7)2.3 系统电路图 (7)第三章软件设计 (7)3.1 系统框图 (7)3.2 程序清单 (7)第四章调试 (7)第五章总结 (7)参考文献 (7)致谢 (7)1绪论1.1课题背景当今时候是一个信息化的时代,信息的重要性不言而喻的,获取手段显得尤其重要。
基于LCD1602液晶显示屏的单片机课程设计

唐山学院单片机原理课程设计题目点阵式YLF1602D液晶显示屏应用系 (部) 智能与信息工程学院班级 13电本 2班姓名李凯学号 4130208205指导教师张国旭江蓓蕾王春生2016 年 6 月 20 日至 6 月 30 日共 2 周2016年 6月 30 日课程设计成绩评定表目录1引言 (1)2 LCD液晶显示屏功能 (2)2.1 简介 (2)2.2 管脚功能 (2)2.3 操作控制 (2)2.4 字符集 (3)3系统硬件设计 (4)3.1 课题设计目标 (4)3.2 课程设计的主要工作 (4)3.3 设计要求 (4)3.4 系统电路图 (5)4软件设计 (6)4.1系统框图 (6)4.2 LCD 显示程序框图 (6)课程总结 (7)致谢 (7)主要参考资料 (8)1引言早在1888年,人们就发现液晶这一呈液体状的化学物质,象磁场中的金属一样,当受到外界电场影响时,其分子会产生精确的有序排列。
如果对分子的排列加以适当的控制,液晶分子将会允许光线穿越。
位于最后面的一层是由荧光物质组成的可以发射光线的背光层。
背光层发出的光线在穿过第一层偏振过滤层之后进入包含成千上万水晶液滴的液晶层。
液晶层中的水晶液滴都被包含在细小的单元格结构中,一个或多个单元格构成屏幕上的一个像素。
当液晶显示器中的电极产生电场时,液晶分子就会产生扭曲,从而将穿越其中的光线进行有规则的折射,然后经过第二层过滤层的过滤在屏幕上显示出来,这就是液晶显示器显示技术。
液晶显示器(LCD)英文全称为Liquid Crystal Display,是一种数字显示技术,可以通过液晶和彩色过滤器过滤光源,在平面面板上产生图象。
它是一种采用了液晶控制透光度技术来实现色彩的显示器。
液晶显示器是一种功耗极低的显示器件。
在袖珍中应用越来越广泛。
液晶显示技术近几年来发展很快,各种规格的LCD显示班名目繁多,其专用驱动芯片也都相互配套,使LCD在控制和议表系统中广泛应用提供了极大的方便。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
唐山学院《EDA技术》课程设计题目 LCD1602显示控制器设计系 (部) 信息工程系班级 11电本3班姓名刘亮学号 4110218214指导教师郭耀华田丽欣柳延领2014 年6 月 30 日至 7月 4日共 1 周2014年 7月 4日课程设计成绩评定表出勤情况出勤天数缺勤天数成绩评定出勤情况及设计过程表现(20分)课设答辩(20分)设计成果(60分)硬件调试设计说明书总成绩(100分)提问(答辩)问题情况综合评定指导教师签名:年月日目录1 引言 (1)1.1 EDA技术的介绍 (1)1.2 EDA技术的发展 (2)2 VHDL/Quartus II简介 (4)2.1 VHDL语言介绍 (4)2.2 界面介绍 (5)3 模块设计 (6)3.1 LCD1602液晶模块 (6)3.2 矩阵键盘模块 (9)3.3 设计思路 (10)4 系统设计方案一 (11)4.1 矩阵键盘模块设计 (11)4.2 LCD1602液晶显示模块设计 (14)5 系统设计方案二 (17)5.1拨码开关控制的LCD1602显示模块 (17)5.2拨码开关控制的LCD1602显示模块程序 (17)5.3拨码开关控制的LCD1602显示模块仿真图 (20)6 设计总结 (21)参考文献 (22)1 引言1.1 EDA技术的介绍在电子设计自动化(英语:Electronic design automation,缩写:EDA)出现之前,设计人员必须手工完成集成电路的设计、布线等工作,这是因为当时所谓集成电路的复杂程度远不及现在。
工业界开始使用几何学方法来制造用于电路光绘(photoplotter)的胶带。
到了1970年代中期,开发人员尝试将整个设计过程自动化,而不仅仅满足于自动完成掩膜草图。
第一个电路布线、布局工具研发成功。
设计自动化会议(Design Automation Conference)在这一时期被创立,旨在促进电子设计自动化的发展。
电子设计自动化发展的下一个重要阶段以卡弗尔·米德(Carver Mead)和琳·康维于1980年发表的论文《超大规模集成电路系统导论》(Introduction to VLSI Systems)为标志。
这一篇具有重大意义的论文提出了通过编程语言来进行芯片设计的新思想。
如果这一想法得到实现,芯片设计的复杂程度可以得到显著提升。
这主要得益于用来进行集成电路逻辑仿真、功能验证的工具的性能得到相当的改善。
随着计算机仿真技术的发展,设计项目可以在构建实际硬件电路之前进行仿真,芯片布线布局对人工设计的要求降低,而且软件错误率不断降低。
直至今日,尽管所用的语言和工具仍然不断在发展,但是通过编程语言来设计、验证电路预期行为,利用工具软件综合得到低抽象级物理设计的这种途径,仍然是数字集成电路设计的基础。
从1981年开始,电子设计自动化逐渐开始商业化。
1984年的设计自动化会议(Design Automation Conference)上还举办了第一个以电子设计自动化为主题的销售展览。
Gateway设计自动化在1986年推出了一种硬件描述语言Verilog,这种语言在现在是最流行的高级抽象设计语言。
1987年,在美国国防部的资助下,另一种硬件描述语言VHDL被创造出来。
现代的电子设计自动化工具可以识别、读取不同类型的硬件描述。
根据这些语言规范产生的各种仿真系统迅速被推出,使得设计人员可对设计的芯片进行直接仿真。
后来,技术的发展更侧重于逻辑综合。
目前的数字集成电路的设计都比较模块化(参见集成电路设计、设计收敛(Design closure)和设计流(Design flow (EDA)))。
半导体器件制造工艺需要标准化的设计描述,高抽象级的描述将被编译为信息单元(cell)的形式。
设计人员在进行逻辑设计时无需考虑信息单元的具体硬件工艺。
利用特定的集成电路制造工艺来实现硬件电路,信息单元就会实施预定义的逻辑或其他电子功能。
半导体硬件厂商大多会为它们制造的元件提供“元件库”,并提供相应的标准化仿真模型。
相比数字的电子设计自动化工具,模拟系统的电子设计自动化工具大多并非模块化的,这是因为模拟电路的功能更加复杂,而且不同部分的相互影响较强,而且作用规律复杂,电子元件大多没有那么理想。
Verilog AMS就是一种用于模拟电子设计的硬件描述语言。
此外,设计人员可以使用硬件验证语言来完成项目的验证工作目前最新的发展趋势是将集描述语言、验证语言集成为一体,典型的例子有SystemVerilog。
随着集成电路规模的扩大、半导体技术的发展,电子设计自动化的重要性急剧增加。
这些工具的使用者包括半导体器件制造中心的硬件技术人员,他们的工作是操作半导体器件制造设备并管理整个工作车间。
一些以设计为主要业务的公司,也会使用电子设计自动化软件来评估制造部门是否能够适应新的设计任务。
电子设计自动化工具还被用来将设计的功能导入到类似现场可编程逻辑门阵列的半定制可编程逻辑器件,或者生产全定制的专用集成电路。
1.2 EDA技术的发展从20世纪70年代,人们就已经开始基于计算机开发出一些软件工具帮助设计者完成电路系统的设计任务,以替代传统的手工设计的方法,随着计算机软件和硬件技术水平的提高,EDA技术也不断进步,大致经历了下面三个发展阶段: (1)CAD阶段:20世纪70年代至80年代初,由于电子技术软件的功能较弱和个人计算机的普及度不高,人们主要借助于计算机对所设计的电路的性能进行模拟和预测;完成简单的版图绘制和PCB布局。
这是EDA技术发展的早起阶段。
(2)CAE阶段:20世纪80年代至90年代初,由于人们在设计方法学、设计工具集成优化方面取得了长足的进步,使得集成电路规模逐渐扩大,电子系统设计也逐步复杂,与CAD相比,又增加了电路功能设计和结构设计、工程设计、原理图输入、逻辑仿真、电路分析、自动布局布线、PCB后分析等功能。
由此EDA进入CAE阶段。
(3)EDA阶段:20世纪90年代以来,由于微电子工艺的显著发展,促进了电子设计工具的不断改善。
尤其是进入21世纪以后,EDA技术得到了更快的发展。
使得EDA技术广泛应用于各个领域,IP核的SoC设计技术日趋成熟、SoPC 技术步入实用化阶段、高速DSP实现成为了可能、复杂电子系统的设计和验证更加高效。
没有EDA技术的支持,想要完成上述超大规模集成电路的设计制造是不可想象的,反过来,生产制造技术的不断进步又必将对EDA技术提出新的要求。
随着电子技术的发展和人们对电子设计开发的难度及周期要求,EDA技术必将广发应用于电子设计的各个领域,因此本设计也采用了EDA的设计方法,其设计的优越性明显高于传统的设计方法。
本次设计的LCD1602显示控制器,就是通过eda进行的一次实践。
在日常生活中,我们对LCD1602显示器并不陌生。
LCD1602显示模块已作为很多电子产品的通过器件,如在计算器、万用表、电子表及很多家用电子产品中都可以看到,显示的主要是数字、专用符号和图形。
LCD1604晶液显示器作为输出器件有以下几个优点:1.显示质量高由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。
因此,液晶显示器画质高且不会闪烁。
2.数字式接口。
液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。
3.体积小、重量轻液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。
4.功耗低。
相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。
这次设计主要任务是设计基于FPGA的LCD控制器,采用了带ST7920驱动的LCD1602液晶模块,并使用Altera公司的cyclone系列的EP2C5T144C8来作为核心的控制器。
控制器部分采用VHDL语言编写,主体程序采用了状态机作为主要控制方式。
该控制器分为字符显示模块和图片显示模块两个主要部分。
在字符的显示功能上采用显示控制模块与字符调用RAM相结合的方式,使使用者能方便地调用液晶自带的字库来显示字符;而图片显示模块则通过特殊的处理算法解决了图像显示缓冲区X地址不断移位以及上下半屏分开的问题,通过读取图片ROM来显示图片。
最后实现使用FPGA在LCD上的任意位置显示任意5*7的英文字符,另外要能根据输入数据的变化同步变化LCD上显示的内容。
同时要能将储存模块中的图片数据正常地显示在LCD上。
2 VHDL/Quartus II简介2.1 VHDL语言介绍电子设计自动化(EDA)的关键技术之一是要求用形式化方法来描述数字系统的硬件电路。
VHDL 硬件描述语言在电子设计自动化中扮演着重要的角色,他是EDA 技术研究的重点之一。
VHDL语言是一种用于电路设计的高级语言。
它在80年代的后期出现。
最初是由美国国防部开发出来供美军用来提高设计的可靠性和缩减开发周期的一种使用范围较小的设计语言。
但是,由于它在一定程度上满足了当时的设计需求,于是他在1987年成为ANSI/IEEE的标准(IEEE STD 1076-1987)。
1993年更进一步修订,变得更加完备,成为ANSI/IEEE的ANSI/IEEE STD 1076-1993标准。
目前,大多数的CAD厂商出品的EDA软件都兼容了这种标准。
VHDL的英文全写是:VHSIC(Very High Speed Integrated Circuit)Hardware Descriptiong Language.翻译成中文就是超高速集成电路硬件描述语言。
因此它的应用主要是应用在数字电路的设计中。
目前,它在中国的应用多数是用在FPGA/CPLD/EPLD的设计中。
当然在一些实力较为雄厚的单位,它也被用来设计ASIC。
硬件描述语言是EDA 技术的重要组成部分,VHDL 是作为电子设计主流硬件描述语言,VHDL(Very High Speed Integrated Circuit Hardware Description Language)于1983 年由美国国防部发起创建,由IEEE进一步发展并在1987年作为IEEE标准10760发布。
因此,VHDL成为硬件描述语言的业界标准之一。
VHDL语言具有很强的电路描述和建模能力,能从多个层次对数字系统进行建模和描述,从而大大简化了硬件设计任务,提高了设计效率和可靠性,使用VHDL 语言,可以就系统的总体要求出发,自上而下地将设计内容细化,最后完成系统硬件的整体设计。
一个完整的VHDL程序包括以下几个基本组成部分:实体(Entity),结构体(Architecture),程序包(Package),库(Library)。