duty cycle of clock divider

formatting link

The frequency is 440Hz, as expected, but the output duty cycle is not 50% a nymore. The low level goes from counter=0 to counter=32767 (when bit 15 of counter is low) and then high level from 32768 to 56817. That gives us "speaker" being high only 42% of the time. The easiest way to get a 50% dut y cycle is to add a stage that divides the output by 2. So first we divide by 28409 (instead of 56818) and then by 2. ????

I do not understand why we need to divide by 2. Could anyone explain the above reasoning in more laymen way ?

Reply to
promach
Loading thread data ...

He means divide the frequency by 2, implemented by a single stage counter flip flop. This will then always give a 50% duty cycle.

Reply to
Andy Bennet

I do not get how just dividing by 2 could get 50% duty cycle instead of 42% ?

Reply to
promach

Assuming the input frequency to the divider is constant, then:- that frequency is defined by the reciprocal of the time period that elapses between successive rising or falling or some fixed point in the repetitive waveform ... True or false ...

If true then if you clock a flip flop at the fixed point in the repetive waveform then the outout will toggle high for one complete period of the input waveform, and toggle low for one complete period of the input waveform. If the frequency is constant, then the period of successive cycle of the input waveform will be the same. Therefore the output of the flip flop divider will have a 50% duty cycle.

If false then it is not a constant input frequency and all the above does not apply.

Andy

Reply to
Andy Bennet

Strange, I have the clock divider coding at

formatting link

but it does not divide accordingly as mentioned in the article.

Any idea about what I missed out ?

// Adapted from

formatting link

module clk_div (i_clk, ck_stb); input i_clk; output reg ck_stb = 0; localparam THRESHOLD = 3; // divides i_clk by (2*THRESHOLD = 6) to obtain ck_stb which is the divided clock signal reg [($clog2(THRESHOLD)-1):0] counter = 0; reg counter_reset = 0; always @(posedge i_clk) counter_reset

Reply to
promach

I have tried clock divider at

formatting link
, but it does not divide accordingly as mentioned in the article.

Any idea about what I missed out ?

// Adapted from

formatting link

module clk_div (i_clk, ck_stb); input i_clk; output reg ck_stb = 0; localparam THRESHOLD = 3; // divides i_clk by (2*THRESHOLD = 6) to obtain ck_stb which is the divided clock signal reg [($clog2(THRESHOLD)-1):0] counter = 0; reg counter_reset = 0; always @(posedge i_clk) counter_reset

Reply to
promach

I have found out the bug.

The last always block should look like the following:

always @(posedge i_clk) if(counter_reset) ck_stb

Reply to
promach

@Andy

For ambulance siren at

formatting link
and
formatting link
, could you comment on the simulation waveform
formatting link
?

Note: I will do the actual hardware (speaker) audio testing tomorrow.

//

formatting link
- Ambulance siren

module clk_div (i_clk, ck_stb); input i_clk; output reg ck_stb = 0; localparam THRESHOLD = 6; // divides i_clk by 6 to obtain ck_stb which is the divided clock signal localparam TOGGLE_FREQUENCY_RATIO = 4; // MSB bit of "tone" toggles with a frequency of about [i_clk / 2^4] reg [($clog2(THRESHOLD) - 1):0] counter = 0; reg counter_reset = 0; reg [(TOGGLE_FREQUENCY_RATIO - 1):0] tone = 0; always @(posedge i_clk) tone

Reply to
promach

Reply to
Andy Bennet

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.