- module i2c(clk,rst,scl,sda,lcd_en ,
- lcd_rw , //��Ϊִֻ��д������������ԶΪ0.
- lcd_rs ,
- lcd_data,led1,led2,led3,led4,adc_data);
- input clk,rst;
- output scl;
- inout sda;
- output led1,led2,led3,led4;
- output adc_data;
- output lcd_en ;
- output lcd_rw ;
- output lcd_rs ;
- output [7:0] lcd_data;
- reg scl;
- reg adc_data;
- reg ledn1,ledn2,ledn3,ledn4;
- reg[23:0] cnt_scan;
- reg sda_buf;
- reg link;
- reg phase0,phase1,phase2,phase3;
- reg[7:0] clk_div;
- reg[1:0] main_state;
- reg[3:0] i2c_state;
- reg[3:0] inner_state;
- reg[19:0] cnt_delay;
- reg start_delaycnt;
- reg[7:0] readData_reg;
- reg[7:0] addr;
- //--------------------------------------------
- //按键检测
- reg[19:0] cnt_20ms; //20ms计数寄存器
- always [url=home.php?mod=space&uid=72445]@[/url] (posedge clk or negedge rst)
- if(!rst) cnt_20ms <= 20'd0;
- else cnt_20ms <= cnt_20ms+1'b1; //不断计数
- parameter div_parameter=100;
- parameter start=4'b0000,
- first=4'b0001,
- second=4'b0010,
- third=4'b0011,
- fourth=4'b0100,
- fifth=4'b0101,
- sixth=4'b0110,
- seventh=4'b0111,
- eighth=4'b1000,
- ack=4'b1001,
- stop=4'b1010;
-
- parameter ini=4'b0000,
- sendaddr=4'b0001,
- //write_data=3'b010,
- read_data=4'b0010,
- read_ini=4'b0011,
- read_s1=4'b0100,
- read_s2=4'b0101,
- read_s3=4'b0110,
- read_s4=4'b0111,
- read_s5=4'b1000,
- read_s6=4'b1001,
- read_s7=4'b1010,
- read_s8=4'b1011,
- read_s9=4'b1100,
- read_s10=4'b1101,
- read_s11=4'b1110,
- read_s12=4'b1111;
-
-
- wire lcd_en ;
- wire lcd_rw;
- reg [7:0] lcd_data;
- reg lcd_rs ;
- reg [5:0] c_state ;
- reg [5:0] n_state ;
- wire [127:0] row_1;
- wire [127:0] row_2;
- //reg[7:0] dis_data=0;
- assign row_1 [127:120]=8'h30+adc_data/100;
- assign row_1 [119:112]=8'h30+adc_data%100/10;
- assign row_1 [111:104]=8'h30+adc_data%10;
- assign row_1 [103:96]=8'h20;
- assign row_1 [95:88]=8'h20;
- assign row_1 [87:80]=8'h20;
- assign row_1 [79:72]=8'h20;
- assign row_1 [71:64]=8'h20;
- assign row_1 [63:56]=8'h20;
- assign row_1 [55:48]=8'h20;
- assign row_1 [47:40]=8'h41;
- assign row_1 [39:32]=8'h42;
- assign row_1 [31:24]=8'h43;
- assign row_1 [23:16]=8'h44;
- assign row_1 [15:8]=8'h45;
- assign row_1 [7:0]=8'h46;
- //assign row_1 =" " ; //��һ����ʾ������
- assign row_2 ="happy everyday !"; //�ڶ�����ʾ������
- //----------------------------------------------------------------------
- //initialize
- //first step is waitng more than 20 ms. �����ֲ�Ҫ���ģ�Ŀ���ǵȴ�ϵͳ�ϵ��ȶ���
- parameter TIME_20MS = 1000_000 ; //20000000/20=1000_000
- parameter TIME_200MS = 1000_0000_0 ; //20000000/20=1000_000
- //parameter TIME_15MS = 9'h100 ; //just for test
- parameter TIME_500HZ= 100_000 ; //
- //parameter TIME_500HZ= 4'hf; //just for test
- //use gray code
- parameter IDLE= 8'h00 ; //��Ϊ��״̬��һ����40��״̬�������������˸����룬һ��ֻ��1λ�����ı䡣00 01 03 02
- parameter SET_FUNCTION= 8'h01 ;
- parameter DISP_OFF= 8'h03 ;
- parameter DISP_CLEAR= 8'h02 ;
- parameter ENTRY_MODE= 8'h06 ;
- parameter DISP_ON = 8'h07 ;
- parameter ROW1_ADDR= 8'h05 ;
- parameter ROW1_0= 8'h04 ;
- parameter ROW1_1= 8'h0C ;
- parameter ROW1_2= 8'h0D ;
- parameter ROW1_3= 8'h0F ;
- parameter ROW1_4= 8'h0E ;
- parameter ROW1_5= 8'h0A ;
- parameter ROW1_6= 8'h0B ;
- parameter ROW1_7= 8'h09 ;
- parameter ROW1_8= 8'h08 ;
- parameter ROW1_9= 8'h18 ;
- parameter ROW1_A= 8'h19 ;
- parameter ROW1_B= 8'h1B ;
- parameter ROW1_C= 8'h1A ;
- parameter ROW1_D= 8'h1E ;
- parameter ROW1_E= 8'h1F ;
- parameter ROW1_F= 8'h1D ;
- parameter ROW2_ADDR= 8'h1C ;
- parameter ROW2_0= 8'h14 ;
- parameter ROW2_1= 8'h15 ;
- parameter ROW2_2= 8'h17 ;
- parameter ROW2_3= 8'h16 ;
- parameter ROW2_4= 8'h12 ;
- parameter ROW2_5= 8'h13 ;
- parameter ROW2_6= 8'h11 ;
- parameter ROW2_7= 8'h10 ;
- parameter ROW2_8= 8'h30 ;
- parameter ROW2_9= 8'h31 ;
- parameter ROW2_A= 8'h33 ;
- parameter ROW2_B= 8'h32 ;
- parameter ROW2_C= 8'h36 ;
- parameter ROW2_D= 8'h37 ;
- parameter ROW2_E= 8'h35 ;
- parameter ROW2_F= 8'h34 ;
- //20ms�ļ��������ʼ����һ��
- reg [19:0] cnt_20ms1 ;
- always @(posedge clk or negedge rst)begin
- if(rst==1'b0)begin
- cnt_20ms1<=0;
- end
- else if(cnt_20ms1 == TIME_20MS -1)begin
- cnt_20ms1<=cnt_20ms1;
- end
- else
- cnt_20ms1<=cnt_20ms1 + 1 ;
- end
- wire delay_done = (cnt_20ms1==TIME_20MS-1)? 1'b1 : 1'b0 ;
- //----------------------------------------------------------------------
- //500ns �����Ƿ�Ƶ����ΪLCD1602�Ĺ���Ƶ����500HZ,��FPGA��50Mhz,����Ҫ��Ƶ
- reg [19:0] cnt_500hz;
- always @(posedge clk or negedge rst)begin
- if(rst==1'b0)begin
- cnt_500hz <= 0;
- end
- else if(delay_done==1)begin
- if(cnt_500hz== TIME_500HZ - 1)
- cnt_500hz<=0;
- else
- cnt_500hz<=cnt_500hz + 1 ;
- end
- else
- cnt_500hz<=0;
- end
- //20ms�ļ��������ʼ����һ��
- reg [28:0] cnt_200ms ;
- always @(posedge clk or negedge rst)begin
- if(rst==1'b0)begin
- cnt_200ms<=0;
- end
- else if(cnt_200ms == TIME_200MS -1)begin
- cnt_200ms<=0;
- end
- else
- cnt_200ms<=cnt_200ms + 1 ;
- end
- assign lcd_en = (cnt_500hz>(TIME_500HZ-1)/2)? 1'b0 : 1'b1; //�½���
- assign write_flag = (cnt_500hz==TIME_500HZ - 1) ? 1'b1 : 1'b0 ;
- //set_function ,display off ��display clear ,entry mode set
- //----------------------------------------------------------------------״̬��
- always @(posedge clk or negedge rst)begin
- if(rst==1'b0)begin
- c_state <= IDLE ;
- end
- else if(write_flag==1) begin
- c_state<= n_state ;
- end
- else
- c_state<=c_state ;
- end
- always @(*)begin
- case (c_state)
- IDLE: n_state = SET_FUNCTION ;
- SET_FUNCTION: n_state = DISP_OFF ;
- DISP_OFF: n_state = DISP_CLEAR ;
- DISP_CLEAR: n_state = ENTRY_MODE ;
- ENTRY_MODE: n_state = DISP_ON ;
- DISP_ON : n_state = ROW1_ADDR ;
- ROW1_ADDR: n_state = ROW1_0 ;
- ROW1_0: n_state = ROW1_1 ;
- ROW1_1: n_state = ROW1_2 ;
- ROW1_2: n_state = ROW1_3 ;
- ROW1_3: n_state = ROW1_4 ;
- ROW1_4: n_state = ROW1_5 ;
- ROW1_5: n_state = ROW1_6 ;
- ROW1_6: n_state = ROW1_7 ;
- ROW1_7: n_state = ROW1_8 ;
- ROW1_8: n_state = ROW1_9 ;
- ROW1_9: n_state = ROW1_A ;
- ROW1_A: n_state = ROW1_B ;
- ROW1_B: n_state = ROW1_C ;
- ROW1_C: n_state = ROW1_D ;
- ROW1_D: n_state = ROW1_E ;
- ROW1_E: n_state = ROW1_F ;
- ROW1_F: n_state = ROW2_ADDR ;
- ROW2_ADDR: n_state = ROW2_0 ;
- ROW2_0: n_state = ROW2_1 ;
- ROW2_1: n_state = ROW2_2 ;
- ROW2_2: n_state = ROW2_3 ;
- ROW2_3: n_state = ROW2_4 ;
- ROW2_4: n_state = ROW2_5 ;
- ROW2_5: n_state = ROW2_6 ;
- ROW2_6: n_state = ROW2_7 ;
- ROW2_7: n_state = ROW2_8 ;
- ROW2_8: n_state = ROW2_9 ;
- ROW2_9: n_state = ROW2_A ;
- ROW2_A: n_state = ROW2_B ;
- ROW2_B: n_state = ROW2_C ;
- ROW2_C: n_state = ROW2_D ;
- ROW2_D: n_state = ROW2_E ;
- ROW2_E: n_state = ROW2_F ;
- ROW2_F: n_state = ROW1_ADDR ;
- default: n_state = n_state ;
- endcase
- end
- assign lcd_rw = 0;
- always @(posedge clk or negedge rst)begin
- if(rst==1'b0)begin
- lcd_rs <= 0 ; //order or data 0: order 1:data
- end
- else if(write_flag == 1)begin
- if((n_state==SET_FUNCTION)||(n_state==DISP_OFF)||
- (n_state==DISP_CLEAR)||(n_state==ENTRY_MODE)||
- (n_state==DISP_ON ) ||(n_state==ROW1_ADDR)||
- (n_state==ROW2_ADDR))begin
- lcd_rs<=0 ;
- end
- else begin
- lcd_rs<= 1;
- end
- end
- else begin
- lcd_rs<=lcd_rs;
- end
- end
- always @(posedge clk or negedge rst)begin
- if(rst==1'b0)begin
- lcd_data<=0 ;
- end
- else if(write_flag)begin
- case(n_state)
- IDLE: lcd_data <= 8'hxx;
- SET_FUNCTION: lcd_data <= 8'h38; //2*16 5*8 8���
- DISP_OFF: lcd_data <= 8'h08;
- DISP_CLEAR: lcd_data <= 8'h01;
- ENTRY_MODE: lcd_data <= 8'h06;
- DISP_ON : lcd_data <= 8'h0c; //��ʾ���ܿ���û�й��꣬�Ҳ���˸��
- ROW1_ADDR: lcd_data <= 8'h80; //00+80
- ROW1_0: lcd_data <= row_1 [127:120];
- ROW1_1: lcd_data <= row_1 [119:112];
- ROW1_2: lcd_data <= row_1 [111:104];
- ROW1_3: lcd_data <= row_1 [103: 96];
- ROW1_4: lcd_data <= row_1 [ 95: 88];
- ROW1_5: lcd_data <= row_1 [ 87: 80];
- ROW1_6: lcd_data <= row_1 [ 79: 72];
- ROW1_7: lcd_data <= row_1 [ 71: 64];
- ROW1_8: lcd_data <= row_1 [ 63: 56];
- ROW1_9: lcd_data <= row_1 [ 55: 48];
- ROW1_A: lcd_data <= row_1 [ 47: 40];
- ROW1_B: lcd_data <= row_1 [ 39: 32];
- ROW1_C: lcd_data <= row_1 [ 31: 24];
- ROW1_D: lcd_data <= row_1 [ 23: 16];
- ROW1_E: lcd_data <= row_1 [ 15: 8];
- ROW1_F: lcd_data <= row_1 [ 7: 0];
- ROW2_ADDR: lcd_data <= 8'hc0; //40+80
- ROW2_0: lcd_data <= row_2 [127:120];
- ROW2_1: lcd_data <= row_2 [119:112];
- ROW2_2: lcd_data <= row_2 [111:104];
- ROW2_3: lcd_data <= row_2 [103: 96];
- ROW2_4: lcd_data <= row_2 [ 95: 88];
- ROW2_5: lcd_data <= row_2 [ 87: 80];
- ROW2_6: lcd_data <= row_2 [ 79: 72];
- ROW2_7: lcd_data <= row_2 [ 71: 64];
- ROW2_8: lcd_data <= row_2 [ 63: 56];
- ROW2_9: lcd_data <= row_2 [ 55: 48];
- ROW2_A: lcd_data <= row_2 [ 47: 40];
- ROW2_B: lcd_data <= row_2 [ 39: 32];
- ROW2_C: lcd_data <= row_2 [ 31: 24];
- ROW2_D: lcd_data <= row_2 [ 23: 16];
- ROW2_E: lcd_data <= row_2 [ 15: 8];
- ROW2_F: lcd_data <= row_2 [ 7: 0];
- endcase
- end
- else
- lcd_data<=lcd_data ;
- end
- assign sda=(link)? sda_buf:1'bz;
- reg [19:0] tics;
- always @(posedge clk or negedge rst)
- begin
- if(!rst)
- tics<=0;
- else if(tics==20'hfffff)
- tics<=0;
- else
- tics<=tics+1;
- end
- always@(posedge clk or negedge rst)
- begin
- if(!rst)
- cnt_delay<=0;
- else begin
- if(start_delaycnt) begin
- if(cnt_delay!=20'd80)
- cnt_delay<=cnt_delay+1;
- else
- cnt_delay<=0;
- end
- end
- end
- always@(posedge clk or negedge rst)
- begin
- if(!rst) begin
- clk_div<=0;
- phase0<=0;
- phase1<=0;
- phase2<=0;
- phase3<=0;
- end
- else begin
- if(clk_div!=div_parameter-1)
- clk_div<=clk_div+1;
- else
- clk_div<=0;
- if(phase0)
- phase0<=0;
- else if(clk_div==99)
- phase0<=1;
- if(phase1)
- phase1<=0;
- else if(clk_div==24)
- phase1<=1;
- if(phase2)
- phase2<=0;
- else if(clk_div==49)
- phase2<=1;
- if(phase3)
- phase3<=0;
- else if(clk_div==74)
- phase3<=1;
- end
- end
- ///////////////////////////EEPROM/////////////
- always@(posedge clk or negedge rst)
- begin
- if(!rst) begin
- start_delaycnt<=0;
- main_state<=2'b00;
- i2c_state<=ini;
- inner_state<=start;
- scl<=1;
- sda_buf<=1;
- link<=0;
- ledn1<=1;
- ledn2<=1;
- ledn3<=1;
- ledn4<=1;
- readData_reg<=0;
- addr<=8'h40;
- end
- else begin
- case(main_state)
- 2'b00: begin
-
- scl<=1;
- sda_buf<=1;
- link<=0;
- inner_state<=start;
- i2c_state<=ini;
- if(cnt_delay==0)
- start_delaycnt<=1;
- else if(cnt_delay==20'd80) begin
- start_delaycnt<=0;
-
- main_state<=2'b10;
- end
- end
-
- 2'b10: begin
- if(phase0)
- scl<=1;
- else if(phase2)
- scl<=0;
-
- case(i2c_state)
- ini: begin
- case(inner_state)
- start: begin
- if(phase1) begin
- link<=1;
- sda_buf<=0;
- end
- if(phase3&&link) begin
- inner_state<=first;
- sda_buf<=1;
- link<=1;
- end
- end
- first:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=second;
- end
- second:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=third;
- end
- third:
- if(phase3) begin
- sda_buf<=1;
- link<=1;
- inner_state<=fourth;
- end
- fourth:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=fifth;
- end
- fifth:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=sixth;
- end
- sixth:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=seventh;
- end
- seventh:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=eighth;
- end
- eighth:
- if(phase3) begin
- link<=0;
- inner_state<=ack;
- end
- ack: begin
- if(phase0)
-
- sda_buf<=sda;
-
- if(phase1) begin
- if(sda_buf==1)
- //begin
- main_state<=2'b00;
- //main_state<=2'b11;
-
- end
- if(phase3) begin
- link<=1;
-
- sda_buf<=addr[7];
- inner_state<=first;
- i2c_state<=sendaddr;
- end
- end
- endcase
- end
- sendaddr: begin
- case(inner_state)
- first:
- if(phase3) begin
- link<=1;
- sda_buf<=addr[6];
- inner_state<=second;
- end
- second:
- if(phase3) begin
- link<=1;
- sda_buf<=addr[5];
- inner_state<=third;
- end
- third:
- if(phase3) begin
- link<=1;
- sda_buf<=addr[4];
- inner_state<=fourth;
- end
- fourth:
- if(phase3) begin
- link<=1;
- sda_buf<=addr[3];
- inner_state<=fifth;
- end
- fifth:
- if(phase3) begin
- link<=1;
- sda_buf<=addr[2];
- inner_state<=sixth;
- end
- sixth:
- if(phase3) begin
- link<=1;
- sda_buf<=addr[1];
- inner_state<=seventh;
- end
- seventh:
- if(phase3) begin
- link<=1;
- sda_buf<=addr[0];
- inner_state<=eighth;
- end
- eighth:
- if(phase3) begin
- link<=0;
- inner_state<=ack;
- end
- ack: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- if(sda_buf==1)
- main_state<=2'b00;
- //main_state<=2'b11;
- end
- if(phase3) begin
- link<=1;
- sda_buf<=1;
- inner_state<=start;
- i2c_state<=read_ini;
- end
- end
- endcase
- end
- read_ini: begin
- case(inner_state)
- start: begin
- if(phase1) begin
- link<=1;
- sda_buf<=0;
- end
- if(phase3&&link) begin
- inner_state<=first;
- sda_buf<=1;
- link<=1;
- end
- end
- first:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=second;
- end
- second:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=third;
- end
- third:
- if(phase3) begin
- sda_buf<=1;
- link<=1;
- inner_state<=fourth;
- end
- fourth:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=fifth;
- end
- fifth:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=sixth;
- end
- sixth:
- if(phase3) begin
- sda_buf<=0;
- link<=1;
- inner_state<=seventh;
- end
- seventh:
- if(phase3) begin
- sda_buf<=1;
- link<=1;
- inner_state<=eighth;
- end
- eighth:
- if(phase3) begin
- link<=0;
- inner_state<=ack;
- end
- ack: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- if(sda_buf==1)
- main_state<=2'b00;
- //main_state<=2'b11;
- end
- if(phase3) begin
- link<=0;
- inner_state<=first;
- i2c_state<=read_data;
- end
- end
- endcase
- end
- read_data: begin
- case(inner_state)
- first: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- readData_reg[7:1]<=readData_reg[6:0];
- readData_reg[0]<=sda;
- end
- if(phase3)
- inner_state<=second;
- end
- second: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- readData_reg[7:1]<=readData_reg[6:0];
- readData_reg[0]<=sda;
- end
- if(phase3)
- inner_state<=third;
- end
- third: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- readData_reg[7:1]<=readData_reg[6:0];
- readData_reg[0]<=sda;
- end
- if(phase3)
- inner_state<=fourth;
- end
- fourth: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- readData_reg[7:1]<=readData_reg[6:0];
- readData_reg[0]<=sda;
- end
- if(phase3)
- inner_state<=fifth;
- end
- fifth: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- readData_reg[7:1]<=readData_reg[6:0];
- readData_reg[0]<=sda;
- end
- if(phase3)
- inner_state<=sixth;
- end
- sixth: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- readData_reg[7:1]<=readData_reg[6:0];
- readData_reg[0]<=sda;
- end
- if(phase3)
- inner_state<=seventh;
- end
- seventh: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- readData_reg[7:1]<=readData_reg[6:0];
- readData_reg[0]<=sda;
- end
- if(phase3)
- inner_state<=eighth;
- end
- eighth: begin
- if(phase0)
- sda_buf<=sda;
- if(phase1) begin
- readData_reg[7:1]<=readData_reg[6:0];
- readData_reg[0]<=sda;
- end
- if(phase3)
- inner_state<=ack;
- end
- ack: begin
- if(phase3) begin
- link<=1;
- sda_buf<=0;
- inner_state<=stop;
- end
- end
- stop: begin
- /*if(phase1)
- sda_buf<=1;
-
- ledn1<=0;
- if(phase3) begin
- link<=0;
- inner_state<=first;
- i2c_state<=read_s1;
- ledn2<=0;
- end*/
- ledn3<=1;
- if(phase1)
- sda_buf<=1;
- if(phase3)
- i2c_state<=read_s1;
- end
-
-
- default:
- ;
- endcase
- end
- read_s1:
- i2c_state<=read_s2;
- read_s2:
- i2c_state<=read_s3;
- read_s3:
- i2c_state<=read_s4;
- read_s4:
- i2c_state<=read_s5;
- read_s5:
- i2c_state<=read_s6;
- read_s6:
- i2c_state<=read_s7;
- read_s7:
- i2c_state<=read_s8;
- read_s8:
- i2c_state<=read_s9;
- read_s9:
- i2c_state<=read_s10;
- read_s10:
- i2c_state<=read_s11;
- read_s11:
- i2c_state<=read_s12;
- read_s12:
-
-
- begin
- if(tics[19])
- begin
- adc_data<=readData_reg;
- main_state<=2'b00;
- i2c_state<=ini;
- inner_state<=start;
- ledn3<=0;
- end
- else
- i2c_state<=read_s12;
- end
- default:
-
-
- ;
-
- endcase
- end
-
- endcase
- end
- end
-
- assign led1=ledn1;
- assign led2=ledn2;
- assign led3=ledn3;
- assign led4=ledn4;
- endmodule
请高手指教,哪里有错?谢谢!我是参考例程AR24C04的程序改的。