Couple Q's... - Does duty-cycle matter? - What is the range of the input freq? - Is the multiplier a fixed value? Cheers, -Neil. On Wednesday 30 April 2003 01:00, Reinaldo Alvares scribbled: > Thanks to all for your answers to my 50% stuff question. > I perhaps didn't explain myself properly or didn't understand your answ= er > correctly. > Let me please rephrase my question. Let's say I want to multiply the > frequency of an input square wave by some factor "F".Consider a sensor > giving pulses from a rotating shaft, if the shaft accelerates then two > consecutive periods are different. Every next period will be shorter th= an > the previous one. Now if I divide the first period "P" by "F" and outpu= t an > "F" amount of pulses with periods equal to "P/F" then the PIC will stil= l be > outputting pulses while the next period is already happening. I can't l= oose > counts since I need this for positioning, direction and speed measureme= nt > purposes. I have to watch both edges for any change in the direction of= the > shaft.The sensor is a quadrature encoder with only A and B outputs, no = Z. I > have to output two channels out of phase by ~90% to the system processi= ng > the data.The phase difference is naturally the same as the incoming pul= se. > I have managed to do it for a fixed or slow variable frequency.I > implemented it in software on an 16F84A, I know they are outdated, but = I > have lots of them!. When the shaft accelerates fast then I start to mis= s > about 3 to 10% of the pulses depending on the acceleration, getting off= sets > in > position.When the shaft is slowing down then is ok because the next per= iod > will be longer. There will be space enough in time to accommodate the > multiplied pulses before the next ones will have to be outputted. I mig= ht > be missing something here, I don't know what a phase accumulator is but > I'll try to find out. It looks to me that this task is just not possibl= e to > fix on a base of period by period multiplication. I appreciate very muc= h > any advise or pointer to how to solve this. And sorry for taking this > thread, I didn't mean to. > Best regards > RA > ----- Original Message ----- > From: "Scott Dattalo" > To: > Sent: Tuesday, April 29, 2003 6:09 PM > Subject: Re: [PIC]: Frequency multiplier? > > > On Tue, 29 Apr 2003, Reinaldo Alvares wrote: > > > What if the duty cycle is not 50%, and say variable? > > > > Any square wave can be made into a 50% duty cycle by dividing by 2. I= n > > other words, just watch the rising (or falling) edge. Brata's approac= h > > still works. This is just another example of a phase accumulator. > > > > I haven't been monitoring this thread too closely, but the easiest wa= y to > > solve this problem for a single channel is to utilize the PIC's input > > capture and timer 2 outputs. For example, configure TMR1 to capture a= ll > > rising edges and PR2 to specify TMR2's period. The value stuffed in P= R2 > > is simply multiplicative (and possibly filtered) factor of the captur= e > > interval. The fact that someone hasn't suggested this solution implie= s > > that either this is for a PIC without these peripherals or there is m= ore > > than one channel. [but after reading the original poster's request, i= t > > appears that only one channel is required -- so maybe there's another > > reason.] > > > > One way to do this in software is like so: > > > > In the (high frequency) interrupt routine: > > > > CurrentState =3D IOPort(); > > rising_edge =3D (CurrentState ^ LastState) & CurrentState; > > LastState =3D CurrentState; > > > > if(rising_edge & BIT_n) { > > rollover =3D rising_edge_counter; > > rising_edge_counter =3D 0; > > } else > > rising_edge_counter++; > > > > > > if(freq_out =3D=3D 0) { > > toggle_output(); > > freq_out =3D Fout_half_period; > > } else > > freq_out--; > > > > And in the main loop: > > > > if (rollover) { > > Fout_update_period(); > > rollover =3D 0; > > } > > > > > > Where Fout_update_period() scales the period of the output clock to b= e > > a multiplicative factor of the input clock. Or more specifically, the > > periods are scaled. > > > > This rather verbose approach is easily scalable to multiple channels. > > > > To monitor the rising edges and control the scaled frequency outputs, > > then something like this would suitable for a high frequency interrup= t > > (e.g. tmr0 rollovers): > > > > movf Input_PORT,W ;Read the current > > xorwf LastState,W ;compare to the last > > xorwf LastState,F ;Save current as last > > andwf LastState,W ;Get the rising edges. > > > > movwf temp ; > > iorwf rollovers,F ;Let the main loop know > > > > ; before processing the rollovers, > > ; generate the outputs (this way you'll be less susceptible to > > ; the jitter incurred with the non-isochronous code that processes > > ; the rising edges.) > > > > clrf FoutToggle ; assume that the outputs aren't > > ; going to change > > > > movf Fout0_period,W ;Get the (half) period in case we roll > > decf Fout0_ctr,F ;Toggle when this reaches zero > > ;Check the rollovers - use btf's instead > > skpnz ;of goto's for isochronous execution. > > movwf Fout0_ctr ;rolled over, so reset the counter > > skpnz ; > > bsf FoutToggle,0 ;and set this bit for below > > > > > > ... same for other outputs > > > > ; now update the outputs > > > > movf FoutToggle,W > > xorwf Fout,W > > movwf Fout > > movwf Output_PORT > > > > ; now process the rising edges. > > > > > > ch0: > > incf Ch0_ctr ;Assume rising edge did not occur > > btfsc temp,0 > > goto re0 ;Handle the rising edge > > > > ch1: > > ... > > > > chn: > > ... > > > > > > > > > > return ; or interrupt exit code > > > > > > re0: > > decf Ch0_ctr,W ; > > movwf Ch0_period > > clrf Ch0_ctr > > > > goto Ch1 > > > > re1: > > ... > > > > > > ------------ > > > > In the main loop, ch0_period and when it becomes non-zero, update th= e > > Fout0_period. Again, this is just a detailed explanation of the phase > > accumulator alogrithm proposed by Breta. > > > > Scott > > > > -- > > http://www.piclist.com hint: The PICList is archived three different > > ways. See http://www.piclist.com/#archives for details. -- http://www.piclist.com#nomail Going offline? Don't AutoReply us! email listserv@mitvma.mit.edu with SET PICList DIGEST in the body