小白的MPU6050
时间:10-02
整理:3721RD
点击:
首先要感谢万能的电子发烧友论坛的管理者啊,排除万难为我争取了宝贵的一个月。
之前由于各种事情,导致这次的FPGA使用和之前的NanoPi M1的试用都没有按期完成。由于已经在弄其他的嵌入式板子了,所以,所幸就放弃NanoPi的使用,来使用更让我惊喜的锆石FPGA开发板。
这次我是使用FPGA来采集多路的角度传感器信号,并通过并行通信的方式发送给ARM开发板来达到快速捕捉动作的目的。完成所有的工作首先就要完成单个MPU6050模块的调试。这次我就将单个的MPU6050数据读取的源程序分享出来,希望可以平息管理员的怒火。
先上个图啊。(好尴尬,只上传成功一张、、、)——一定要看最后的哦!
- module zhu(
- clk,
- scl,
- sda,
- rst_n,
- data,
- seg,
- dig
- );
- output [7:0]seg;
- output [3:0]dig;
- input clk,rst_n;
- output scl;
- output[7:0]data;
- inout sda;
- reg[2:0] cstate;
-
- reg [2:0]cnt;//cnt=0,scl上升沿;cnt=1,scl高电平中间;cnt=2,scl下降沿;cnt=3,scl低电平中间
- reg [8:0]cnt_sum;//产生IIC所需要的时钟
- reg scl_r;//产生的时钟脉冲
-
- reg [15:0]cnt_10ms;
- reg div_clk;
- reg[3:0] Show_data; //显示的数据
- reg[3:0] Show_dig; //要显示的数码管
- reg[6:0] Show_seg; //数码管的七个段
-
- reg[9:0] cnt1;
-
- always@(posedge clk or posedge rst_n)
- if(rst_n)
- cnt_10ms = 5'd6)
- state <= START2;
- else
- state <= ADD_EXT;
- end
- else
- state <= ACK2;//等待响应
- end
- ADD_EXT:begin//初始化一些设定寄存器
- if(`SCL_LOW)
- begin
- if(num == 4'd8)
- begin
- num <= 4'd0;
- sda_r <= 1'b1;
- sda_link <= 1'b0;//sda高阻态
- state <= ACK_EXT;
- end
- else
- begin
- sda_link <= 1'b1;
- state <= ADD_EXT;
- num <= num+1'b1;
- sda_r <= db_r[4'd7-num];//按位设定寄存器工作方式
- end
- end
- else
- state <= ADD_EXT;
- end
- ACK_EXT:begin
- if(`SCL_NEG)
- begin
- sda_r <= 1'b1;//拉高sda
- state <= STOP1;
- end
- else
- state <= ACK_EXT;//等待响应
- end
- START2:begin
- if(`SCL_LOW)//scl为低
- begin
- sda_link <= 1'b1;//sda为输出
- sda_r <= 1'b1;//拉高sda
- state <= START2;
- end
- else if(`SCL_HIG)//scl为高
- begin
- sda_r <= 1'b0;//拉低sda,产生start信号
- state <= ADD3;
- end
- else
- state <= START2;
- end
- ADD3: begin
- if(`SCL_LOW)//scl位低
- begin
- if(num == 4'd8)
- begin
- num <= 4'd0;
- sda_r <= 1'b1;//拉高sda
- sda_link <= 1'b0;//scl高阻态
- state <= ACK3;
- end
- else
- begin
- num <= num+1'b1;
- sda_r <= db_r[4'd7-num];//按位写入读取寄存器地址
- state <= ADD3;
- end
- end
- else state <= ADD3;
- end
- ACK3: begin
- if(`SCL_NEG)
- begin
- state <= DATA;
- sda_link <= 1'b0;//sda高阻态
- end
- else
- state <= ACK3;//等待响应
- end
- DATA: begin
- if(num <= 4'd7)
- begin
- state <= DATA;
- if(`SCL_HIG)
- begin
- num <= num+1'b1;
- case(times)
- 5'd6: ACC_XH_READ[4'd7-num] <= sda;
- 5'd7: ACC_XL_READ[4'd7-num] <= sda;
- 5'd8: ACC_YH_READ[4'd7-num] <= sda;
- 5'd9: ACC_YL_READ[4'd7-num] <= sda;
- 5'd10: ACC_ZH_READ[4'd7-num] <= sda;
- 5'd11: ACC_ZL_READ[4'd7-num] <= sda;
- 5'd12: GYRO_XH_READ[4'd7-num] <= sda;
- 5'd13: GYRO_XL_READ[4'd7-num] <= sda;
- 5'd14: GYRO_YH_READ[4'd7-num] <= sda;
- 5'd15: GYRO_YL_READ[4'd7-num] <= sda;
- 5'd16: GYRO_ZH_READ[4'd7-num] <= sda;
- 5'd17: GYRO_ZL_READ[4'd7-num] <= sda;
- default: ;//暂时未考虑,可添加代码提高系统稳定性
- endcase
- end
- end
- else if((`SCL_LOW)&&(num == 4'd8))
- begin
- sda_link <= 1'b1;//sda为输出
- num <= 4'd0;//计数清零
- state <= ACK4;
- end
- else
- state <= DATA;
- end
- ACK4: begin
- if(times == 5'd17)
- times <= 5'd0;
- if(`SCL_NEG)
- begin
- sda_r <= 1'b1;//拉高sda
- state <= STOP1;
- end
- else
- state <= ACK4;//等待响应
- end
- STOP1:begin
- if(`SCL_LOW)//scl为低
- begin
- sda_link <= 1'b1;//sda输出
- sda_r <= 1'b0;//拉低sda
- state <= STOP1;
- end
- else if(`SCL_HIG)//sda为高
- begin
- sda_r <= 1'b1;//拉高sda,产生stop信号
- state <= STOP2;
- end
- else
- state <= STOP1;
- end
- STOP2:begin
- if(`SCL_LOW)
- sda_r <= 1'b1;
- else if(cnt_10ms == 16'hffff)//约10ms得一个数据
- state <= IDLE;
- else
- state <= STOP2;
- end
- default:state <= IDLE;
- endcase
- end
-
- assign sda = sda_link?sda_r:1'bz;
- assign data[0]=ACC_XH_READ[4'd0];
- assign data[1]=ACC_XH_READ[4'd1];
- assign data[2]=ACC_XH_READ[4'd2];
- assign data[3]=ACC_XH_READ[4'd3];
- assign data[4]=ACC_XH_READ[4'd4];
- assign data[5]=ACC_XH_READ[4'd5];
- assign data[6]=ACC_XH_READ[4'd6];
- assign data[7]=ACC_XH_READ[4'd7];
-
- always @(posedge clk or posedge rst_n)
- begin
- if(rst_n) cnt1 <= 10'd0;
- else if(cnt1 == 10'd999) cnt1 <= 10'd0;
- else cnt1 <= cnt1 + 1'b1;
- end
- always @(posedge clk or posedge rst_n)
- begin
- if(rst_n) div_clk <= 1'b0;
- else if(cnt1 <= 10'd499) div_clk <= 1'b0;
- else div_clk <= 1'b1;
- end
-
- always @(posedge div_clk or posedge rst_n)
- begin
- if(rst_n)
- begin
- cstate <= Show_H;
- Show_dig <= 4'b0011;
- Show_data <= 4'b0000;
- end
- else
- begin
- case(cstate)//通过状态机循环显示两位十六进制数
- Show_H:
- begin
- Show_data <= {ACC_XH_READ[4'd0],ACC_XH_READ[4'd1],ACC_XH_READ[4'd2],ACC_XH_READ[4'd3]};
- Show_dig <= 4'b1011;
- cstate <= Show_L;
- end
- Show_L:
- begin
- Show_data <= {ACC_XH_READ[4'd4],ACC_XH_READ[4'd5],ACC_XH_READ[4'd6],ACC_XH_READ[4'd7]};
- Show_dig <= 4'b0111;
- cstate <= Show_M1;
- end
- Show_M1:
- begin
- Show_data <= {ACC_XL_READ[4'd0],ACC_XL_READ[4'd1],ACC_XL_READ[4'd2],ACC_XL_READ[4'd3]};
- Show_dig <= 4'b1110;
- cstate <= Show_M2;
- end
- Show_M2:
- begin
- Show_data <= {ACC_XL_READ[4'd4],ACC_XL_READ[4'd5],ACC_XL_READ[4'd6],ACC_XL_READ[4'd7]};
- Show_dig <= 4'b1101;
- cstate <= Show_H;
- end
- endcase
- end
- end
-
- always @(posedge clk or posedge rst_n)
- begin
- if(rst_n)
- begin
- Show_seg <= 7'b0111111;
- end
- else
- case(Show_data)
- 4'b0000 : Show_seg <= 7'b0111111; //0
- 4'b0001 : Show_seg <= 7'b0000110; //1
- 4'b0010 : Show_seg <= 7'b1011011; //2
- 4'b0011 : Show_seg <= 7'b1001111; //3
- 4'b0100 : Show_seg <= 7'b1100110; //4
- 4'b0101 : Show_seg <= 7'b1101101; //5
- 4'b0110 : Show_seg <= 7'b1111101; //6
- 4'b0111 : Show_seg <= 7'b0100111; //7
- 4'b1000 : Show_seg <= 7'b1111111; //8
- 4'b1001 : Show_seg <= 7'b1101111; //9
- 4'b1010 : Show_seg <= 7'b1110111; //A
- 4'b1011 : Show_seg <= 7'b1111100; //B
- 4'b1100 : Show_seg <= 7'b0111001; //C
- 4'b1101 : Show_seg <= 7'b1011110; //D
- 4'b1110 : Show_seg <= 7'b1111001; //E
- 4'b1111 : Show_seg <= 7'b1110001; //F
- default : Show_seg <= 7'b0000000;
- endcase
- end
- assign seg = {1'b1,(Show_seg[6:0])};//加上第八位-小数点位(小数点不显//示)
- assign dig = Show_dig;
-
- endmodule
其他的调试进度会陆续发上来的,大家关注哦!