Can I get 840HZ from a Xilinx Spartan-3's DCM? Phase locked?

I need to generate signals to dim incandescent lights to one of 16 dimming levels.

I have built a 14-bit counter, which gives 16 discrete signals when used with always-on and always-off signals. To properly dim my lights, I need an 840Hz signal (that's the 60Hz mains frequency times 14 clock cycles needed) to drive my 14-bit counter circuit.

(Yes, I plan on using the same solution to generate 700Hz (50Hz * 14) for other regions of the world.)

Oh yeah, and I'd like this clock synchronized to the zero-crossing of the mains voltage, to minimize line noise when switching loads on.

I'm looking at Appnote XAPP462 and I don't think it's going to be possible to generate this singal on-chip. My desired output frequency is lower than the DCM will go. I know I can divide the output of whatever frequency I can generate, but I don't know if (or how) I can sync with the mains zero crossing at such low frequencies.

However, I'm an amateur here and wanted to toss it out to the more experienced crowd. Can this be done?

Thanks,

-Nevo

Reply to
Nevo
Loading thread data ...

Hi Nevo -

A 14-bit counter does not cycle every 14 clock cycles. It rolls over every

2^14 clock cycles. It really sounds like you want a 4-bit counter counting modulus 14 and driving 14 PWM outputs (plus your always-on and always-off outputs). I didn't look at XAPP462 so I don't know what you're referring to there, but if you need to multiply the mains frequency to generate a clock, see the recent thread with the subject line "2KHz clock signal from 50Hz main frequency with ADPLL".

Rob

Reply to
RobJ

I don't think that 16 levels are sufficient for dimming, because it be logarithmic: If the lamp is dim, small changes in the pulse width may cause larger brightness perception than if the lamp is already bright. So I suggest to use 256 steps and using a lookup table, if your controll unit has 16 steps.

For such low frequencies you can measure it and adjust a divider for every rising reference clock edge:

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL;

entity pll is generic(multiplier, reference_clock_frequency, system_clock_frequency: natural); port( reference_clock: in std_logic; system_clock: in std_logic; clock_out: out std_logic); end entity pll;

architecture rtl of pll is

signal system_clock_counter: unsigned(31 downto 0) := (others => '0'); signal system_clock_divider: unsigned(31 downto 0) := to_unsigned(system_clock_frequency / (multiplier * reference_clock_frequency) / 2, 32); signal clock_counter: unsigned(15 downto 0) := (others => '0'); signal clock_signal: std_logic := '0'; signal old_reference_clock: std_logic := '0';

begin update_counter: process(system_clock) begin if system_clock'event and system_clock = '1' then if old_reference_clock /= reference_clock and reference_clock = '1' then if clock_counter > multiplier * 2 then system_clock_divider

Reply to
Frank Buss

You're right; I didn't design a counter. I should have realized that I can't get away with imprecise language use on a technical discussion group! I did, in fact, implement a 14-bit wide PWM output (essentially using a shift register where the incoming bit is always high.)

Thank you for the reference to the previous thread; I'll go dig it up!

-Nevo

Reply to
Nevo

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.