OpenEdv-开源电子网

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

VHDL小源程序

[复制链接]

18

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
374
金钱
374
注册时间
2012-6-20
在线时间
100 小时
发表于 2012-6-30 11:34:59 | 显示全部楼层 |阅读模式
 
一.积分分频(小数分频)注:只是对平均频率,输出不均匀。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
ENTITY FDIV IS
   ORT (
      clkin                    : in std_logic;      
      clkout          ut std_logic);   
END FDIV;

ARCHITECTURE epm570 OF FDIV IS   
   SIGNAL delay             :  std_logic;  
      SIGNAL q           :  std_logic_vector(3 downto 0);   

BEGIN
   ROCESS
   BEGIN
   WAIT UNTIL (clkin'EVENT AND clkin = '1');  
    delay <=q(3);  
    q <= q+6;  
   END PROCESS;

clkout <=(q(3) xor delay) and not clkin;
END epm570;

二.上升沿,下降沿微分电路。
clk  :时钟大于大于din   
din  :输入信号
up_diff :din 上升沿后输出一个clk周期宽的脉冲
dn_diff :din 下降沿后输出一个clk周期宽的脉冲


library ieee;  
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;  
use ieee.std_logic_arith.all;  
ENTITY DIFF IS  
   ORT (  
      clk                    : in std_logic;     
      din                    : in std_logic;     
      up_diff,dn_diff          ut std_logic);     
END DIFF;  

ARCHITECTURE epm570 OF DIFF IS   
   SIGNAL t1,t2           :  std_logic;     

BEGIN  
   ROCESS
   BEGIN  
   WAIT UNTIL (clk'EVENT AND clk = '1');     
    t2 <= t1;   
    t1 <= din;   
   END PROCESS;  

up_diff<=t1 AND NOT t2;
dn_diff<=NOT t1 AND t2;

END epm570;

三.下降沿单稳态电路,或类似定时器之类。
clk:   时钟
tclk:  触发输入
delayout :输出脉宽=delaymax*clk周期
   



library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
ENTITY DELAY_T IS
GENERIC (delaymax:integer:=4);
   ORT (
      clk                    : in std_logic;
      tclk       : in std_logic;
      delayout     :buffer std_logic);   
END DELAY_T;

ARCHITECTURE epm570 OF DELAY_T IS   
SIGNAL tclk_1        :  std_logic;   

BEGIN
PROCESS(tclk,tclk_1)
BEGIN
        if        (tclk_1='1')then
        delayout<='0';
        elsif(tclk'EVENT AND tclk = '0')then  
        delayout<='1';
        end if;
END PROCESS;
   
PROCESS(clk,delayout)
variable delayT: integer range 0 to delaymax:=0;
BEGIN
if (delayout='0')then   
delayT:=0;
tclk_1<='0';
else if(clk'EVENT AND clk = '1')then       
                if(delayT=delaymax)then
                tclk_1<='1';
                end if;
                delayT:=delayT+1;
                end if;
end if;   
END PROCESS;

END epm570;

梯形加减脉冲产生程序,只提供方法,可简单应用。
      load       加载参数,高电平      
      pulout      输出
      puldata     产生脉冲的总数   
      smax        工作速度 1-250         
      smin         起始速度 1-250
      lnub         到达最低速度后输出的脉冲个数


(原文件名:未命名.jpg)

        

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
ENTITY TPJ IS
GENERIC (lnub:integer:=0);

   ORT (
      clk                    : IN std_logic;  
      load                      : IN std_logic;  
      en                      : IN std_logic;  
      pulout                 : out std_logic;
      puldata              : in  std_logic_vector(15 DOWNTO 0);
      smax                 : in  std_logic_vector(7 DOWNTO 0);
      smin                 : in  std_logic_vector(7 DOWNTO 0));
END TPJ;

ARCHITECTURE epm570 OF TPJ IS
SIGNAL smax_0 :  std_logic_vector(7 DOWNTO 0);
SIGNAL sq_r :  std_logic_vector(7 DOWNTO 0);   
SIGNAL smin_r:  std_logic_vector(7 DOWNTO 0);  
SIGNAL dir_r    : std_logic;
SIGNAL puldata_r    : std_logic_vector(15 DOWNTO 0);
  
BEGIN
PROCESS(clk)
BEGIN
IF (clk'EVENT AND clk = '1')THEN
if ((puldata-puldata_r)<smin+lnub) then

dir_r<='0';
else
dir_r<='1';
end if;
end if;
END PROCESS;

PROCESS(clk)
BEGIN
IF (clk'EVENT AND clk = '1')THEN
if (load='1')then
sq_r <="00000000" ;
smin_r <=smin ;
smax_0 <=smin ;
end if;
        if (en='1')then
       
                if(puldata_r=puldata)then
                pulout<='0';
                else
       
                                if(dir_r='1')then
                                        if (sq_r<smin_r)then
                                        sq_r <= sq_r + 1;  
                                        pulout<='1';
                                        else
                                        sq_r<="00000000";
                                                if (smin_r>smax)then       
                                                        smin_r<=smin_r-1;
                                                else
                                                smin_r<=smax;
                                                end if;
                                        pulout<='0';
                                        puldata_r<=puldata_r+'1';
                                        END IF;
                                else
                                        if (sq_r<(smin_r))then
                                        sq_r <= sq_r + 1;  
                                        pulout<='1';                               
                                        else
                                        sq_r<="00000000";
                                                if (smin_r<smax_0)then       
                                                        smin_r<=smin_r+1;
                                                else
                                                smin_r<=smax_0;
                                                end if;
                                        pulout<='0';
                                                puldata_r<=puldata_r+'1';
                                        END IF;
                          end if;
            
            end if;
        end if;       
end if;
END PROCESS;
END epm570;

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

18

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
374
金钱
374
注册时间
2012-6-20
在线时间
100 小时
 楼主| 发表于 2012-6-30 11:42:46 | 显示全部楼层

DDA两轴直线插补



其中m就是一楼我要的Z值 m一个和积分有关的数,能改变整个周期,就是XY进给速度和m有关.



library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity DDA is
--generic (n : natural := 32);
port (
Xe           : in STD_LOGIC_VECTOR (31 DOWNTO 0);
Ye           : in STD_LOGIC_VECTOR (31 DOWNTO 0);
n           : in STD_LOGIC_VECTOR (31 DOWNTO 0);
Clock,rest    : in std_logic;
Xout          : out std_logic;
Yout          : out std_logic);

end entity DDA;

architecture maxcpld of DDA is
SIGNAL Jrx : STD_LOGIC_VECTOR (31 DOWNTO 0);
SIGNAL Jry : STD_LOGIC_VECTOR (31 DOWNTO 0);
SIGNAL Jvx : STD_LOGIC_VECTOR (31 DOWNTO 0);
SIGNAL Jvy : STD_LOGIC_VECTOR (31 DOWNTO 0);
SIGNAL m  : STD_LOGIC_VECTOR (31 DOWNTO 0);   
SIGNAL c  : STD_LOGIC_VECTOR (31 DOWNTO 0);
SIGNAL d  :  std_logic;
begin

process (Clock,rest) is
begin
if(rest='1')then
Jrx <= "00000000000000000000000000000000";
Jry <= "00000000000000000000000000000000";
m <= n;
Jvx <= Xe;
Jvy <= Ye;
d <='0';
elsif rising_edge(Clock) then
   
        if (c/=m)then
            c<=c+1;
            
                if((jvx+jrx)>=m )then
                jrx<=jvx+jrx-m;
                       
                        Xout<='1';
               
                else
                jrx<=jvx+jrx;
                Xout<='0';
                end if;
       
                if((jvy+jry)>=m )then
                jry<=jvy+jry-m;
                 
                        Yout<='1';
               
               
                else
                jry<=jvy+jry;
                Yout<='0';
                end if;
        else
        Yout<='0';
        Xout<='0';
        end if;
end if;
end  process;

end maxcpld;




D (原文件名:1.jpg)


m (原文件名:2.jpg)


m (原文件名:3.jpg)

回复 支持 反对

使用道具 举报

18

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
374
金钱
374
注册时间
2012-6-20
在线时间
100 小时
 楼主| 发表于 2012-6-30 11:47:42 | 显示全部楼层
 
PID VHDL [审核未通过] 2012-3-6 15:02阅读(0)
赞赞赞赞转载分享评论复制地址举报编辑
 
 library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity pid_controller is 

   generic 
      ( 
            -- size of input and output data -- 
            iDataWidith : integer range 8 to 32:= 8; 
            -- proportionally gain -- 
            iKP         : integer range 0 to 7:= 3;  -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256 
            -- integral gain -- 
            iKI         : integer range 0 to 7:= 2;  -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256 
            -- differential gain -- 
            iKD         : integer range 0 to 7:= 2;  -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256 
            -- master gain -- 
            iKM         : integer range 0 to 7:= 1;  -- 0 - /1, 1 - /2, 2 - /4, 3 - /8 , 4 - /16, 5 - /32, 6 - /64 , 7 - /128 
            -- delay between samples of error -- 
            iDelayD     : integer range 1 to 16:= 10; 
            -- 0 - controller use derivative of ATERN_I and ATERN_ESTIMATION_I, 1 - controller use error to work -- 
            iWork       : integer range 0 to 1:= 1    
            ); 

   port 
      ( 
            CLK_I            : in  std_logic; 
            RESET_I          : in  std_logic; 
            -- error  -- 
            ERROR_I          : in  std_logic_vector(iDataWidith - 1 downto 0); 
            -- threshold
            ATERN_I         : in  std_logic_vector(iDataWidith - 1 downto 0); 
            -- current sample
            ATERN_ESTIMATION_I: in  std_logic_vector(iDataWidith - 1 downto 0); 
            -- correction
            CORRECT_O        : out std_logic_vector(iDataWidith - 1 downto 0) 
            ); 
    
end entity pid_controller; 

architecture rtl of pid_controller is 
------------------------------------------------------------------------------- 
-- functions -- 
------------------------------------------------------------------------------- 
-- purpose: make a std_logic_vector of size c_size and build from c_value -- 
   function f_something ( constant c_size: integer; signal c_value: std_logic) return std_logic_vector is 

      variable var_temp: std_logic_vector(c_size - 1 downto 0); 
       
   begin  -- function f_something -- 

      var_temp:= (others => c_value); 

      return var_temp; 
       
   end function f_something; 
-- examples: 
-- f_something(c_size => 3 , c_value => 'Z')  == "ZZZ" 
-- f_something(c_size => 3 , c_value => '1')  == "111" 
-- ... 
------------------------------------------------------------------------------- 
-- types -- 
------------------------------------------------------------------------------- 
   -- delay register -- 
   type type_sr is array (0 to iDelayD - 1) of std_logic_vector(iDataWidith - 1 downto 0); 
    
------------------------------------------------------------------------------- 
-- signals -- 
------------------------------------------------------------------------------- 
   signal v_error : std_logic_vector(iDataWidith - 1 downto 0); 
   signal v_error_KM: std_logic_vector(iDataWidith - 1 downto 0); 
   signal v_error_KP: std_logic_vector(iDataWidith - 1 downto 0); 
   signal v_error_KD: std_logic_vector(iDataWidith - 1 downto 0); 
   signal v_error_KI: std_logic_vector(iDataWidith - 1 downto 0); 
   signal t_div_late: type_sr; 
   signal v_div   : std_logic_vector(iDataWidith - 1 downto 0); 
   signal v_acu_earl: std_logic_vector(iDataWidith - 1 downto 0); 
   signal v_acu   : std_logic_vector(iDataWidith - 1 downto 0); 
   signal v_sum   : std_logic_vector(iDataWidith - 1 downto 0); 
    
begin  -- architecture rtl -- 

-- choice source of input data -- 
   v_error <= ERROR_I       when iWork = 1 else 
              conv_std_logic_vector(signed(PATERN_I) - signed(PATERN_ESTIMATION_I) , iDataWidith) when iWork = 0 else 
              (others => '0'); 
-- master gain execute by shift of iKM bits to the right -- 
   v_error_KM <= v_error                                                                                                when iKM = 0 else 
                 f_something(c_size => iKM , c_value => v_error(iDataWidith - 1)) & v_error(iDataWidith - 1 downto iKM) when iKM > 0 else 
                 (others => '0'); 
    
-- proportionally gain execute by shift of (iKP - 1) bits to the right -- 
   v_error_KP <= f_something(c_size => iKP + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKP + 1); 
    
-- derivative gain execute by shift of (iKD - 1) bits to the right -- 
   v_error_KD <= f_something(c_size => iKD + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKD + 1); 
    
-- integral gain execute by shift of (iKI + 1) bits to the right -- 
   v_error_KI <= f_something(c_size => iKI + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKI + 1); 

   DI00: process (CLK_I) is 
   begin  -- process DI00 

      if rising_edge(CLK_I) then 

         -- synchronous reset -- 
         if RESET_I = '1' then 

            t_div_late <= (others => (others => '0')); 
            v_div      <= (others => '0'); 
            v_acu      <= (others => '0'); 
            v_acu_earl <= (others => '0'); 

         else 

            -- delay register -- 
            t_div_late <= v_error_KD & t_div_late(0 to iDelayD - 2); 

            -- difference between samples -- 
            v_div <= conv_std_logic_vector(signed(v_error_KD) - signed(t_div_late(iDelayD - 1)) , iDataWidith); 

            -- integration of error -- 
            v_acu <= conv_std_logic_vector(signed(v_error_KI) + signed(v_acu_earl) , iDataWidith); 
            -- sum of N - 1 samples of error -- 
            v_acu_earl <= v_acu;          
         end if; 
          
      end if; 
       
   end process DI00; 

   -- first stage of adder --  
   v_sum <= conv_std_logic_vector(signed(v_acu) + signed(v_div) , iDataWidith); 
   -- correction and second stage of adder -- 
   CORRECT_O <= conv_std_logic_vector(signed(v_error_KP) + signed(v_sum) , iDataWidith) when RESET_I  = '0' else 
                (others => '0'); 
    
end architecture rtl;  
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-6-30 13:26:17 | 显示全部楼层
谢谢分享.
回复 支持 反对

使用道具 举报

35

主题

227

帖子

3

精华

高级会员

Rank: 4

积分
956
金钱
956
注册时间
2014-3-5
在线时间
35 小时
发表于 2015-4-4 15:06:14 | 显示全部楼层
回复【2楼】MY40130064:
---------------------------------
谢谢分享,有没有stm32的DDA插补程序呢,最近在做步进电机控制,希望多交流
把看到的有意义的例子进行扩充,并将其切实的运用到自己的设计中。 应用确实不容易,水平是在不断的实践中完善和发展的。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-23 05:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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