CPLD驱动PCF8591ADC采样老是零
<p>我买了一个PCF8591模块,用单片机是正常的。</p><p> </p>
<p>我写了一个CPLD读PCF8591的ADC值的程序,可是读出来老是零。</p>
<p>代码如下:</p>
<pre>
<code>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;
inoutsda;
output led1,led2,led3,led4;
output adc_data;
output lcd_en ;
output lcd_rw ;
output lcd_rs ;
output lcd_data;
reg scl;
reg adc_data;
reg ledn1,ledn2,ledn3,ledn4;
reg cnt_scan;
reg sda_buf;
reg link;
reg phase0,phase1,phase2,phase3;
reg clk_div;
reg main_state;
reg i2c_state;
reg inner_state;
reg cnt_delay;
reg start_delaycnt;
reg readData_reg;
reg addr;
//--------------------------------------------
//按键检测
reg cnt_20ms; //20ms计数寄存器
always @ (posedge clk or negedge rst)
if(!rst) cnt_20ms <= 20'd0;
else cnt_20ms <= cnt_20ms+1'b1; //不断计数
parameter div_parameter=100;
parameterstart=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 lcd_data;
reg lcd_rs;
reg c_state ;
reg n_state ;
wirerow_1;
wirerow_2;
//reg dis_data=0;
assign row_1 =8'h30+adc_data/100;
assign row_1 =8'h30+adc_data%100/10;
assign row_1 =8'h30+adc_data%10;
assign row_1 =8'h20;
assign row_1 =8'h20;
assign row_1 =8'h20;
assign row_1 =8'h20;
assign row_1 =8'h20;
assign row_1 =8'h20;
assign row_1 =8'h20;
assign row_1 =8'h41;
assign row_1 =8'h42;
assign row_1 =8'h43;
assign row_1 =8'h44;
assign row_1 =8'h45;
assign row_1 =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 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 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 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 data0: 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
elsebegin
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
elseif(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 ;
ROW1_1: lcd_data <= row_1 ;
ROW1_2: lcd_data <= row_1 ;
ROW1_3: lcd_data <= row_1 ;
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 ;
ROW2_ADDR: lcd_data <= 8'hc0; //40+80
ROW2_0: lcd_data <= row_2 ;
ROW2_1: lcd_data <= row_2 ;
ROW2_2: lcd_data <= row_2 ;
ROW2_3: lcd_data <= row_2 ;
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 ;
endcase
end
else
lcd_data<=lcd_data ;
end
assign sda=(link)? sda_buf:1'bz;
reg 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;
inner_state<=first;
i2c_state<=sendaddr;
end
end
endcase
end
sendaddr: begin
case(inner_state)
first:
if(phase3) begin
link<=1;
sda_buf<=addr;
inner_state<=second;
end
second:
if(phase3) begin
link<=1;
sda_buf<=addr;
inner_state<=third;
end
third:
if(phase3) begin
link<=1;
sda_buf<=addr;
inner_state<=fourth;
end
fourth:
if(phase3) begin
link<=1;
sda_buf<=addr;
inner_state<=fifth;
end
fifth:
if(phase3) begin
link<=1;
sda_buf<=addr;
inner_state<=sixth;
end
sixth:
if(phase3) begin
link<=1;
sda_buf<=addr;
inner_state<=seventh;
end
seventh:
if(phase3) begin
link<=1;
sda_buf<=addr;
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<=readData_reg;
readData_reg<=sda;
end
if(phase3)
inner_state<=second;
end
second: begin
if(phase0)
sda_buf<=sda;
if(phase1) begin
readData_reg<=readData_reg;
readData_reg<=sda;
end
if(phase3)
inner_state<=third;
end
third: begin
if(phase0)
sda_buf<=sda;
if(phase1) begin
readData_reg<=readData_reg;
readData_reg<=sda;
end
if(phase3)
inner_state<=fourth;
end
fourth: begin
if(phase0)
sda_buf<=sda;
if(phase1) begin
readData_reg<=readData_reg;
readData_reg<=sda;
end
if(phase3)
inner_state<=fifth;
end
fifth: begin
if(phase0)
sda_buf<=sda;
if(phase1) begin
readData_reg<=readData_reg;
readData_reg<=sda;
end
if(phase3)
inner_state<=sixth;
end
sixth: begin
if(phase0)
sda_buf<=sda;
if(phase1) begin
readData_reg<=readData_reg;
readData_reg<=sda;
end
if(phase3)
inner_state<=seventh;
end
seventh: begin
if(phase0)
sda_buf<=sda;
if(phase1) begin
readData_reg<=readData_reg;
readData_reg<=sda;
end
if(phase3)
inner_state<=eighth;
end
eighth: begin
if(phase0)
sda_buf<=sda;
if(phase1) begin
readData_reg<=readData_reg;
readData_reg<=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)
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
</code></pre>
<p>请高手指教,哪里有错?谢谢!我是参考例程AR24C04的程序改的。</p>
<p>输入的模拟电压为零?还是AD转换电路不对,转换结果为零,</p>
<p>ADC的参考电压是否选择错误</p>
火辣西米秀 发表于 2023-4-30 09:03
输入的模拟电压为零?还是AD转换电路不对,转换结果为零,
ADC的参考电压是否选择错误
<p>谢谢!输入的模拟电压不为零。AD模块是好的,用51没问题。</p>
<p>电路图:</p>
<p><br />
<br />
<br />
我VCC用的是3.3V.<br />
</p>
<p> </p>
页:
[1]