基于I2C EPPRPM(AT24C02B) + LCD12864实验

本次实验目的:在指定的EPPROM地址中,写入一数据,延时100MS后,在从该地址中读取,并在LCD上显示。

该实验在前两天就开始做了,一开始并没有成功,读出的一直0x00,当时也调了一会,但跳回到PS2鼠标实验继续调试(因为晚上睡觉会一直想那个问题),当把PS2鼠标实验调通之后,感觉自己对时序图有进一步的好感,写状态机时,我能抓住每一个动作细节,这就是经验吧,然后今天晚上调试I2C实验,直接对着时序图一步一步检查状态机的变动,经过仔细的检查,确实发现不少问题,当场就改掉,检查完一遍后(仅检查了一遍),改完后立即编译下载到板子上验证,结果很OK。此时我非常高兴,PS2鼠标实验花了那么长的时间去调试,是值得的。

由于主板子上没有EPPROM,故在外面用飞线接了一个AT24C02B器件,如下图。

在写代码前,建议先看看特权视频,有了一定的了解后,在去仔细的去琢磨I2C的时序。

1、首先得知道起始和停止在什么时候产生,

2、主机到设备发送数据时,是在时钟为低时改变数据,每发完一组数据,设备都会产生应答位。

3、主机从设备中读取数据时,是在时钟为高时进行锁存,因为在时钟高电平期间,SDA上的数据是稳定的,如果是连续读,每读完一组数据,主机一般要给设备发送应答位,读到最后一组数据时,主机可以不发送应答位,直接发送停止信号作为结束。

 

代码实现:

