zoukankan      html  css  js  c++  java
  • 基于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,先到这,明天在完善吧。。。。

  • 相关阅读:
    Oracle EBS 初始化用户密码
    Oracle EBS FND User Info API
    linux ERROR: ld.so: object '/lib/libcwait.so' from /etc/ld.so.preload cannot be preloaded: ignored.
    linux解压cpio.gz类型文件
    linux删除乱码文件
    linux使用man命令后退出
    linux字符图形界面
    Red Hat linux 如何增加swap空间
    Linux删除文件夹命令
    Linux本地无法登录,远程却可以登录
  • 原文地址:https://www.cnblogs.com/wen2376/p/3391612.html
Copyright © 2011-2022 走看看