微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 小白的MPU6050

小白的MPU6050

时间:10-02 整理:3721RD 点击:

首先要感谢万能的电子发烧友论坛的管理者啊,排除万难为我争取了宝贵的一个月。
之前由于各种事情,导致这次的FPGA使用和之前的NanoPi M1的试用都没有按期完成。由于已经在弄其他的嵌入式板子了,所以,所幸就放弃NanoPi的使用,来使用更让我惊喜的锆石FPGA开发板。
这次我是使用FPGA来采集多路的角度传感器信号,并通过并行通信的方式发送给ARM开发板来达到快速捕捉动作的目的。完成所有的工作首先就要完成单个MPU6050模块的调试。这次我就将单个的MPU6050数据读取的源程序分享出来,希望可以平息管理员的怒火。

先上个图啊。(好尴尬,只上传成功一张、、、)——一定要看最后的哦!


  1. module zhu(  
  2.     clk,  
  3.     scl,  
  4.     sda,  
  5.     rst_n,
  6.          data,
  7.          seg,
  8.          dig
  9.     );
  10. output [7:0]seg;
  11. output [3:0]dig;         
  12. input clk,rst_n;  
  13. output scl;  
  14. output[7:0]data;
  15. inout sda;
  16. reg[2:0] cstate;  
  17.   
  18. reg [2:0]cnt;//cnt=0,scl上升沿;cnt=1,scl高电平中间;cnt=2,scl下降沿;cnt=3,scl低电平中间  
  19. reg [8:0]cnt_sum;//产生IIC所需要的时钟  
  20. reg scl_r;//产生的时钟脉冲  
  21.   
  22. reg [15:0]cnt_10ms;
  23. reg div_clk;

  24. reg[3:0] Show_data; //显示的数据
  25. reg[3:0] Show_dig;  //要显示的数码管
  26. reg[6:0]        Show_seg;  //数码管的七个段  

  27. reg[9:0] cnt1;

  28. always@(posedge clk or posedge rst_n)  
  29. if(rst_n)   
  30.     cnt_10ms = 5'd6)  
  31.                             state <= START2;  
  32.                         else  
  33.                             state <= ADD_EXT;  
  34.                     end  
  35.                     else  
  36.                         state <= ACK2;//等待响应  
  37.                 end  
  38.         ADD_EXT:begin//初始化一些设定寄存器  
  39.                     if(`SCL_LOW)  
  40.                     begin  
  41.                         if(num == 4'd8)  
  42.                         begin  
  43.                             num <= 4'd0;  
  44.                             sda_r <= 1'b1;  
  45.                             sda_link <= 1'b0;//sda高阻态  
  46.                             state <= ACK_EXT;  
  47.                         end  
  48.                         else  
  49.                         begin  
  50.                             sda_link <= 1'b1;  
  51.                             state <= ADD_EXT;  
  52.                             num <= num+1'b1;  
  53.                             sda_r <= db_r[4'd7-num];//按位设定寄存器工作方式  
  54.                         end  
  55.                     end  
  56.                     else  
  57.                         state <= ADD_EXT;  
  58.                 end  
  59.         ACK_EXT:begin  
  60.                     if(`SCL_NEG)  
  61.                     begin  
  62.                         sda_r <= 1'b1;//拉高sda  
  63.                         state <= STOP1;  
  64.                     end  
  65.                     else  
  66.                         state <= ACK_EXT;//等待响应  
  67.                 end  
  68.         START2:begin  
  69.                     if(`SCL_LOW)//scl为低  
  70.                     begin  
  71.                         sda_link <= 1'b1;//sda为输出  
  72.                         sda_r <= 1'b1;//拉高sda  
  73.                         state <= START2;  
  74.                     end  
  75.                     else if(`SCL_HIG)//scl为高  
  76.                     begin  
  77.                         sda_r <= 1'b0;//拉低sda,产生start信号  
  78.                         state <= ADD3;  
  79.                     end  
  80.                     else   
  81.                         state <= START2;  
  82.                 end  
  83.         ADD3: begin  
  84.                     if(`SCL_LOW)//scl位低  
  85.                     begin  
  86.                         if(num == 4'd8)  
  87.                         begin  
  88.                             num <= 4'd0;  
  89.                             sda_r <= 1'b1;//拉高sda  
  90.                             sda_link <= 1'b0;//scl高阻态  
  91.                             state <= ACK3;  
  92.                         end  
  93.                         else  
  94.                         begin  
  95.                             num <= num+1'b1;  
  96.                             sda_r <= db_r[4'd7-num];//按位写入读取寄存器地址  
  97.                             state <= ADD3;  
  98.                         end  
  99.                     end  
  100.                     else state <= ADD3;  
  101.                 end  
  102.         ACK3: begin  
  103.                     if(`SCL_NEG)  
  104.                     begin  
  105.                         state <= DATA;  
  106.                         sda_link <= 1'b0;//sda高阻态  
  107.                     end  
  108.                     else  
  109.                         state <= ACK3;//等待响应  
  110.                 end  
  111.         DATA: begin  
  112.                     if(num <= 4'd7)  
  113.                     begin  
  114.                         state <= DATA;  
  115.                         if(`SCL_HIG)  
  116.                         begin  
  117.                             num <= num+1'b1;  
  118.                             case(times)  
  119.                                 5'd6: ACC_XH_READ[4'd7-num] <= sda;  
  120.                                 5'd7: ACC_XL_READ[4'd7-num] <= sda;  
  121.                                 5'd8: ACC_YH_READ[4'd7-num] <= sda;  
  122.                                 5'd9: ACC_YL_READ[4'd7-num] <= sda;  
  123.                                 5'd10: ACC_ZH_READ[4'd7-num] <= sda;  
  124.                                 5'd11: ACC_ZL_READ[4'd7-num] <= sda;  
  125.                                 5'd12: GYRO_XH_READ[4'd7-num] <= sda;  
  126.                                 5'd13: GYRO_XL_READ[4'd7-num] <= sda;  
  127.                                 5'd14: GYRO_YH_READ[4'd7-num] <= sda;  
  128.                                 5'd15: GYRO_YL_READ[4'd7-num] <= sda;  
  129.                                 5'd16: GYRO_ZH_READ[4'd7-num] <= sda;  
  130.                                 5'd17: GYRO_ZL_READ[4'd7-num] <= sda;  
  131.                                 default: ;//暂时未考虑,可添加代码提高系统稳定性  
  132.                             endcase  
  133.                         end  
  134.                     end  
  135.                     else if((`SCL_LOW)&&(num == 4'd8))  
  136.                     begin  
  137.                         sda_link <= 1'b1;//sda为输出  
  138.                         num <= 4'd0;//计数清零  
  139.                         state <= ACK4;  
  140.                     end  
  141.                     else  
  142.                         state <= DATA;  
  143.                 end  
  144.         ACK4: begin  
  145.                     if(times == 5'd17)  
  146.                         times <= 5'd0;  
  147.                     if(`SCL_NEG)  
  148.                     begin  
  149.                         sda_r <= 1'b1;//拉高sda  
  150.                         state <= STOP1;  
  151.                     end  
  152.                     else  
  153.                         state <= ACK4;//等待响应  
  154.                 end  
  155.         STOP1:begin  
  156.                     if(`SCL_LOW)//scl为低  
  157.                     begin  
  158.                         sda_link <= 1'b1;//sda输出  
  159.                         sda_r <= 1'b0;//拉低sda  
  160.                         state <= STOP1;  
  161.                     end  
  162.                     else if(`SCL_HIG)//sda为高  
  163.                     begin  
  164.                         sda_r <= 1'b1;//拉高sda,产生stop信号  
  165.                         state <= STOP2;  
  166.                     end  
  167.                     else  
  168.                         state <= STOP1;  
  169.                 end  
  170.         STOP2:begin  
  171.                     if(`SCL_LOW)  
  172.                     sda_r <= 1'b1;  
  173.                     else if(cnt_10ms == 16'hffff)//约10ms得一个数据  
  174.                         state <= IDLE;  
  175.                     else  
  176.                         state <= STOP2;  
  177.                 end  
  178.         default:state <= IDLE;  
  179.         endcase  
  180. end  
  181.   
  182. assign sda = sda_link?sda_r:1'bz;
  183. assign data[0]=ACC_XH_READ[4'd0];
  184. assign data[1]=ACC_XH_READ[4'd1];
  185. assign data[2]=ACC_XH_READ[4'd2];
  186. assign data[3]=ACC_XH_READ[4'd3];
  187. assign data[4]=ACC_XH_READ[4'd4];
  188. assign data[5]=ACC_XH_READ[4'd5];
  189. assign data[6]=ACC_XH_READ[4'd6];
  190. assign data[7]=ACC_XH_READ[4'd7];

  191. always @(posedge clk or posedge rst_n)
  192. begin
  193.         if(rst_n) cnt1 <= 10'd0;
  194.         else if(cnt1 == 10'd999) cnt1 <= 10'd0;
  195.         else cnt1 <= cnt1 + 1'b1;
  196. end
  197. always @(posedge clk or posedge rst_n)
  198. begin
  199.         if(rst_n) div_clk <= 1'b0;
  200.         else if(cnt1 <= 10'd499) div_clk <= 1'b0;
  201.         else        div_clk <= 1'b1;
  202. end


  203. always @(posedge div_clk or posedge rst_n)
  204. begin
  205.         if(rst_n)
  206.         begin
  207.         cstate <= Show_H;
  208.         Show_dig <= 4'b0011;
  209.         Show_data <= 4'b0000;
  210.         end
  211.         else
  212.         begin
  213.                 case(cstate)//通过状态机循环显示两位十六进制数
  214.                         Show_H:
  215.                         begin  
  216.                                 Show_data <= {ACC_XH_READ[4'd0],ACC_XH_READ[4'd1],ACC_XH_READ[4'd2],ACC_XH_READ[4'd3]};
  217.                                 Show_dig <= 4'b1011;
  218.                                 cstate <= Show_L;
  219.                         end
  220.                         Show_L:
  221.                         begin
  222.                                 Show_data <= {ACC_XH_READ[4'd4],ACC_XH_READ[4'd5],ACC_XH_READ[4'd6],ACC_XH_READ[4'd7]};
  223.                                 Show_dig <= 4'b0111;
  224.                                 cstate <= Show_M1;
  225.                         end
  226.                         Show_M1:
  227.                         begin
  228.                                 Show_data <= {ACC_XL_READ[4'd0],ACC_XL_READ[4'd1],ACC_XL_READ[4'd2],ACC_XL_READ[4'd3]};
  229.                                 Show_dig <= 4'b1110;
  230.                                 cstate <= Show_M2;
  231.                         end
  232.                         Show_M2:
  233.                         begin
  234.                                 Show_data <= {ACC_XL_READ[4'd4],ACC_XL_READ[4'd5],ACC_XL_READ[4'd6],ACC_XL_READ[4'd7]};
  235.                                 Show_dig <= 4'b1101;
  236.                                 cstate <= Show_H;
  237.                         end
  238.                 endcase
  239.         end               
  240. end




  241. always @(posedge clk or posedge rst_n)
  242. begin
  243.         if(rst_n)
  244.         begin
  245.                 Show_seg <= 7'b0111111;
  246.         end
  247.         else
  248.                 case(Show_data)
  249.                         4'b0000 : Show_seg <= 7'b0111111; //0
  250.                         4'b0001 : Show_seg <= 7'b0000110; //1
  251.                         4'b0010 : Show_seg <= 7'b1011011; //2
  252.                         4'b0011 : Show_seg <= 7'b1001111; //3
  253.                         4'b0100 : Show_seg <= 7'b1100110; //4
  254.                         4'b0101 : Show_seg <= 7'b1101101; //5
  255.                         4'b0110 : Show_seg <= 7'b1111101; //6
  256.                         4'b0111 : Show_seg <= 7'b0100111; //7
  257.                         4'b1000 : Show_seg <= 7'b1111111; //8
  258.                         4'b1001 : Show_seg <= 7'b1101111; //9
  259.                         4'b1010 : Show_seg <= 7'b1110111; //A
  260.                         4'b1011 : Show_seg <= 7'b1111100; //B
  261.                         4'b1100 : Show_seg <= 7'b0111001; //C
  262.                         4'b1101 : Show_seg <= 7'b1011110; //D
  263.                         4'b1110 : Show_seg <= 7'b1111001; //E
  264.                         4'b1111 : Show_seg <= 7'b1110001; //F
  265.                         default : Show_seg <= 7'b0000000;
  266.                 endcase
  267. end

  268. assign seg = {1'b1,(Show_seg[6:0])};//加上第八位-小数点位(小数点不显//示)
  269. assign dig = Show_dig;
  270.   
  271. endmodule  

复制代码

当然这是一份不太完整的,只读取了角速度的信息,其他的更具这份程序上的其他部分修改就好了。其中的精髓便是IIC通信程序的编写,希望大家可以研究一下。当然,将这份代码中的IIC通信程序直接复制粘贴到其他的FPGA开发板中也是直接可以用的哦(这是我之前调试的PCF8591模块ps.同时采集15路信号.的IIC通信程序,只要更具模块协议进行修改就好,一般不会出现时序问题的)。
其他的调试进度会陆续发上来的,大家关注哦!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top