i2c_epprom.v

  1 // 给EPPROM 写数据,延时100ms后读出该数据
  2 ////////////////////////////////////////////////////////////////////////////////
  3 `timescale 1 ns/ 1 ps
  4 module i2c_epprom(
  5                     //input 
  6                     sys_clk,
  7                     rst_n,
  8                 
  9                     //output
 10                     scl,
 11                     sda,   //inout
 12                     dis_data_low,
 13                     dis_data_hig
 14                 );
 15 
 16 input     sys_clk;                // 50MHz
 17 input     rst_n;                    //复位信号,低有效
 18 output     scl;                    // 24C02的时钟端口
 19 inout     sda;                    // 24C02的数据端口
 20 output [7:0] dis_data_low;        //LCD显示的数据
 21 output [7:0] dis_data_hig;
 22 /**************************************************************/
 23 parameter     T100MS              =     23'd4_999_999;
 24 parameter     IDLE              =     5'd0;
 25 parameter     START1              =     5'd1;
 26 parameter     ADD1              =     5'd2;
 27 parameter     ACK1              =     5'd3;
 28 parameter     ADD2              =     5'd4;
 29 parameter     ACK2              =     5'd5;
 30 parameter   WR_DATA          =     5'd6;
 31 parameter    ACK2_1           =     5'd7;
 32 parameter     STOP1              =     5'd8;
 33 parameter   DELAY            =     5'd9;
 34 parameter     START2              =     5'd10;
 35 parameter     ADD3              =     5'd11;
 36 parameter     ACK3             =     5'd12;
 37 parameter   RD_DATA          =     5'd13;
 38 parameter     ACK4             =     5'd14;
 39 parameter     STOP2              =     5'd15;
 40 parameter    OVER             =     5'd16;
 41 /**************************************************************/
 42 //100ms计数
 43 reg [22:0] cnt1;
 44 reg cnt_en;
 45 always @ (posedge sys_clk or negedge rst_n)
 46 if(!rst_n) 
 47     cnt1 <= 23'd0;
 48 else if((!cnt_en) || (cnt1 == T100MS)) 
 49     cnt1 <= 23'd0;
 50 else 
 51     cnt1 <= cnt1+1'b1;
 52 /**************************************************************/
 53 //分频部分
 54 // cnt=0:scl上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl低电平中间
 55 reg[2:0] cnt;    
 56 reg[8:0] cnt_delay;                            //500循环计数,产生iic所需要的时钟
 57 reg scl_r;                                    //时钟脉冲寄存器
 58 always @ (posedge sys_clk or negedge rst_n)
 59 if(!rst_n) 
 60     cnt_delay <= 9'd0;
 61 else if(cnt_delay == 9'd499) 
 62     cnt_delay <= 9'd0;                        //计数到10us为scl的周期,即100KHz
 63 else 
 64     cnt_delay <= cnt_delay + 1'b1;            //时钟计数
 65 /**************************************************************/
 66 always @ (posedge sys_clk or negedge rst_n)
 67 if(!rst_n) 
 68     cnt <= 3'd5;
 69 else begin
 70     case (cnt_delay)
 71     9'd0      :     cnt <= 3'd0;                //cnt=0:scl上升沿
 72     9'd124    :    cnt <= 3'd1;                //cnt=1:scl高电平中间,用于数据采样
 73     9'd249    :    cnt <= 3'd2;                //cnt=2:scl下降沿
 74     9'd374    :    cnt <= 3'd3;                //cnt=3:scl低电平中间,用于数据变化
 75 //    9'd499    :    cnt <= 3'd0;                //cnt=0:scl上升沿
 76     default    :     cnt <= 3'd5;
 77     endcase
 78 end
 79 
 80 /**************************************************************/
 81 `define     SCL_POS            (cnt == 3'd0)        //cnt=0:scl上升沿
 82 `define     SCL_HIG            (cnt == 3'd1)        //cnt=1:scl高电平中间,用于数据采样
 83 `define     SCL_NEG            (cnt == 3'd2)        //cnt=2:scl下降沿
 84 `define     SCL_LOW            (cnt == 3'd3)        //cnt=3:scl低电平中间,用于数据变化
 85 /**************************************************************/        
 86 `define        DEVICE_READ        8'b1010_0001 //被寻址器件地址(读操作)a1
 87 `define     DEVICE_WRITE    8'b1010_0000 //被寻址器件地址(写操作)a0
 88 `define        WRITE_DATA        8'hc8         //写入EEPROM的数据  
 89 `define     BYTE_ADDR        8'h03          //写入/读出EEPROM的地址寄存器    
 90 /**************************************************************/
 91 always @ (posedge sys_clk or negedge rst_n)
 92 if(!rst_n) 
 93     scl_r <= 1'b0;
 94 else if(cnt_delay == 9'd0/*cnt==3'd0*/) 
 95     scl_r <= 1'b1;                            //scl信号上升沿
 96 else if(cnt_delay == 9'd249/*cnt==3'd2*/) 
 97     scl_r <= 1'b0;                            //scl信号下降沿
 98 
 99 assign scl = scl_r;                            //产生iic所需要的时钟
100 /**************************************************************/
101 reg [7:0] db_r;                                //在IIC上传送的数据寄存器
102 reg [7:0] read_data;                        //读出EEPROM的数据寄存器
103 reg [4:0] cstate;                            //状态寄存器
104 reg [3:0] num;
105 reg       sda_r;                            //输出数据寄存器
106 reg       sda_link;                            //输出数据sda信号inout方向控制位        
107 reg       rd_flag;                            //读操作标志
108 always @ (posedge sys_clk or negedge rst_n)
109 if(!rst_n) begin
110     cstate <= IDLE;
111     sda_r <= 1'b1;
112     sda_link <= 1'b0;
113     num <= 4'd0;
114     rd_flag <= 1'b0;
115     read_data <= 8'b0000_0000;
116     cnt_en <= 1'b0;
117 end
118 else begin       
119     case (cstate)
120         IDLE:
121         begin
122             sda_link <= 1'b1;                //数据线sda为输出
123             sda_r <= 1'b1;        
124             cstate <= START1;        
125             db_r <= `DEVICE_WRITE;            //送器件地址(写操作)
126         end        
127                 
128         START1:         
129         begin        
130             if(`SCL_HIG) begin                //scl为高电平期间
131                 num <= 4'd0;                //num计数清零
132                 sda_link <= 1'b1;            //数据线sda为output
133                 sda_r <= 1'b0;                //拉低数据线sda,产生起始位信号
134                 cstate <= ADD1;        
135             end        
136             else         
137                 cstate <= START1;             //等待scl高电平中间位置到来
138         end        
139                     
140         ADD1:            
141         begin                                  //给EPPROM送入器件地址
142             if(`SCL_LOW) begin        
143                 if(num == 4'd8) begin        
144                     num <= 4'd0;            //num计数清零
145                     sda_r <= 1'b1;             
146                     sda_link <= 1'b0;        //sda置为高阻态(input)
147                     cstate <= ACK1;
148                 end
149                 else begin
150                     sda_link <= 1'b1;
151                     num <= num+1'b1;
152                     case (num)
153                     4'd0    :    sda_r <= db_r[7];
154                     4'd1    :    sda_r <= db_r[6];
155                     4'd2    :    sda_r <= db_r[5];
156                     4'd3    :    sda_r <= db_r[4];
157                     4'd4    :    sda_r <= db_r[3];
158                     4'd5    :    sda_r <= db_r[2];
159                     4'd6    :    sda_r <= db_r[1];
160                     4'd7    :    sda_r <= db_r[0];
161                     default    :                     ;
162                     endcase
163                     cstate <= ADD1;
164                 end
165             end
166             else 
167                 cstate <= ADD1;
168         end
169         ACK1: 
170         begin
171             if(`SCL_NEG) begin                //注:24C01/02/04/08/16器件可以不考虑应答位
172                 db_r <= `BYTE_ADDR;            // 1地址
173                 cstate <= ADD2;                //从机响应信号                    
174             end
175             else 
176                 cstate <= ACK1;                //等待从机响应
177         end
178              
179         ADD2:    
180         begin                               //给EPPROM送入存储地址
181             if(`SCL_LOW) begin
182                 if(num==4'd8) begin    
183                     num <= 4'd0;            //num计数清零
184                     sda_r <= 1'b1;
185                     sda_link <= 1'b0;        //sda置为高阻态(input)
186                     cstate <= ACK2;
187                 end
188                 else begin
189                     sda_link <= 1'b1;        //sda作为output
190                     num <= num+1'b1;
191                     case (num)
192                     4'd0    :    sda_r <= db_r[7];
193                     4'd1    :    sda_r <= db_r[6];
194                     4'd2    :    sda_r <= db_r[5];
195                     4'd3    :    sda_r <= db_r[4];
196                     4'd4    :    sda_r <= db_r[3];
197                     4'd5    :    sda_r <= db_r[2];
198                     4'd6    :    sda_r <= db_r[1];
199                     4'd7    :    sda_r <= db_r[0];
200                     default    :                     ;
201                     endcase        
202                     cstate <= ADD2;                    
203                 end
204             end
205             else 
206                 cstate <= ADD2;                
207         end
208         
209         ACK2: 
210         begin
211             if(`SCL_NEG) begin                //从机响应信号
212                 if(!rd_flag) begin
213                     rd_flag <= 1'b1;          //标志下轮进入读状态                    
214                     db_r <= `WRITE_DATA;    //写入的数据
215                     cstate <= WR_DATA;         //写数据
216                 end
217                 else begin
218                     rd_flag <= 1'b0;
219                     cstate <= START2;
220                 end
221             end
222             else 
223                 cstate <= ACK2;                //等待从机响应
224        end
225 
226         WR_DATA: 
227         begin
228             if(num<=4'd7) begin
229                 if(`SCL_LOW) begin
230                     sda_link <= 1'b1;        //sda作为output
231                     num <= num+1'b1;
232                     case (num)
233                     4'd0    :    sda_r <= db_r[7];
234                     4'd1    :    sda_r <= db_r[6];
235                     4'd2    :    sda_r <= db_r[5];
236                     4'd3    :    sda_r <= db_r[4];
237                     4'd4    :    sda_r <= db_r[3];
238                     4'd5    :    sda_r <= db_r[2];
239                     4'd6    :    sda_r <= db_r[1];
240                     4'd7    :    sda_r <= db_r[0];
241                     default    :                     ;
242                     endcase
243                     cstate <= WR_DATA;
244                 end
245             end
246             else if((`SCL_LOW) && (num==4'd8)) begin
247                 num <= 4'd0;
248                 sda_r <= 1'b1;
249                 sda_link <= 1'b0;            //sda置为高阻态
250                 cstate <= ACK2_1;
251             end
252         end
253         
254         ACK2_1: 
255         begin
256             if(`SCL_NEG)
257                 cstate <= STOP1;                    
258             else 
259                 cstate <= ACK2_1;
260         end
261         
262         STOP1:    
263         begin
264             if(`SCL_LOW) begin
265                 sda_link <= 1'b1;
266                 sda_r <= 1'b0;
267                 cstate <= STOP1;
268             end
269             else if(`SCL_HIG) begin
270                 sda_link <= 1'b1;
271                 sda_r <= 1'b1;                //scl为高时,sda产生上升沿(结束信号)
272                 cnt_en <= 1'b1;                //启动100MS计数器
273                 cstate <= DELAY;
274             end
275         end
276         
277         DELAY:                               //延时100ms后在进行读
278         begin
279             if(cnt1 == T100MS) begin
280                 cnt_en <= 1'b0;
281                 cstate <= IDLE;
282             end
283             else begin    
284                 sda_link <= 1'b1;
285                 sda_r <= 1'b1;
286                 cstate <= DELAY;
287             end
288         end
289             
290         START2: 
291         begin                                //读操作起始位
292             if(`SCL_LOW) begin
293                 sda_link <= 1'b1;            //sda作为output
294                 sda_r <= 1'b1;                //拉高数据线sda
295                 cstate <= START2;
296             end
297             else if(`SCL_HIG) begin            //scl为高电平中间
298                 num <= 4'd0;
299                 sda_link <= 1'b1;
300                 sda_r <= 1'b0;                //拉低数据线sda,产生起始位信号
301                 db_r <= `DEVICE_READ;          //准备读
302                 cstate <= ADD3;
303             end     
304             else 
305                 cstate <= START2;
306         end
307             
308         ADD3:    
309         begin                                //送器件地址 读操作
310             if(`SCL_LOW) begin
311                 if(num==4'd8) begin    
312                     num <= 4'd0;            //num计数清零
313                     sda_r <= 1'b1;
314                     sda_link <= 1'b0;        //sda置为高阻态(input)
315                     cstate <= ACK3;
316                 end
317                 else begin
318                     sda_link <= 1'b1;
319                     num <= num+1'b1;
320                     case (num)
321                     4'd0    :    sda_r <= db_r[7];
322                     4'd1    :    sda_r <= db_r[6];
323                     4'd2    :    sda_r <= db_r[5];
324                     4'd3    :    sda_r <= db_r[4];
325                     4'd4    :    sda_r <= db_r[3];
326                     4'd5    :    sda_r <= db_r[2];
327                     4'd6    :    sda_r <= db_r[1];
328                     4'd7    :    sda_r <= db_r[0];
329                     default    :                     ;
330                     endcase     
331                     cstate <= ADD3;                    
332                 end
333             end
334             else cstate <= ADD3;                
335         end
336             
337         ACK3:
338         begin
339             if(`SCL_NEG)
340                 cstate <= RD_DATA;            //从机响应信号
341             else 
342                 cstate <= ACK3;             //等待从机响应
343         end
344         
345         RD_DATA:
346         begin
347             if(num<=4'd7) begin
348                 if(`SCL_HIG) begin    
349                     sda_link <= 1'b0;        // sda 作为输入管脚
350                     num <= num+1'b1;    
351                     case (num)
352                     4'd0    :    read_data[7] <= sda;
353                     4'd1    :    read_data[6] <= sda;  
354                     4'd2    :    read_data[5] <= sda; 
355                     4'd3    :    read_data[4] <= sda; 
356                     4'd4    :    read_data[3] <= sda; 
357                     4'd5    :    read_data[2] <= sda; 
358                     4'd6    :    read_data[1] <= sda; 
359                     4'd7    :    read_data[0] <= sda; 
360                     default    :                         ;
361                     endcase    
362                     cstate <= RD_DATA;    
363                 end
364                 else
365                     cstate <= RD_DATA;
366             end
367             else if((`SCL_LOW) && (num==4'd8)) begin
368                 num <= 4'd0;            //num计数清零
369                 sda_link <= 1'b1;
370                 sda_r <= 1'b0;           //数据拉低,准备产生停止信号
371                 cstate <= ACK4;          //这里也可以直接跳到STOP2
372             end
373             else
374                 cstate <= RD_DATA;
375         end
376         
377         ACK4:                              //主机发出应答为
378         begin
379             if(`SCL_NEG) 
380                 cstate <= STOP2;                        
381             else 
382                 cstate <= ACK4;
383         end
384         
385         STOP2:
386         begin
387             if(`SCL_HIG) begin
388                 sda_link <= 1'b1;
389                 sda_r <= 1'b1;          //产生结束信号
390                 cstate <= OVER;
391             end
392             else
393                 cstate <= STOP2;
394         end
395         
396         OVER: cstate <= OVER;
397         
398         default: cstate <= IDLE;
399         
400         endcase
401 end
402 /**************************************************************/
403 //sda_link =  1, 作为输出
404 //sda_link =  0, 作为输入,FPGA内部得把该管脚设置为高祖太,可以接收高低电平
405 assign sda = sda_link ? sda_r:1'bz; 
406 /**************************************************************/
407 reg [7:0] dis_data_low;
408 always @(read_data[3:0])
409     case(read_data[3:0])
410         4'h0: dis_data_low = "0";
411         4'h1: dis_data_low = "1";
412         4'h2: dis_data_low = "2";
413         4'h3: dis_data_low = "3";
414         4'h4: dis_data_low = "4";
415         4'h5: dis_data_low = "5";
416         4'h6: dis_data_low = "6";
417         4'h7: dis_data_low = "7";
418         4'h8: dis_data_low = "8";
419         4'h9: dis_data_low = "9";
420         4'ha: dis_data_low = "a";
421         4'hb: dis_data_low = "b";
422         4'hc: dis_data_low = "c";
423         4'hd: dis_data_low = "d";
424         4'he: dis_data_low = "e";
425         4'hf: dis_data_low = "f";
426     endcase
427 /**************************************************************/
428 reg [7:0] dis_data_hig;
429 always @(read_data[7:4])
430     case(read_data[7:4])
431         4'h0: dis_data_hig = "0";
432         4'h1: dis_data_hig = "1";
433         4'h2: dis_data_hig = "2";
434         4'h3: dis_data_hig = "3";
435         4'h4: dis_data_hig = "4";
436         4'h5: dis_data_hig = "5";
437         4'h6: dis_data_hig = "6";
438         4'h7: dis_data_hig = "7";
439         4'h8: dis_data_hig = "8";
440         4'h9: dis_data_hig = "9";
441         4'ha: dis_data_hig = "a";
442         4'hb: dis_data_hig = "b";
443         4'hc: dis_data_hig = "c";
444         4'hd: dis_data_hig = "d";
445         4'he: dis_data_hig = "e";
446         4'hf: dis_data_hig = "f";
447     endcase
448 /**************************************************************/
449 endmodule
View Code

LCD12864.v

  1 module LCD12864(
  2                     //input 
  3                     sys_clk,
  4                     rst_n,
  5                     dis_data_low,
  6                     dis_data_hig,
  7                     
  8                     //output 
  9                     lcd_rs,
 10                     lcd_rw,
 11                     lcd_en,
 12                     lcd_data,
 13                     lcd_psb
 14                 );
 15 input sys_clk;// 50MHZ
 16 input rst_n;
 17 input [7:0] dis_data_low;
 18 input [7:0] dis_data_hig;
 19 
 20 output lcd_rs;//H:data    L:command
 21 output lcd_rw;//H:read module    L:write module
 22 output lcd_en;//H active
 23 output [7:0] lcd_data;
 24 output lcd_psb;//H:parallel    module    L:SPI module
 25 
 26 /***************************************************/
 27 parameter T3MS = 18'd149_999;
 28 parameter    IDLE           = 5'd0,
 29             INIT_FUN_SET1 = 5'd1,
 30             INIT_FUN_SET2 = 5'd2,
 31             INIT_DISPLAY  = 5'd3,
 32             INIT_CLEAR       = 5'd4,
 33             INIT_DOT_SET  = 5'd5,
 34             SET_DDRAM      = 5'd6,
 35             WRITE_DATA0      = 5'd7,
 36             SET_DDRAM2    = 5'd8,
 37             WRITE_DATA1   = 5'd9,
 38             WRITE_DATA2   = 5'd10,
 39             WRITE_DATA3   = 5'd11;
 40             
 41 
 42 /***************************************************/
 43 //产生周期为6MS的lcd_clk给LCD
 44 reg [17:0] cnt;
 45 reg lcd_clk;
 46 always @(posedge sys_clk or negedge rst_n)
 47 if(!rst_n) begin
 48     cnt <= 18'd0;
 49     lcd_clk <= 1'b0;
 50 end
 51 else if(cnt == T3MS)begin
 52     cnt <= 18'd0;
 53     lcd_clk <= ~lcd_clk;
 54 end
 55 else
 56     cnt <= cnt + 1'b1;
 57 
 58 /***************************************************/
 59 reg lcd_rs;
 60 reg [4:0] state;
 61 always @(posedge lcd_clk or negedge rst_n)
 62 if(!rst_n)
 63     lcd_rs <= 1'b0;
 64 else if((state == WRITE_DATA0)  || (state == WRITE_DATA1) 
 65         || (state == WRITE_DATA2)  || (state == WRITE_DATA3))
 66     lcd_rs <= 1'b1;        //写数据模式
 67 else
 68     lcd_rs <= 1'b0;        //写命令模式
 69 /***************************************************/
 70 reg [7:0] lcd_data;
 71 reg [7:0] dis_data;
 72 reg [6:0] num;
 73 reg en;
 74 always @(posedge lcd_clk or negedge rst_n)
 75 if(!rst_n) begin
 76     state <= IDLE;
 77     lcd_data <= 8'h00;
 78     en <= 1'b1;
 79     num <= 7'd0;
 80 end    
 81 else 
 82     case(state)
 83         IDLE: 
 84         begin
 85             state <= INIT_FUN_SET1;
 86             lcd_data <= 8'hzz;
 87             en <= 1'b1;
 88         end
 89         
 90         INIT_FUN_SET1: 
 91         begin
 92             lcd_data <= 8'h30;    //功能设定
 93             state <= INIT_FUN_SET2;
 94         end 
 95         
 96         INIT_FUN_SET2:
 97         begin
 98             lcd_data <= 8'h30;    //功能设定
 99             state <= INIT_DISPLAY;
100         end
101             
102         INIT_DISPLAY:
103         begin
104             lcd_data <= 8'h0c;    //显示设定
105             state <= INIT_CLEAR;
106         end
107             
108         INIT_CLEAR:
109         begin
110             lcd_data <= 8'h01;    //清屏
111             state <= INIT_DOT_SET;
112         end
113         
114         INIT_DOT_SET:
115         begin
116             lcd_data <= 8'h06;    //进入点设定
117             state <= SET_DDRAM;
118         end
119         
120         SET_DDRAM:
121         begin
122             lcd_data <= 8'h91;//2 line            
123             state <= WRITE_DATA0;
124         end
125         
126         WRITE_DATA0:  ////I2C通信实验
127         begin
128             if(num == 7'd11)
129                 state <= SET_DDRAM2;
130             else begin
131                 num <= num + 1'b1;
132                 lcd_data <= dis_data;
133                 state <= WRITE_DATA0;  
134             end
135         end
136         
137         SET_DDRAM2:
138         begin
139             lcd_data <= 8'h89;//3 line            
140             state <= WRITE_DATA1;
141         end
142         
143         WRITE_DATA1:  //03地址值
144         begin
145             if(num == 7'd20) begin
146                 num <= 7'd0;
147                 state <= WRITE_DATA2;
148             end
149             else begin
150                 num <= num + 1'b1;
151                 lcd_data <= dis_data;
152                 state <= WRITE_DATA1;  
153             end
154         end
155         
156         WRITE_DATA2: //高字节
157         begin
158             lcd_data <= dis_data_hig;
159             state <= WRITE_DATA3;  
160         end
161         
162         WRITE_DATA3://低字节
163         begin
164             lcd_data <= dis_data_low;
165             state <= SET_DDRAM;  
166         end
167 
168 /*        STOP: 
169         begin
170             en <= 1'b0;//显示完了,lcd_e就一直拉为低
171             state <= STOP;
172         end   */
173         
174         default: state <= IDLE;
175     endcase
176 
177 
178 always @(posedge sys_clk or negedge rst_n)
179 if(!rst_n)
180     dis_data <= 8'h00;
181 else
182     case(num)
183     //I2C通信实验%CD%A8%D0%C5%CA%B5%D1%E9
184     7'd0   :    dis_data <= "I";
185     7'd1   :    dis_data <= "2"; 
186     7'd2   :    dis_data <= "C";
187     7'd3   :    dis_data <= " ";//8'hcd;
188     7'd4   :    dis_data <= "E";//8'ha8;
189     7'd5   :    dis_data <= "P";//8'hd0;
190     7'd6   :    dis_data <= "P";//8'hc5;
191     7'd7   :    dis_data <= "R";//8'hca;
192     7'd8   :    dis_data <= "O";//8'hb5;
193     7'd9   :    dis_data <= "M";//8'hd1;
194     7'd10  :    dis_data <= " ";//8'he9;
195     //03地址值 %B5%D8%D6%B7
196     7'd11  :    dis_data <= "0";
197     7'd12  :    dis_data <= "3";
198     7'd13  :    dis_data <= 8'hb5;
199     7'd14  :    dis_data <= 8'hd8; 
200     7'd15  :    dis_data <= 8'hd6; 
201     7'd16  :    dis_data <= 8'hb7; 
202     7'd17  :    dis_data <= 8'hd6;
203     7'd18  :    dis_data <= 8'hb5;
204     7'd19  :    dis_data <= " ";
205     default:    dis_data <= 8'h00;
206     endcase
207 /***************************************************/
208 assign lcd_rw = 1'b0;//只有写模式
209 assign lcd_psb = 1'b1;//并口模式
210 assign lcd_en = en ?  lcd_clk : 1'b0;
211 /***************************************************/
212 endmodule
View Code

i2c_top.v

 1 module i2c_top(
 2                 //input 
 3                 sys_clk,
 4                 rst_n,
 5                 
 6                 //inout
 7                 sda,
 8                 
 9                 //output
10                 scl,
11                 lcd_rs,
12                 lcd_rw,
13                 lcd_en,
14                 lcd_data,
15 //                lcd_psb
16                 );
17 input sys_clk;        // 50MHz
18 input rst_n;    //复位信号,低有效
19 output scl;        // 24C02的时钟端口
20 inout sda;        // 24C02的数据端口
21 
22 output lcd_rs;//H:data    L:command
23 output lcd_rw;//H:read module    L:write module
24 output lcd_en;//H active
25 output [7:0] lcd_data;
26 //output lcd_psb;//H:parallel    module    L:SPI module
27 wire [7:0] dis_data_low;
28 wire [7:0] dis_data_hig;
29 
30 i2c_epprom    u1(
31                         //input 
32                         .sys_clk(sys_clk),
33                         .rst_n(rst_n),
34                     
35                         //output
36                         .scl(scl),
37                         .sda(sda),
38                         .dis_data_low(dis_data_low),
39                         .dis_data_hig(dis_data_hig)
40                     );
41                     
42 LCD12864        u2(
43                         //input 
44                         .sys_clk(sys_clk),
45                         .rst_n(rst_n),
46                         .dis_data_low(dis_data_low),
47                         .dis_data_hig(dis_data_hig),
48                         
49                         //output 
50                         .lcd_rs(lcd_rs),
51                         .lcd_rw(lcd_rw),
52                         .lcd_en(lcd_en),
53                         .lcd_data(lcd_data)
54 //                        .lcd_psb(lcd_psb)
55                         );
56 endmodule
View Code

OK,先到这,明天在完善吧。。。。

原文地址:https://www.cnblogs.com/wen2376/p/3391612.html