找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3017|回复: 0
打印 上一主题 下一主题
收起左侧

FPGA M07驱动LCD1602 display character例程源码与资料

[复制链接]
跳转到指定楼层
楼主
这是例程


全部资料51hei下载地址:
M07_LCD1602 display character.zip (18.18 MB, 下载次数: 22)





Quartus 工程 qsf 文件管脚约束命令,把以下命令拷贝到新建 quartus 工程的 qsf 文件即可完成管脚约束(注
意信号名必须相同) :

3  实验步骤
3.1  综合
(1)运行综合工具。   
(2)打开项目工程,项目工程存放于以软件开发工具命名的文件夹中。   
(3)编译运行或直接点击下载,下载 FPGA 软件到目标板。   
(4)查看软件运行效果
3.2  仿真
请参考视频讲解。
主要命令:   
切换仿真路径  cd {仿真库路径}    ,如:cd {F:\Verilog_demo\M06_Digital clock\clock\sim};
  run 100us:仿真运行时间长度 100us ;
do wave.do:运行波形文件;
vlog ../src/*.v:编译 scr路径下的所有 v文件
vsim:开始仿真命令
quit –sim:退出仿真

4  实验结果
4.1  结果演示
4.1.1  MODELSIM  仿真演示

图表  2 modelsim 仿真波形
仿真时可以通过按比例修改数据通信时间长度,模拟真实通信协议,来缩短仿真时间。
4.1.2  MATLAB  数据分析
略。
4.1.3  开发板演示
通过以上的讲解,相信各位已经可以熟练驱动 LCD1602 了吧,在今后的使用中,可以试着将一些采集的数据
用1602 显示出来显示,比如传感器温度啊,时间啊,AD采集的电压值啊…等等。
4.2  特别说明


源程序如下:
  1. //==========================================================================
  2. //Filename  :lcd1602_ctl.v                                      
  3. //modulename:lcd1602_inf                                       
  4. //Author    :a fei                                                         
  5. //Function  :驱动1602,包括初始化和数据的写,写入数据由用户定义                 
  6. //==========================================================================
  7. `timescale 1ns/1ps

  8. module    lcd1602_ctl
  9.    (
  10. //sys_signal
  11.     input               i_50m_clk    ,
  12.     input               i_rst_n       ,

  13.     input  [7:0]       i_disp_data   ,//写入的数据
  14.     input              i_data_trig   ,//数据触发
  15.    
  16.     input               i_addr_trig1   ,//第一行地址触发信号
  17.     input               i_addr_trig2   ,//第二行地址触发信号
  18.     input [7:0]         i_addr        , //地址   
  19.    
  20.     output reg             o_lcd_rs      ,//1602端口
  21.     output reg             o_lcd_rw      ,
  22.     output reg             o_lcd_en      ,
  23.     output reg   [7:0]     o_lcd_data
  24.     );  

  25.                               
  26.      
  27. //=============================================================================
  28. //控制状态机状态
  29. //=============================================================================     
  30. parameter Idle        = 10'b0000000001 ;//
  31. parameter Set_mode    = 10'b0000000010 ;//模式设置
  32. parameter Disp_on_off = 10'b0000000100 ;//显示开和关
  33. parameter Cursor      = 10'b0000001000 ;//光标设置
  34. parameter Clear       = 10'b0000010000 ;//数据地址清零
  35. parameter Stand_by    = 10'b0000100000 ;//准备就绪,初始化完成
  36. parameter Wr_address1 = 10'b0001000000 ;//写第一行首地址
  37. parameter Wr_data1    = 10'b0010000000 ;//写第一行数据  
  38. parameter Wr_address2 = 10'b0100000000 ;//写第二行首地址   
  39. parameter Wr_data2    = 10'b1000000000 ;//写第二行数据  

  40. reg [9:0] crt_state , next_state ;
  41. //=================================================================
  42. reg [15:0] cnt_4000 ;//TC,en脉冲宽度 4000*20ns=80us
  43. reg           data_trig ;
  44. reg           addr_tirg1 ;
  45. reg           addr_tirg2 ;

  46. always@( posedge i_50m_clk or negedge i_rst_n )//
  47.     if( !i_rst_n )
  48.            cnt_4000 <= 16'b0 ;
  49.     else if(crt_state!=next_state)
  50.            cnt_4000 <= 16'b0 ;  
  51.    else if(!data_trig &&i_data_trig)
  52.             cnt_4000 <= 16'b0 ;
  53.     else if( cnt_4000 == 16'd4000)
  54.            cnt_4000 <= cnt_4000 ;
  55.     else
  56.            cnt_4000 <= cnt_4000 +1'b1  ;
  57.            
  58. reg [18:0]  time_cnt1 ;//5ms计时器,每个指令间隔
  59. always@( posedge i_50m_clk or negedge i_rst_n )//
  60.     if( !i_rst_n )
  61.            time_cnt1 <= 18'b0 ;
  62.     else if(crt_state!=next_state)
  63.            time_cnt1 <= 18'b0 ;
  64.     else if( time_cnt1 == 18'h3ffff)
  65.            time_cnt1 <= time_cnt1 ;
  66.     else
  67.            time_cnt1 <= time_cnt1 +1'b1  ;         
  68.            

  69. //==================================================================
  70. //检测数据、地址触发信号


  71. reg[7:0]      disp_data ;
  72. reg[7:0]      address   ;
  73. reg[3:0]      data_cnt  ;
  74. reg[15:0]     time_cnt2  ;
  75. always@( posedge i_50m_clk or negedge i_rst_n )//
  76.     if( !i_rst_n )
  77.           data_trig <= 1'b0 ;
  78.     else
  79.           data_trig <= i_data_trig ;
  80.          
  81. always@( posedge i_50m_clk)
  82.         disp_data <= i_disp_data ;  

  83. always@( posedge i_50m_clk)         
  84.        addr_tirg1 <= i_addr_trig1 ;   

  85. always@( posedge i_50m_clk)         
  86.        addr_tirg2 <= i_addr_trig2 ;   


  87. always@( posedge i_50m_clk)         
  88.         address <= i_addr ;
  89.         
  90. always@( posedge i_50m_clk)  //数据持续最小时间控制   
  91.       if(crt_state==Wr_data1||crt_state==Wr_data2)
  92.            if(! data_trig &&i_data_trig)
  93.                   time_cnt2 <= 16'b0 ;
  94.            else if(time_cnt2==16'hffff)
  95.                   time_cnt2 <= time_cnt2 ;
  96.            else
  97.                  time_cnt2 <=time_cnt2+1'b1 ;
  98.       else
  99.               time_cnt2 <= 16'b0 ;

  100. always@( posedge i_50m_clk) //数据个数计数器   
  101.       if(crt_state==Wr_data1||crt_state==Wr_data2)
  102.            if(! data_trig &&i_data_trig)
  103.                   data_cnt <= data_cnt +1'b1 ;
  104.            else
  105.                   data_cnt <= data_cnt ;
  106.       else
  107.                  data_cnt <=4'b0 ;
  108.         
  109.         
  110. //==================================================================
  111. //状态转移                     
  112. //==================================================================
  113. reg [19:0] power_up_cnt ;//上电等待时间42ms

  114. always@( posedge i_50m_clk or negedge i_rst_n )//
  115.     if( !i_rst_n )
  116.             power_up_cnt <= 20'b0   ;         
  117.     else if(power_up_cnt==20'hfffff)//power_up_cnt==22'hff
  118.            power_up_cnt<= power_up_cnt ;
  119.     else
  120.            power_up_cnt <= power_up_cnt + 1'b1  ;

  121. //====================================================================
  122. //????
  123. //====================================================================
  124. always@( posedge i_50m_clk or negedge i_rst_n )//     
  125.     if( !i_rst_n )
  126.             crt_state <= Idle ;
  127.     else
  128.             crt_state <= next_state ;


  129. always@( *)  
  130.       case(crt_state)
  131.                  Idle : if(power_up_cnt==20'hfffff) //时间42ms到
  132.                                  next_state = Set_mode ;
  133.                         else
  134.                                  next_state = crt_state ;
  135.                                  
  136.                  Set_mode: if(time_cnt1 == 18'h3ffff) //模式设置
  137.                                  next_state = Clear ;
  138.                            else
  139.                                  next_state = crt_state ;
  140.                 
  141.            Clear   : if(time_cnt1 == 18'h3ffff)//清零
  142.                            next_state = Disp_on_off ;
  143.                      else
  144.                            next_state = crt_state ;                 
  145.                                   
  146.                                
  147.           Disp_on_off: if(time_cnt1 == 18'h3ffff)//显示开、关
  148.                            next_state = Cursor ;
  149.                        else
  150.                            next_state = crt_state ;  
  151.                            
  152.           Cursor   : if(time_cnt1 == 18'h3ffff)//光标设置
  153.                            next_state = Stand_by ;
  154.                      else
  155.                            next_state = crt_state ;
  156.          
  157.          
  158.            Stand_by   :if(!addr_tirg1&&i_addr_trig1)//准备就绪
  159.                            next_state = Wr_address1 ;
  160.                        else if(!addr_tirg2&&i_addr_trig2)
  161.                             next_state = Wr_address2 ;
  162.                         else
  163.                            next_state = crt_state ;

  164.           Wr_address1   : if( !data_trig &&i_data_trig)//写第一行数据
  165.                                next_state = Wr_data1 ;           
  166.                            else
  167.                                next_state = crt_state ;

  168.            Wr_data1    : if(data_cnt==4'd6&&time_cnt2 == 16'hffff)  //写第一行数据,返回准备状态
  169.                            next_state = Stand_by ;
  170.                         else
  171.                            next_state = crt_state ;                                                      
  172.                            
  173.          Wr_address2   : if( !data_trig &&i_data_trig)//第二行数据
  174.                                  next_state = Wr_data2 ;            
  175.                              else                                   
  176.                                  next_state = crt_state ;           
  177.            
  178.            Wr_data2    : if(data_cnt==4'd4&&time_cnt2==16'hffff)  //第二行数据  
  179.                              next_state = Stand_by ;                     
  180.                           else                                                        
  181.                              next_state = crt_state ;
  182.                                                                   
  183.         default :next_state = Idle ;
  184.      endcase                    


  185. //==================================================================端口输出

  186. ///////lcd_rs,1写数据 ,0写命令
  187. always@( posedge i_50m_clk or negedge i_rst_n )//     
  188.     if( !i_rst_n )
  189.            o_lcd_rs <= 1'b0 ;
  190.     else if((crt_state ==Wr_data2||crt_state ==Wr_data1)&&cnt_4000<16'd4000)
  191.            o_lcd_rs <= 1'b1 ;
  192.    else
  193.            o_lcd_rs <= 1'b0 ;
  194.             
  195. //==lcd_rw ,总是写
  196. always@( posedge i_50m_clk)
  197.        o_lcd_rw <= 1'b0 ;

  198.    

  199. //====lcd_en

  200. always@( posedge i_50m_clk or negedge i_rst_n )//     
  201.     if( !i_rst_n )
  202.           o_lcd_en <= 1'b0 ;
  203.     else if(crt_state==Stand_by)
  204.           o_lcd_en <= 1'b0 ;
  205.     else if(cnt_4000>5'd10&&cnt_4000<16'd3990)
  206.            o_lcd_en <= 1'b1 ;        
  207.     else                             
  208.            o_lcd_en <=  1'b0 ;
  209.             
  210.             
  211. //lcd_data ,?????            
  212. always@( *)
  213.        case(crt_state)
  214.                Idle                      :  o_lcd_data = 8'h38 ;
  215.                Set_mode                  :  o_lcd_data = 8'h38 ;//模式设置
  216.         Disp_on_off               :  o_lcd_data = 8'h0e ;//显示开、关
  217.         Cursor                    :  o_lcd_data = 8'h06 ;//光标设置
  218.         Clear                     :  o_lcd_data = 8'h01 ;//清零
  219.         Wr_address1,Wr_address2   :  o_lcd_data = address  [7:0]  ; //地址                                                
  220.         Wr_data1 ,Wr_data2        :  o_lcd_data = disp_data[7:0]  ;//数据
  221.          default :     o_lcd_data = 8'hff ;
  222.         
  223.        endcase  
  224.       
  225. endmodule            
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表