Go Down

Topic: Setting clock prescaler to get lower SPI clock frequency (Uno 3.1 board) (Read 1 time) previous topic - next topic

pblase

Working with a Uno 3.1 board, with an ATmega328, I am working with a display that uses the SPI interface with a maximum clock speed of 100kHz. Given that the Uno has a clock frequency of 16 MHz, and the SPI prescaler only goes down to clock/128 = 125 kHz, I need to drop the basic clock rate to get the SPI clock down far enough. How does the Arduino IDE set up the processor, and is there anything keeping me from writing to the prescaler register (CLKPR)?

e.g.
  CLKPR = _BV(CLKPCE);
  CLKPR |= 0x01; //div by 2

dhenry

1) It is rare to have a spi device asking for a specific speed, especially at 100Khz.
2) If so, you are basically out of luck.
3) A few alternatives: write a software spi that uses a timer interrupt; or to bit bang. The 2nd approach is blocking and very inefficient at low speed.
4) A hardware-based solution would be to utilize a parallel-to-serial shift register.

pblase

It's not a specific speed, 100 kHz is the maximum speed.

CLKPR = _BV(CLKPCE); //enable clock
CLKPR = 0x01; //div by 2
will change the system clock, BTW. Still doesn't work, I'll have to get out the logic probe.
I wonder if this futzes up anything else, though?

Coding Badly

I wonder if this futzes up anything else, though?


Yes.  Everything time-based (baud rate, delay, millis, etcetera).

SPI is easy to bit-bang.  Have you considered doing that instead of using the hardware SPI module?

pblase

Well, if I was going to do that, I wouldn't use the Arduino IDE at all but program it directly through Studio. It's a possibility, though.

dhenry

The issue you are facing is a hardware limitation (or design limitation, depending on your perspective): the prescaler value required is beyond the hardware's capabilities.

That cannot be possibly remediated by going to any IDE/software platform.

Coding Badly

That cannot be possibly remediated by going to any IDE/software platform.


I absolutely agree.

@pblase, why would you switch development tools just because you need a tiny bit of software that can very likely be found by spending a few minutes with Google?

pblase

You misunderstand. If I want to do "bit-banging", I'm not going to do it in the Arduino IDE. Of course I'd rather not do that at all, if I can just drop the clock and make the on-chip hardware do what I need to do.  I know that the ultimate problem is a hardware limitation, I just want to make sure what else I'm messing up. I'm new to the Arduino IDE, not to Atmel microcontrollers.

dhenry

You can still use the spi hardware, if you use external circuitry.

Say that you want to half the clock rate. You can put a flip-flop on the sck line to slow it down. Then you can load split the data byte into two bytes, by repeating the consecutive bits. For example, if you are sending 0b1001 1101, you can split it up to 0b1100 0011, and 0b1111 0011. The two bytes will be received as 0b1001 1101, as half the actual clock rate.

However, I still think using a timer isr is  much simpler and more elegant.

Go Up