Confused by prescallers

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Guys,

 

Wonder if someone can help.  I'm trying to track down an issue with a board I've put together which after a while 'appears' to stop all together

 

CPU is Atmega328P connecting to a TLC5940 with SPI.  External clock running at 20mHz

 

I've using some sample code (michael cousins's TLC5940 class) and I've realised that the problem might be that I don't have the prescaler settings for 20mHz as the sample is for 16.

 

However for the life of me, I can't figure out what needs changing for the higher clock speed

 

regards

 

cli();

	// user timer 1 to toggle the gs clock pin
	TCCR1A = 0;
	TCCR1B = 0;
	TCCR1C = 0;
	TIMSK1 = 0;
	// toggle OC1A (pin B1) on compare match event
	TCCR1A |= (1 << COM1A0);
	// set the top of the timer
	// PS = 1, F_CPU = 16 MHz, F_OC = F_CPU/(2 * PS * (OCR1A+1)
	// gs edge gets sent every 32*2=64 clock ticks
	OCR1A = 31;
	// put the timer in CTC mode and start timer with no prescaler
	TCCR1B |= ( (1 << WGM12) | (1 << CS10) );

	// set up an isr for the serial cycle to live in
	// let it live in timer 0
	TCCR0A = 0;
	TCCR0B = 0;
	TIMSK0 = 0;
	// set waveform generation bit to put the timer into CTC mode
	TCCR0A |= (1 << WGM01);
	// set the top of the timer - want this to happen every 4096 * gs clocks = every 8192 clock ticks
	// set top to 255 for an interrupt every 256 * 1024 = 64 * 4096 clock ticks
	OCR0A = 255;
	// start the timer with a 1024 prescaler
	TCCR0B |= ( (1 << CS02) | (1 << CS00) );
	// enable the interrupt of output compare A match
	TIMSK0 |= (1 << OCIE0A);

	sei();

 

This topic has a solution.

 

 

Last Edited: Thu. Jun 17, 2021 - 07:40 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Doesn't the comment help?

	// set the top of the timer
	// PS = 1, F_CPU = 16 MHz, F_OC = F_CPU/(2 * PS * (OCR1A+1)
	// gs edge gets sent every 32*2=64 clock ticks
	OCR1A = 31;

It's not so much about prescaling (I sort of assume 16 and 20 MHz are likely to use the same prescale) but it's about the period calculation. It even gives the calculation in the comment but even without that, simplistically. If you increase the clock rate by a factor of 16:20 then presumably the period would need to be changed by increasing the 31 in the same ratio. So the 31 would presumably become 31 * 20 / 16 = 39 (rounded up to nearest integer).

 

As it stands the 16MHz calculation for

F_OC = F_CPU/(2 * PS * (OCR1A+1)

is presumably:

F_OC = 16000000/(2 * 1 * (31 + 1)

so:

F_OC = 16000000/64
F_OC = 250,000

If you plug in 20000000 and 39 then I guess this becomes:

F_OC = 20000000/80
F_OC = 250,000

which does indeed seem to arrive at the same place.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Check the code for SPCR, what is there, please. Setting of SPR0 and SPR1 is important.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's bit banging the SPI data, so unless I'm mistaken it's not pertinent, though I'm happy to be corrected

 

regards

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Turns out that cause of the processor 'stopping' was a power issue.  Turning all the outputs on at once caused the voltage to go below 1.8 volts and the processor reset.  (I set a break point in the start of thecode and picked it up)

 

A better PSU resolved the issue.  

 

Many thanks for all the input, it certainly made me understand what was going on.

 

regards

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nikm wrote:

Turns out that cause of the processor 'stopping' was a power issue.  Turning all the outputs on at once caused the voltage to go below 1.8 volts and the processor reset.  (I set a break point in the start of thecode and picked it up)

 

A better PSU resolved the issue.  

 

Welcome to the exciting world of micros. :)