Go Down

Topic: Clock divider methods on an Arduino UNO. (Read 138 times) previous topic - next topic

Thevenins

Aug 24, 2019, 08:02 pm Last Edit: Aug 24, 2019, 08:05 pm by Thevenins
Hi. I want to create a low frequency master clock say 200hz -  with a fixed 50 per cent duty cycle for use as an LFO on a 5v synthesiser modular rack. I also want to divide down the master frequency by 2,4 , 8, 16 .32,  64, on some other pins.
 
Without getting into the code here - does it seem feasible to achieve this all in a loop using a counter between outputs to output to the other pins e.g. if the counter has reached 2 then output to the next pin and so on.

I've looked at timers and interrupts but I think this would be the simplest method and fairly straight forward?
Many thanks for any advice.

blh64

If you chose your pins to match up with a single port (PORTB or PORTC, ...) on whatever arduino you are using, then it would be a simple matter of just incrementing a counter and writing it to that port.  The least significant bit will toggle at 200hz, bit 1 as /2, bit 2 at /x, etc.

Thevenins

Are you saying write to the port registers directly to control the pins?  If so could I do that within the loop?
I also want to be able to increment and decrement the frequency though a potentiometer so I thought I'd have to use an interrupt to process that.

jremington

#3
Aug 24, 2019, 10:57 pm Last Edit: Aug 25, 2019, 12:00 am by jremington
Quote
Are you saying write to the port registers directly to control the pins
Yes. Look up "Arduino direct port access".

Example:

Code: [Select]
PORTB = value;

Quote
so I thought I'd have to use an interrupt to process that
No, you don't. Use of interrupts usually creates more problems than it solves, especially for beginners.

It is relatively straightforward to program an 8 bit timer to increment at around 200 Hz. There are many tutorials on line, like this one.

noweare



So you would have to set the count for your highest frequency you want.

When the timer/counter gets to that count it triggers an interrupt.

in the interrupt use a counter to store the number of interrupts and you can use

that variable in your program to set your output pins on or off.




GolamMostafa

#5
Aug 25, 2019, 08:44 am Last Edit: Aug 25, 2019, 08:47 am by GolamMostafa
Clock PORTB with a signal of 200 Hz which can be easily created using TC1. The procedures are:

1.  Configure Port-B to work as output.

2.  Configure TC1 to pulse TOV1 flag at every 5 ms (1/.005 = 200 Hz). Use TOV1 as triggering source for the 200 Hz clocking signal of PORTB Register.

The Sketch: (try and check that L at DPin-13 blinks at 0.75 Hz)
Code: [Select]
void setup()
{
  DDRB = 0xFF;        //all pints of PORTB are output
  PORTB = 0x00;      //all pins are LOW

  //---TC1 intialization to generate 200 Hz triggering pulse (the TOV1 flag)
  TCCR1A = 0x0000;   //Normal Mode operation of TC1/TCNT1
  TCCR1B = 0x0000;   //TCNT1 is OFF
  TCNT1 = 0x7290;   //preset count for the overflow event to occur at 5 ms interval at clkTC1 = 2 MHz
  //2000000*.005 = 10000; ==> 0x10000 - 10000 = 0x7290
  TCCR1B = 0x02;    //start TC1 at driving clock (clkTc1) = 16000000/8 = 2 MHz
}

void loop()
{
  while (bitRead(TIFR1, 0) != HIGH)
  {
    ;     //5 ms has not elapsed
  }
  bitSet(TIFR1, 0);    //clear TOV1 flag bit
  TCNT1 = 0x7290;      //re-load preset count
  PORTB = PORTB + 1;
}

Thevenins

#6
Aug 25, 2019, 11:23 am Last Edit: Aug 25, 2019, 11:28 am by Thevenins
Thanks to everyone. I'm much more informed. It looks like counting interrupt overflows and using the port registers are my best bet. Its been taking me ages to read up on stuff between posts.

Go Up