CPLD 与AVR通信 PWM控制程序

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

 

entity KBCtest is

port(

rst,clk : in std_logic; --时钟和复位信号

--AVR 读写相关信号线

ale,rd,wr : in std_logic; --地址锁存、读、写信号

ad : inout std_logic_vector(7 downto 0); --地址数据信号线

--指示灯

led1,led2 : out std_logic;

--PWM

pwm1,pwm2 : out std_logic

--放大增益控制

--AD8364读写操作信号线

);

end KBCtest;

 

architecture art of  KBCtest is

------------------------------------------------全局信号定义-------------------------------------------------------------------

--AVR访问操作相关信号

signal adr :   std_logic_vector(7 downto 0);  --地址寄存器

signal data_buf :   std_logic_vector(7 downto 0);

signal data_outctl : std_logic;

 

 

--pwm部分相关寄存器定义 寄存器暂时定义为8位

signal pwmfreq_reg : std_logic_vector(7 downto 0);

signal pwmocr1_reg : std_logic_vector(7 downto 0);

signal pwmocr2_reg : std_logic_vector(7 downto 0);

 

signal pwm_cnt : std_logic_vector(7 downto 0);

 

--时钟分频相关变量

signal clkcnt : std_logic_vector(16 downto 0);

signal adc_clk : std_logic; --ADC时钟信号

signal pwm_clk : std_logic; --pwm时钟信号

 

--led指示相关变量

signal led_clk : std_logic; --led时钟信

signal led1_cnt : std_logic_vector(7 downto 0);

signal led2_cnt : std_logic_vector(7 downto 0);

signal led1s : std_logic;

signal led2s : std_logic;

begin

 

------------------------------------------------时钟分频-------------------------------------------------------------------

process(rst,clk) is

begin

if rst='0' then

clkcnt <= "00000000000000000";

elsif(clk'event and clk = '1') then

if(clkcnt = "11111111111111111") then

clkcnt<= "00000000000000000";

else

clkcnt <= clkcnt+1;

end if;

end if;

end process;

pwm_clk <= clkcnt(7); --分频PWM时钟

led_clk <= clkcnt(16); --分频LED时钟

 

------------------------------------------------AVR访问操作----------------------------------------------------------------

data_outctl <= (not ale) and (not rd) and (wr);

ad <=  data_buf when (data_outctl='1') else "ZZZZZZZZ";

 

--锁存AVR地址数据

process(rst,ale) is

begin

if rst='0' then 

adr <= "00000000";

elsif(ale'event and ale='0') then --在ale信号的下降沿锁存地址数据

adr <= ad;

end if;

end process;

 

-------------------------------------AVR写数据-----------------------------------

process(rst,wr,ale) is

begin

if rst='0' then --对各寄存器给定初值

pwmfreq_reg <= "11111111";

pwmocr1_reg <= "10000000";

elsif (wr='1' and wr'event) then --在wr信号上升沿进行写操作

if ale = '0' then 

case adr is

when "00000001" => pwmfreq_reg <= ad;

when "00000010" => pwmocr1_reg <= ad;

 

when others =>

pwmfreq_reg <= pwmfreq_reg;

 

end case;

end if;

end if;

end process;

 

------------------------------------AVR读数据-------------------------------------

process(rst,rd,ale) is

begin

if rst='0' then

data_buf<="00000000";

elsif (rd='0'and rd'event) then

case adr is

when "00000001" => data_buf <= pwmfreq_reg;

when "00000010" => data_buf <= pwmocr1_reg;

when "00000011" => data_buf <= "00110011";

when others => 

data_buf <= "ZZZZZZZZ";

end case;

end if;

end process;

------------------------------------LED指示-------------------------------------

process(led_clk)is

begin

if(led_clk'event and led_clk='1') then

led1_cnt <= led1_cnt+1;

if (led1_cnt >= pwmfreq_reg) then

led1s <= NOT led1s; 

led1_cnt <="00000000";

end if;

end if;

end process;

led1<=led1s;

process(led_clk)is

begin

if(led_clk'event and led_clk='1') then

led2_cnt <= led2_cnt+1;

if (led2_cnt >= pwmocr1_reg) then

led2s <= NOT led2s; 

led2_cnt <="00000000";

end if;

end if;

end process;

led2<=led2s;

 

--------------------------------------PWM---------------------------------------

process(pwm_clk) is

begin

if rst='0' then             

pwm_cnt<="00000000";

elsif(pwm_clk'event and pwm_clk='1') then

if(pwm_cnt > pwmfreq_reg) then

pwm_cnt <= "00000000";

else  

pwm_cnt<=pwm_cnt+1;

end if;

--数据比较模块

if(pwm_cnt>=pwmocr1_reg) then  

pwm1<= '1';

else 

pwm1<= '0';

end if;

end if;

end process;

end;

 

你可能感兴趣的:(CPLD 与AVR通信 PWM控制程序)