OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9874|回复: 4

[ALTERA] FPGA电机测速问题,求助!!

[复制链接]

3

主题

4

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2020-12-3
在线时间
14 小时
发表于 2021-5-18 18:35:29 | 显示全部楼层 |阅读模式
5金钱
我要用FPGA实现电机驱动并且测速,测速选择的是光耦模块,有遮挡的时候为高电平,无遮挡时为低电平。也就是说,通过检测固定时间内测速传感器的上升沿个数来检测当前电机的速度。
我的想法是给电机绑一个长条,测量一秒钟内上升沿的个数,并且将数值发送到串口,这样就可以知道电机转速为 x转/秒。
目前计数功能,串口发送什么的都已经实现了。
但是,当我将遮挡物拿开的时候,计数并不清零,而是持续显示最新的一次测量数值,再次测量的时候还是接着上次的数值继续增加。试了一些方法,还是没有实现,不知道问题出在哪里,请大神指导一下。

目前的代码如下:

顶层模块:
  1. module motor(
  2.         input                                 sys_clk,                //时钟输入,50MHz
  3.         input                                 sys_rst_n,        //系统复位信号,下降沿有效
  4.         input                                        speed_val,                //速度信号输入       
  5.         output                                 uart_tx
  6. );

  7. parameter        time_ones        =        50_000_000;

  8. reg                                 speed_reg1;
  9. reg                                 speed_reg2;
  10. reg                                 speed_rise;
  11. reg                [7: 0] speed_count;
  12. reg                [7: 0] speed_Average;
  13. reg                [25: 0] time_cnt;

  14. always@(posedge sys_clk,negedge        sys_rst_n)
  15. begin
  16.         if(!sys_rst_n)
  17.         begin
  18.         speed_reg1 <= 1'b0;
  19.         speed_reg2 <= 1'b0;       
  20.         end
  21.         else begin
  22.         speed_reg1 <= speed_val;
  23.         speed_reg2 <= speed_reg1;
  24.         end
  25. end

  26. always@(posedge sys_clk,negedge        sys_rst_n)
  27. begin
  28.         if(!sys_rst_n)
  29.                 speed_rise        <=        1'b0;
  30.         else if(!speed_reg2 && speed_reg1)
  31.                 speed_rise        <=        1'b1;
  32.         else
  33.                 speed_rise        <=        1'b0;
  34. end

  35. always@(posedge sys_clk or negedge sys_rst_n)
  36. begin
  37.          if(!sys_rst_n)
  38.                  speed_count   <= 'b0;
  39.          else if(speed_rise)
  40.                         speed_count <= speed_count + 1;
  41.          else
  42.                         speed_count <= speed_count;
  43. end

  44. always@(posedge sys_clk or negedge sys_rst_n)
  45. begin
  46.          if(!sys_rst_n)
  47.                  speed_Average <= 'b0;
  48.          else if(time_cnt == 49999999)
  49.                 speed_Average <= 0;
  50.          else
  51.                 speed_Average <= speed_count;
  52. end

  53. always@(posedge sys_clk,negedge        sys_rst_n)
  54. begin
  55.         if(!sys_rst_n)
  56.                 time_cnt        <=        'b0;
  57.         else if(time_cnt == 49999999)
  58.                 time_cnt        <=        0;               
  59.         else
  60.                 time_cnt        <=        time_cnt        +        1'b1;               
  61. end

  62. /*串口显示单元*/
  63. reg Send_Go;
  64. reg [7:0]Data;

  65. uart_byte_tx uart_byte_tx(
  66.         .sys_clk(sys_clk),
  67.         .sys_rst_n(sys_rst_n),
  68.         .Data(Data),
  69.         .Send_Go(Send_Go),
  70.         .Baud_set(3'd0),
  71.         .uart_tx(uart_tx),
  72.         .Tx_done(Tx_done)
  73.     );
  74.          
  75. reg [25:0]counter;

  76. always@(posedge sys_clk or negedge sys_rst_n)
  77.         if(!sys_rst_n)
  78.           counter <= 0;
  79.         else if(counter == 49999999)
  80.           counter <= 0;
  81.         else
  82.           counter <= counter + 1;
  83.   
  84. always@(posedge sys_clk or negedge sys_rst_n)
  85.         if(!sys_rst_n)      
  86.           Send_Go <= 0;
  87.         else if(counter == 1)
  88.           Send_Go <= 1;
  89.         else
  90.           Send_Go <= 0;
  91.   
  92. always@(posedge sys_clk or negedge sys_rst_n)
  93.         if(!sys_rst_n)        
  94.           Data <= 0;
  95.         else if(Tx_done)
  96.           Data <= speed_Average;
  97.           
  98. endmodule
复制代码
串口发送子模块:
  1. module uart_byte_tx(
  2.     sys_clk,
  3.     sys_rst_n,
  4.     Data,
  5.     Send_Go,
  6.     Baud_set,
  7.     uart_tx,
  8.     Tx_done
  9. );
  10.     input sys_clk;
  11.     input sys_rst_n;
  12.     input [7:0]Data;
  13.     input Send_Go;
  14.     input [2:0]Baud_set;
  15.     output reg uart_tx;
  16.     output reg Tx_done;
  17.    
  18.     //Baud_set = 0   就让波特率 = 9600;
  19.     //Baud_set = 1   就让波特率 = 19200
  20.     //Baud_set = 2   就让波特率 = 38400;
  21.     //Baud_set = 3   就让波特率 = 57600;   
  22.     //Baud_set = 4   就让波特率 = 115200;

  23.     reg [17:0]bps_DR;
  24.     always@(*)
  25.         case(Baud_set)
  26.             0:bps_DR = 1000000000/9600/20;
  27.             1:bps_DR = 1000000000/19200/20;
  28.             2:bps_DR = 1000000000/38400/20;
  29.             3:bps_DR = 1000000000/57600/20;
  30.             4:bps_DR = 1000000000/115200/20;
  31.             default:bps_DR = 1000000000/9600/20;
  32.          endcase

  33.     reg Send_en;
  34.     always@(posedge sys_clk or negedge sys_rst_n)
  35.     if(!sys_rst_n)      
  36.         Send_en <= 0;
  37.     else if(Send_Go)
  38.         Send_en <= 1;
  39.     else if(Tx_done)
  40.         Send_en <= 0;
  41.         
  42.     reg [7:0]r_Data;
  43.     always@(posedge sys_clk)
  44.     if(Send_Go)
  45.         r_Data <= Data;
  46.     else
  47.         r_Data <= r_Data;     

  48.     wire bps_clk;
  49.     assign bps_clk = (div_cnt == 1);
  50.    
  51.     reg [17:0]div_cnt;
  52.     always@(posedge sys_clk or negedge sys_rst_n)
  53.     if(!sys_rst_n)
  54.         div_cnt <= 0;
  55.     else if(Send_en)begin
  56.         if(div_cnt == bps_DR - 1)
  57.             div_cnt <= 0;
  58.         else
  59.             div_cnt <= div_cnt + 1'b1;
  60.     end
  61.     else
  62.         div_cnt <= 0;

  63.     reg [3:0]bps_cnt;
  64.     always@(posedge sys_clk or negedge sys_rst_n)
  65.     if(!sys_rst_n)
  66.         bps_cnt <= 0;
  67.     else if(Send_en)begin
  68.         if(bps_clk)begin
  69.             if(bps_cnt == 11)
  70.                 bps_cnt <= 0;
  71.             else
  72.                 bps_cnt <= bps_cnt + 1'b1;
  73.         end
  74.     end
  75.     else
  76.         bps_cnt <= 0;
  77.    
  78.     always@(posedge sys_clk or negedge sys_rst_n)
  79.     if(!sys_rst_n) begin
  80.         uart_tx <= 1'b1;
  81.     end
  82.     else begin
  83.         case(bps_cnt)
  84.             1:uart_tx <= 0;
  85.             2:uart_tx <= r_Data[0];
  86.             3:uart_tx <= r_Data[1];
  87.             4:uart_tx <= r_Data[2];
  88.             5:uart_tx <= r_Data[3];
  89.             6:uart_tx <= r_Data[4];
  90.             7:uart_tx <= r_Data[5];
  91.             8:uart_tx <= r_Data[6];
  92.             9:uart_tx <= r_Data[7];
  93.             10:uart_tx <= 1;
  94.             11:begin uart_tx <= 1;end
  95.             default:uart_tx <= 1;
  96.         endcase
  97.      end
  98.      
  99.     always@(posedge sys_clk or negedge sys_rst_n)
  100.     if(!sys_rst_n)
  101.         Tx_done <= 0;
  102.     else if((bps_clk == 1)  && (bps_cnt == 10))
  103.         Tx_done <= 1;
  104.     else
  105.         Tx_done <= 0;

  106. endmodule
复制代码
效果如下:

测试效果

测试效果


0B之后我已经将遮挡物拿开,但是他还是继续保持0B,并没有清零。
测速模块用的这种的:





最佳答案

查看完整内容[请看2#楼]

你的speed_count一直没有清0,当然一直累加了。应该在每1秒到时,清0. 代码应该改成这样: always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) speed_count
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2020-7-8
在线时间
1 小时
发表于 2021-5-18 18:35:30 | 显示全部楼层
你的speed_count一直没有清0,当然一直累加了。应该在每1秒到时,清0.
代码应该改成这样:
always@(posedge sys_clk or negedge sys_rst_n)
begin
         if(!sys_rst_n)
                 speed_count   <= 'b0;
         else if(time_cnt == 49999999)
                speed_count <= 0;
         else if(speed_rise)
                speed_count <= speed_count + 1;
         else
                speed_count <= speed_count;
end

always@(posedge sys_clk or negedge sys_rst_n)
begin
         if(!sys_rst_n)
                 speed_Average <= 'b0;
         else if(time_cnt == 49999999)
                speed_Average <= speed_count ;
         else
                speed_Average <= speed_Average ;
end
回复

使用道具 举报

109

主题

5554

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10501
金钱
10501
注册时间
2017-2-18
在线时间
1902 小时
发表于 2021-5-19 16:42:06 | 显示全部楼层
帮顶~~
回复

使用道具 举报

3

主题

1979

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5520
金钱
5520
注册时间
2018-10-21
在线时间
1561 小时
发表于 2021-5-20 09:05:48 | 显示全部楼层
计数功能是你代码里计数的吧,拿掉遮挡物,计数怎么会清零呢
回复

使用道具 举报

3

主题

4

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2020-12-3
在线时间
14 小时
 楼主| 发表于 2021-5-31 09:03:59 | 显示全部楼层
tangkuan660 发表于 2021-5-18 18:35
你的speed_count一直没有清0,当然一直累加了。应该在每1秒到时,清0.
代码应该改成这样:
always@(posed ...

谢谢!我去试试看
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-10-3 20:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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