搜索
bottom↓
回复: 2

求助关于读取adxl 345加速度模块值的FPGA的程序

[复制链接]

出0入0汤圆

发表于 2012-4-24 11:11:07 | 显示全部楼层 |阅读模式
求助关于读取adxl 345加速度模块值的FPGA的程序
最近在网上找了一个实例程序 但是感觉不正确。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入442汤圆

发表于 2012-4-24 11:20:19 | 显示全部楼层
你这程序是什么东西呀,看不懂。你需要一个I2C_Host来读取数据。我给你一个测试过的代码,目前挂在我的3个设备的I2C总线上,正常工作。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:    22:01:45 04/18/2012
// Design Name:
// Module Name:    I2CHost
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//                Formal I2C host module. Note that Start signal will only be send
//                if there's a data write operation after Start bit is set.
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module I2CHost(
    input int_in_GCLK,
    input int_in_GRST,
       
        // Bus definition
    input [7:0] int_in_Control,
        input int_in_Validate_Ctrl,
    output [7:0] int_out_Status,
    input [7:0] int_in_Data,
        input int_in_Validate_Data,
    output [7:0] int_out_Data,
        // If to input one byte, assert this wire to initiate a read cycle.
        input int_in_Read_Probe,
       
        // Port definition
        output port_out_SCL,
        inout port_io_SDA
    );
       
        // 100KHz -- 100MHz
        reg [11:0] rc_I2C_SCK_Counter_Threshold = 12'd999;
        // The following two signals are used to tell Clock generator whether to generate clock.
        reg r_I2C_Transmit_Enable = 1'b0;
        wire w_I2C_Transmit_Clock;
        wire w_I2C_Start_Stop_Clock;
       
        // SDA output control register.
        reg r_SDA_Assert_Zero = 1'b0;
        reg r_SCL_Assert_Zero = 1'b0;
       
        // Configure register. b7-Start b6-Stop b5-LastRD b1-ACK b0-Done.
        // External write should not affect except b7 to b5.
        // Because LastRD has no actual effect, we just skip it and set to zero every ACK period.
        reg [7:0] r_I2C_Control = 8'h00;
        wire w_Start = r_I2C_Control[7];
        wire w_Stop = r_I2C_Control[6];
        wire w_LastRD = r_I2C_Control[5];
        // Status routed directly to Control register.
        assign int_out_Status = r_I2C_Control;
       
        // Data will be latched only when controller is IDLE and int_in_Validate_Data is asserted HIGH.
        reg [7:0] r_I2C_Data_In;
        reg [7:0] r_I2C_Data_Out;
        // Output data is routed to r_I2C_To_Parallel_Data_Out, which will be affected after one transaction.
        reg [7:0] r_I2C_To_Parallel_Data_Out;
        assign int_out_Data = r_I2C_To_Parallel_Data_Out;
       
        reg [3:0] rs_I2C_Transceive;
        reg [3:0] rc_I2C_Transceive;
       
        wire [3:0] ws_I2C_Transceive_IDLE                                         = 0;
        wire [3:0] ws_I2C_Transceive_Start_Begin                        = 1;
        wire [3:0] ws_I2C_Transceive_Start_SCL_Transition        = 2;
        wire [3:0] ws_I2C_Transceive_Send_Begin                                = 3;
        wire [3:0] ws_I2C_Transceive_Send_Transition                = 4;
        wire [3:0] ws_I2C_Transceive_Read_Begin                                = 5;
        wire [3:0] ws_I2C_Transceive_Read_Latch                                = 6;
        wire [3:0] ws_I2C_Transceive_Read_ACK                                = 7;
        wire [3:0] ws_I2C_Transceive_ACK                                        = 8;
        wire [3:0] ws_I2C_Transceive_Stop_Begin                                = 9;
        wire [3:0] ws_I2C_Transceive_Stop_SCL_Transition        = 10;
        wire [3:0] ws_I2C_Transceive_SCL_Low_Last_Cycle                = 11;
       
        always @(posedge int_in_GCLK or negedge int_in_GRST)
                begin
                        if(~int_in_GRST)
                                begin
                                        r_I2C_Control <= 0;
                                        r_I2C_Data_In <= 0;
                                        r_I2C_Data_Out <= 0;
                                        rs_I2C_Transceive <= ws_I2C_Transceive_IDLE;
                                        rc_I2C_Transceive <= 0;
                                        r_I2C_Transmit_Enable <= 0;
                                        r_SDA_Assert_Zero <= 0;
                                        r_SCL_Assert_Zero <= 1;
                                        rc_I2C_SCK_Counter_Threshold <= 12'd999;
                                end
                        else
                                begin
                                        // Control register is updated whenever a write operation occurs.
                                        // We assume this command's only executed serially (not parallelly).
                                        if(int_in_Validate_Ctrl)
                                                r_I2C_Control[7:5] <= int_in_Control[7:5];
                                        else
                                                begin
                                        case (rs_I2C_Transceive)
                                                ws_I2C_Transceive_IDLE:
                                                        begin
                                                                // Idle state. Wait for any changes in Control Register.
                                                                // When Stop is asserted, then generate a stop condition.
                                                                // Else wait for Data Validate command.
                                                                if(w_Stop)
                                                                        begin
                                                                        // State 14 is used for Stop condition.
                                                                                r_I2C_Transmit_Enable <= 1;
                                                                                r_SDA_Assert_Zero <= 1;
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Stop_Begin;
                                                                                r_I2C_Control[0] <= 0;
                                                                                // Clear Stop bit.
                                                                                r_I2C_Control[6] <= 0;
                                                                        end
                                                                else if(int_in_Validate_Data)
                                                                        begin
                                                                                // Load data;
                                                                                r_I2C_Data_In <= int_in_Data;
                                                                                r_I2C_Control[0] <= 0;
                                                                                rc_I2C_Transceive <= 0;
                                                                                r_I2C_Transmit_Enable <= 1;
                                                                                if(w_Start)
                                                                                        begin
                                                                                                // State 1 is the state for initial transmission.
                                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Start_Begin;
                                                                                                // SDA is set to 1 ahead of other operation.
                                                                                                r_SDA_Assert_Zero <= 0;
                                                                                                // Clear Start bit.
                                                                                                r_I2C_Control[7] <= 0;
                                                                                        end
                                                                                else
                                                                                        begin
                                                                                                // Just goto State 3 to send data.
                                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Send_Begin;
                                                                                        end
                                                                        end
                                                                else if(int_in_Read_Probe)
                                                                        begin
                                                                                // Read data. First load internal register to output register.
                                                                                r_I2C_To_Parallel_Data_Out <= r_I2C_Data_Out;
                                                                                r_I2C_Control[0] <= 0;
                                                                                // Goto State 5 for read operation. ACK to device.
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Read_Begin;
                                                                                r_SDA_Assert_Zero <= 0;
                                                                                rc_I2C_Transceive <= 0;
                                                                                r_I2C_Transmit_Enable <= 1;
                                                                        end
                                                                else
                                                                        begin
                                                                                r_SDA_Assert_Zero <= 0;
                                                                                r_SCL_Assert_Zero <= 1;
                                                                                r_I2C_Transmit_Enable <= 0;
                                                                                r_I2C_Control[0] <= 1;
                                                                        end
                                                        end
                                                ws_I2C_Transceive_Start_Begin:
                                                        begin
                                                                // Start condition. Assume SDA is previously set to 1.
                                                                r_SCL_Assert_Zero <= 0;
                                                                // Wait for w_I2C_Transmit_Clock becomes high to change pole.
                                                                if(w_I2C_Start_Stop_Clock)
                                                                        begin
                                                                                r_SDA_Assert_Zero <= 1;
                                                                                // Goto state 15 so that after this send cycle return to IDLE.
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Start_SCL_Transition;
                                                                        end
                                                                else
                                                                        rs_I2C_Transceive <= rs_I2C_Transceive;
                                                        end
                                                ws_I2C_Transceive_Start_SCL_Transition:
                                                        begin
                                                                if(w_I2C_Transmit_Clock)
                                                                        begin
                                                                                r_SCL_Assert_Zero <= 1;
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Send_Begin;
                                                                        end
                                                                else
                                                                        rs_I2C_Transceive <= rs_I2C_Transceive;
                                                        end
                                                ws_I2C_Transceive_Send_Begin:
                                                        begin
                                                                // After start condition. Begin transmit data (MSB first).
                                                                // First set data, then goto State 3.
                                                                if(~w_I2C_Transmit_Clock)
                                                                        begin
                                                                                // Set data first if rc_I2C_Transceive is not 7.
                                                                                // If rc_I2C_Transceive is 7, then it means 8 bits are sent, and next to receive ACK.
                                                                                rc_I2C_Transceive <= rc_I2C_Transceive + 1;
                                                                                r_I2C_Data_In <= {r_I2C_Data_In[6:0],1'b0};
                                                                                if(rc_I2C_Transceive == 8)
                                                                                        begin
                                                                                                // Receive ACK bit.
                                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_ACK;
                                                                                                r_SDA_Assert_Zero <= 0;
                                                                                        end
                                                                                else
                                                                                        begin
                                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Send_Transition;
                                                                                                r_SDA_Assert_Zero <= (r_I2C_Data_In[7]?1'b0:1'b1);
                                                                                        end
                                                                        end
                                                                else
                                                                        rs_I2C_Transceive <= rs_I2C_Transceive;
                                                        end
                                                ws_I2C_Transceive_Send_Transition:
                                                        begin
                                                                // Write data wait w_I2C_Transmit_Clock High.
                                                                if(w_I2C_Transmit_Clock)
                                                                        begin
                                                                                r_SCL_Assert_Zero <= 1;
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Send_Begin;
                                                                        end
                                                                else
                                                                        begin
                                                                                r_SCL_Assert_Zero <= 0;
                                                                                rs_I2C_Transceive <= rs_I2C_Transceive;
                                                                        end
                                                        end
                                                ws_I2C_Transceive_Read_Begin:
                                                        begin
                                                                // Read data.
                                                                r_SDA_Assert_Zero <= 0;
                                                                if(~w_I2C_Transmit_Clock)
                                                                        begin
                                                                                // Begin receive data.
                                                                                rc_I2C_Transceive <= rc_I2C_Transceive + 1;
                                                                                if(rc_I2C_Transceive == 8)
                                                                                        begin
                                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Read_ACK;
                                                                                        end
                                                                                else
                                                                                        begin
                                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Read_Latch;
                                                                                        end
                                                                        end
                                                                else
                                                                        begin
                                                                                rs_I2C_Transceive <= rs_I2C_Transceive;
                                                                        end
                                                        end
                                                ws_I2C_Transceive_Read_Latch:
                                                        begin
                                                                if(w_I2C_Transmit_Clock)
                                                                        begin
                                                                                r_SCL_Assert_Zero <= 1;
                                                                                r_I2C_Data_Out <= {r_I2C_Data_Out[6:0],port_io_SDA};
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Read_Begin;
                                                                        end
                                                                else
                                                                        begin
                                                                                rs_I2C_Transceive <= rs_I2C_Transceive;
                                                                                r_SCL_Assert_Zero <= 0;
                                                                        end
                                                        end
                                                ws_I2C_Transceive_Read_ACK:
                                                        begin
                                                                if(w_LastRD)
                                                                        begin
                                                                                // High-Z SDA
                                                                                r_SDA_Assert_Zero <= 0;
                                                                        end
                                                                else
                                                                        begin
                                                                                r_SDA_Assert_Zero <= 1;
                                                                        end
                                                                // Wait for w_I2C_Transmit_Clock High.
                                                                if(w_I2C_Transmit_Clock)
                                                                        begin
                                                                                r_I2C_Control[1] <= port_io_SDA;
                                                                                // Goto state 15 so that after this send cycle return to IDLE.
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_SCL_Low_Last_Cycle;
                                                                                r_SCL_Assert_Zero <= 1;
                                                                                r_I2C_Control[5] <= 0;
                                                                        end
                                                                else
                                                                        begin
                                                                                r_SCL_Assert_Zero <= 0;
                                                                        end
                                                        end
                                                ws_I2C_Transceive_ACK:
                                                        begin
                                                                // ACK period. First set SCL high, then read at w_I2C_Transmit_Clock.
                                                                // Assert SCL high. Assume SDA is previously set to float.
                                                                r_SDA_Assert_Zero <= 0;
                                                                if(w_I2C_Transmit_Clock)
                                                                        begin
                                                                                r_I2C_Control[1] <= port_io_SDA;
                                                                                // Goto state 15 so that after this send cycle return to IDLE.
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_SCL_Low_Last_Cycle;
                                                                                r_SCL_Assert_Zero <= 1;
                                                                        end
                                                                else
                                                                        begin
                                                                                r_SCL_Assert_Zero <= 0;
                                                                        end
                                                        end
                                                ws_I2C_Transceive_Stop_Begin:
                                                        begin
                                                                // Stop condition.
                                                                // Assert SCL high. Assume SDA is previously set to zero.
                                                                r_SCL_Assert_Zero <= 0;
                                                                // Wait for w_I2C_Transmit_Clock becomes high to change pole.
                                                                if(w_I2C_Start_Stop_Clock)
                                                                        begin
                                                                                r_SDA_Assert_Zero <= 0;
                                                                                // Goto state 15 so that after this send cycle return to IDLE.
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_Stop_SCL_Transition;
                                                                        end
                                                                else
                                                                        begin
                                                                                rs_I2C_Transceive <= rs_I2C_Transceive;
                                                                        end
                                                        end
                                                ws_I2C_Transceive_Stop_SCL_Transition:
                                                        begin
                                                                if(w_I2C_Transmit_Clock)
                                                                        begin
                                                                                r_SCL_Assert_Zero <= 1;
                                                                                rs_I2C_Transceive <= ws_I2C_Transceive_SCL_Low_Last_Cycle;
                                                                        end
                                                                else
                                                                        begin
                                                                                rs_I2C_Transceive <= rs_I2C_Transceive;
                                                                        end
                                                        end
                                                ws_I2C_Transceive_SCL_Low_Last_Cycle:
                                                        begin
                                                                // Last active cycle. After w_I2C_Transmit_Clock low, goto IDLE.
                                                                if(~w_I2C_Transmit_Clock)
                                                                        rs_I2C_Transceive <= ws_I2C_Transceive_IDLE;
                                                                else
                                                                        rs_I2C_Transceive <= rs_I2C_Transceive;
                                                        end
                                                default:
                                                        begin
                                                                rs_I2C_Transceive <= ws_I2C_Transceive_IDLE;
                                                        end
                                        endcase
                                                end
                                end
                end       
       
       
        BaudGenerator clk_I2C_Transmit(
                .int_in_GCLK(int_in_GCLK),
                .port_in_RXD(1'b1),
                .int_out_RcvCLK(w_I2C_Transmit_Clock),
                .int_in_CountEnable(r_I2C_Transmit_Enable),                // Enable when 1
                .int_in_CountValue({4'h0,rc_I2C_SCK_Counter_Threshold[11:0]})
    );
       
        BaudGenerator clk_I2C_StartStopBitClk(
                .int_in_GCLK(int_in_GCLK),
                .port_in_RXD(1'b1),
                .int_out_RcvCLK(w_I2C_Start_Stop_Clock),
                .int_in_CountEnable(r_I2C_Transmit_Enable),                // Enable when 1
                .int_in_CountValue({5'h0,rc_I2C_SCK_Counter_Threshold[11:1]})
    );
       
        assign port_io_SDA = r_SDA_Assert_Zero?1'b0:1'bz;
        assign port_out_SCL = r_SCL_Assert_Zero?1'b0:1'bz;

endmodule


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:    08:07:48 04/08/2012
// Design Name:
// Module Name:    BaudGenerator
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module BaudGenerator(
    input int_in_GCLK,
    input port_in_RXD,
    output int_out_RcvCLK,
    input int_in_CountEnable,                // Enable when 1
    input [15:0] int_in_CountValue
    );

        reg [1:0] r_port_in_RXD_delay;
       
        always @(posedge int_in_GCLK)
                r_port_in_RXD_delay <= {r_port_in_RXD_delay[0],port_in_RXD};
       
        wire w_int_RXD_edge = ^r_port_in_RXD_delay;                // Edge detect.
        wire w_int_CountReset = ~w_int_RXD_edge & int_in_CountEnable;        // Reset counter on edge or count enable.
       
        reg [15:0] r_Counter;
        reg r_int_out_RcvCLK;
       
        assign int_out_RcvCLK = r_int_out_RcvCLK;
       
        always @(posedge int_in_GCLK or negedge w_int_CountReset)
                begin
                        if(~w_int_CountReset)
                                begin
                                        r_Counter <= 0;
                                        r_int_out_RcvCLK <= 0;
                                end
                        else
                                begin
                                        if(r_Counter == int_in_CountValue)
                                                begin
                                                        r_Counter <= 0;
                                                        r_int_out_RcvCLK <= 0;
                                                end
                                        else
                                                begin
                                                        r_Counter <= r_Counter + 1;
                                                        if(r_Counter == {1'b0,int_in_CountValue[15:1]})
                                                                begin
                                                                        r_int_out_RcvCLK <= 1;
                                                                end
                                                        else
                                                                begin
                                                                        r_int_out_RcvCLK <= r_int_out_RcvCLK;
                                                                end
                                                end
                                end
                end

endmodule

注意这个是I2CHost,操作方式同EZ-USB FX2的I2C总线寄存器操作,写寄存器bmSTART,bmSTOP,读bmACK,bmDONE,写I2DAT,读I2DAT。100KHz。注意你读超过8位数据时,需要每读一个字节后要回应设备nACK,要不然设备就认为传输结束,而停止继续输出数据。

出0入0汤圆

 楼主| 发表于 2012-4-27 08:48:39 | 显示全部楼层
wye11083 发表于 2012-4-24 11:20
你这程序是什么东西呀,看不懂。你需要一个I2C_Host来读取数据。我给你一个测试过的代码,目前挂在我的3个 ...

谢谢啦~~~
我对FPGA不熟...所以在 编写IIC时有点吃力
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 11:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表