1nnocet-

  • 2025-01-06
  • 回复了主题帖: 温度传感器只有第一次采集的是准的是怎么回事?

    tagetage 发表于 2024-12-28 22:28 那你到底解决问题没有了啊????? 不是你说的这个问题,是地址搞错了

  • 回复了主题帖: 温度传感器只有第一次采集的是准的是怎么回事?

    1nnocent 发表于 2025-1-6 16:29 我看你配置的vio里面期间的地址addr怎么配置的0x00啊?数据手册里的给地址不可能有0x00的情况,检查下 ... 改了下地址,还真是地址的原因,把温度寄存器的pointer当成地址配置了

  • 2024-12-28
  • 回复了主题帖: 温度传感器只有第一次采集的是准的是怎么回事?

    tagetage 发表于 2024-12-28 20:14 temperature conversion time One-shot mode    -----有2个地方需要注意,一个是温度的转换时间 ... 数据手册好像没写上电默认是单一模式还是连续模式,我直接当成上电默认连续模式了

  • 发表了主题帖: 温度传感器只有第一次采集的是准的是怎么回事?

        使用verilog写了一个P3T1750DP温度传感器的驱动代码,但是测量出来的温度只有上电后第一次采集的是准的,后面采集回来的都是不准了。工程代码如下: top.v module top( input pl_ref_clk_100m_p , input pl_ref_clk_100m_n , output ex_i2c_scl , inout ex_i2c_sda ); wire p3t1750dp_en; wire clk_100m; wire rst_n; wire p3t1750dp_done; wire [15:0] temp_out; wire [7:0] p3t1750dp_addr,p3t1750dp_pointer; vio_0 vio_0 ( .clk(clk_100m), // input wire clk .probe_out0(p3t1750dp_en), // output wire [0 : 0] probe_out0 .probe_out1(p3t1750dp_addr), // output wire [7 : 0] probe_out1 .probe_out2(p3t1750dp_pointer), // output wire [7 : 0] probe_out2 .probe_out3(rst_n) // output wire [0 : 0] probe_out2 ); p3t1750dp p3t1750dp( .clk_100m (clk_100m ), .rst_n (rst_n ), .p3t1750dp_en (p3t1750dp_en ), .p3t1750dp_addr (p3t1750dp_addr ), .p3t1750dp_pointer(p3t1750dp_pointer), .scl (ex_i2c_scl ), .sda (ex_i2c_sda ), .p3t1750dp_done (p3t1750dp_done ), .temp_out (temp_out ) ); IBUFDS clk_100m_ibufds( .O (clk_100m ), .I (pl_ref_clk_100m_p ), .IB (pl_ref_clk_100m_n ) ); endmodule p3t1750dp.v模块参照官方的时序Figure 19. Read register including pointer byte (2-byte data)写的。   module p3t1750dp( input clk_100m , input rst_n , input p3t1750dp_en , input [7:0] p3t1750dp_addr , input [7:0] p3t1750dp_pointer, (* MARK_DEBUG="true" *)output scl , inout sda , (* MARK_DEBUG="true" *)output p3t1750dp_done , (* MARK_DEBUG="true" *)output reg [15:0] temp_out ); localparam SCL_NUM = 64; (* MARK_DEBUG="true" *)reg [$clog2(SCL_NUM) -1:0] cnt_scl ; // 100MHz/64=1.5625MHz reg p3t1750dp_en_d ; (* MARK_DEBUG="true" *)wire scl_high ; (* MARK_DEBUG="true" *)wire neg_scl ; (* MARK_DEBUG="true" *)wire scl_low ; (* MARK_DEBUG="true" *)wire scl_done ; assign scl_high = (cnt_scl == ((SCL_NUM >>2) -1)); assign neg_scl = (cnt_scl == ((SCL_NUM >>1) -1)); assign scl_low = (cnt_scl == (SCL_NUM -(SCL_NUM >>2) -1)); assign scl = (!cnt_scl[$clog2(SCL_NUM) -1]); assign scl_done = (&cnt_scl); always @(posedge clk_100m or negedge rst_n) begin if(!rst_n)begin p3t1750dp_en_d <= 1'b0; cnt_scl <= 'd0; end else begin p3t1750dp_en_d <= p3t1750dp_en; cnt_scl <= p3t1750dp_en_d ? (cnt_scl + 'd1) : 'd0; end end (* MARK_DEBUG="true" *)reg [5:0] bit_cnt ; (* MARK_DEBUG="true" *)reg [15:0] read_data ; reg sda_o ; reg sda_en_d,master_ack_d,slave_ack_d ; wire sda_i ; wire sda_en ; wire start ; //1 20 wire addr_w ; //2-9 wire pointer ; //11-18 wire slave_ack ; //10 19 29 wire addr_r ; //21-28 wire read_byte1 ; //30-37 wire master_ack ; //38 47 wire read_byte2 ; //39-46 wire stop ; //48 wire idle ; //49 wire [7:0] address_w,address_r; assign sda_i = sda; assign sda_en = (start | addr_w | pointer | addr_r | master_ack | stop | idle); assign sda = sda_en_d ? sda_o : 1'bz; assign address_w= {p3t1750dp_addr[6:0],1'b0}; // write assign address_r= {p3t1750dp_addr[6:0],1'b1}; // read assign p3t1750dp_pointer = 8'h00; assign p3t1750dp_done = (stop & scl_high); assign start = ((bit_cnt == 'd0)|(bit_cnt == 'd19)); //1 20 assign addr_w = ((bit_cnt >= 'd1)&(bit_cnt <= 'd8)); //2-9 assign pointer = ((bit_cnt >= 'd10)&(bit_cnt <= 'd17)); //11-18 assign slave_ack = ((bit_cnt == 'd9)|(bit_cnt == 'd18)|(bit_cnt == 'd28)); //10 19 29 assign addr_r = ((bit_cnt >= 'd20)&(bit_cnt <= 'd27)); //21-28 assign read_byte1 = ((bit_cnt >= 'd29)&(bit_cnt <= 'd36)); //30-37 assign master_ack = ((bit_cnt == 'd37)|(bit_cnt == 'd46)); //38 47 assign read_byte2 = ((bit_cnt >= 'd38)&(bit_cnt <= 'd45)); //39-46 assign stop = (bit_cnt == 'd47); //48 assign idle = (bit_cnt == 'd48); //49 always @(posedge clk_100m or negedge rst_n) begin if(!rst_n) bit_cnt <= 'd0; else if(neg_scl) if(idle) bit_cnt <= 'd0; else bit_cnt <= (bit_cnt + 'd1); else bit_cnt <= bit_cnt; end always @(posedge clk_100m or negedge rst_n) begin if(!rst_n)begin master_ack_d <= 1'b0; slave_ack_d <= 1'b0; sda_en_d <= 1'b0; temp_out <= 'd0; end else begin master_ack_d <= master_ack; slave_ack_d <= slave_ack; sda_en_d <= sda_en; temp_out <= p3t1750dp_done ? read_data : temp_out; end end always@(posedge clk_100m or negedge rst_n)begin if(!rst_n) sda_o <= 1'd1; else if(start)// 1 20 sda_o <= scl_high ? 1'b0 : sda_o; else if(addr_w)// 2-9 sda_o <= scl_low ? address_w[8 - bit_cnt] : sda_o; else if(slave_ack) sda_o <= 1'b1; else if(pointer)// 11-18 sda_o <= scl_low ? p3t1750dp_pointer[17 - bit_cnt] : sda_o; else if(addr_r)// 21-28 sda_o <= scl_low ? address_r[27 - bit_cnt] : sda_o; else if(master_ack) if(scl_low)// 38 47 sda_o <= (bit_cnt == 'd37) ? 1'b0 : 1'b1; else sda_o <= ((bit_cnt == 'd46)& neg_scl) ? 1'b0 : sda_o; else if(stop)// 48 sda_o <= scl_high ? 1'b1 : sda_o; else if(idle)// 49 sda_o <= 1'b1; else sda_o <= sda_o; end always@(posedge clk_100m or negedge rst_n)begin if(!rst_n) read_data <= 'd0; else read_data <= ((read_byte1 | read_byte2)& scl_high) ? {read_data[14:0],sda_i} : read_data; end endmodule       测试时ila设置抓取p3t1750dp_done 的上升沿。       vio依次配置p3t1750dp_addr(硬件上设置器件地址为0x00),p3t1750dp_pointer(指向温度传感器寄存测量结果的寄存器),拉高rst_n信号,最后打开p3t1750dp_en(iic开始和器件通讯)。       第一次触发抓到的结果,温度数据为高12bit,7520右移4位后为470,器件测量精度为0.0625,所以第一次测量结果为:470*0.0625=29.375℃。       第二次触发的测量结果:结果直接变负数了  

最近访客

< 1/2 >

统计信息

已有23人来访过

  • 芯积分:124
  • 好友:--
  • 主题:8
  • 回复:16

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言