NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » How to Display Mhz and Baudrate on Display

May 02, 2015
by lnino
lnino's Avatar

Hi at all,

to get a better understanding how the Mhz and Baudrate are calculated and set I want to Display the current value on the attached Display.

Do you know how I can Show live values of Baudrate and Crystal frequency on my nerdkit Display?

May 02, 2015
by BobaMosfet
BobaMosfet's Avatar

Inino-

Datasheet for the micro-controller will give you the formula for calculating baudrate. Datasheet should also give you example code for setting it, in assembly and in C (Atmel is pretty good at providing this info, normally).

If you want two-way communication, relatively simply, just set up a function to initialize the UART for the baudrate you want to use. Create a global variable that is your circular input data buffer, and set up an interrupt to fill that buffer. Other code, can keep that buffer cleared out faster than it can be filled.

If you don't care about inbound comm, then simply create a function to initialize the UART, and a function to output a char (which is easy. Just load a register and let the chip do the rest).

MHz-- that's the clockspeed of your micro-controller. Everything the micro does is based on that, including timing. Look in your datasheet of for an optimal baudrate that will work for you, based on the requirements of the device you intend to talk to (it might not be able to work with a baudrate higher than 9600 for example), and isn't too lossy.

For learning, I recommend starting at 50baud and working up, just to keep things simple and be able to register changes with an LED for example, on the TX pin. In fact, it's not a bad idea to put an LED on each TX or RX pin in parallel with it, so you can even see if anything is initially done on the pin(s) in response to what your code is doing.

BM

May 02, 2015
by lnino
lnino's Avatar

Hi BobaMosfet,

thank you for your explanation.

I know which registers I have to set for cpu and baudrate. I want more like a check to control if I have programmed everything right and if I did all the wireing correctly on the PCB.

I want to see if the external crystal is oscillating on 14,7456Mhz. Or is the internal clock of 1Mhz used?

Is there a way to show the live value of the current cpu clock on my nerdkit display?

Because when I set the CPU like this:

#define F_CPU 14745600

How do I know the CPU really opperates at this speed? Because Setting the Baudrate regarding to the CPU speed is relevant.

When I want a Baudrate of 19200 at a CPU speed of 14475600 I have to set UBRR to 47.

If the CPU is not 14475600 the value for UBBR will be wrong and the UART communication is not working.

May 03, 2015
by Noter
Noter's Avatar

I suppose you could use the watchdog timer via interrupt to measure/calculate cpu clock speed. Probably wouldn't be perfectly accurate but might be close enough for your purposes.

May 04, 2015
by Noter
Noter's Avatar

I gave it a try and although the watchdog timer is not very accurate it does give a reasonable measurement so that you could tell if you were using the internal 8mhz or 1mhz clock vs an external crystal. The little arduino I tested on has a watchdog timer that is too long by about 10% so the measurement printed is 17.5 mHz instead of the expected 16.0 mHz. No telling how much of that error is in the external oscillator either but may still be useful depending on what you are looking for.

/*
  MeasureCpuFrequency

  Uses the watchdog timer to measure cpu frequency.
 */

#include <avr/wdt.h>

volatile unsigned long increment = 0;
volatile unsigned long measurement = 0;

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  //set timer2 interrupt every 256 * 32 = 8192 clock ticks
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2  = 0;
  OCR2A = 255;
  TCCR2A |= _BV(WGM21); // CTC mode
  TCCR2B |= _BV(CS21) | _BV(CS20);  // prescaler of 32 
  TIMSK2 |= _BV(OCIE2A); // enable compare interrupt

  // setup the watchdog timer
  MCUSR &= ~_BV(WDRF);  // clear reset flag
  WDTCSR |= _BV(WDCE) | _BV(WDE); // enable WDE/prescaler update
  WDTCSR = _BV(WDIE) | _BV(WDP1) | _BV(WDP2); // enable WD interrupt only (no reset) with prescaler set to 1 second

  // enable interrupts
  sei();
}

// Timer2 Interrupt Service
ISR(TIMER2_COMPA_vect){
  increment++;
}

// Watchdog Interrupt Service
ISR(WDT_vect)
{
  measurement = increment;
  increment = 0;
}

// the loop routine runs forever:
void loop() {
  if(measurement){
    unsigned long tmp = measurement;
    measurement = 0;
    Serial.print("cpu frequency = ");
    Serial.print(tmp * 8192);
    Serial.println(" Hz");
  }
}
May 04, 2015
by lnino
lnino's Avatar

Hi Noter,

thanks a lot for your time and your help. I really appreciate this. That definately helps me to see if the external chrystal is working or not.

May 04, 2015
by BobaMosfet
BobaMosfet's Avatar

Inino-

Actually, if you intend to do this internally, The only reasonably accurate way you can do this is by using two timers and two interrupts. You cannot trigger an interrupt on every cycle-- the uC can't keep up. It takes several cycles for stackframes, and instructions, contexts, etc to occur to get in and out of an interrupt, let alone whatever you're trying to do in the interrupt.

First timer is prescaled-- in other words, downsampled. This is your counter. For every x actual cycles, it can trigger your first interrupt where you simply increment a value.

Second timer- prescale or configure as convenient to run for 1 second.

Once the second timer has elapsed, simply upsample your count values and display it. Retain the frequency value, and average it with the next go-round, if you repeat continuously and it will get a little more accurate over time, to a point.

BM

May 04, 2015
by Noter
Noter's Avatar

Thanks BM for reading and describing the example I provided above. Note that one of the timers used must be independent of the system clock and that is why the the watchdog timer is used.

May 05, 2015
by BobaMosfet
BobaMosfet's Avatar

Noter,

I didn't read and describe your example. Neither timer has to be independent of system clock. I was describing how most frequency counters are done, whether in hardware or software.

You need to stop thinking so highly of yourself.

BM

May 05, 2015
by BobaMosfet
BobaMosfet's Avatar

Noter,

But I do like your idea of using the watchdog timer. No averaging should be required using it. Because of the fact that you can also calibrate it more accurately than as shipped, it should be very accurate.

BM

May 05, 2015
by Noter
Noter's Avatar

BM,

Maybe you didn't read it but you described almost exactly my previous example so it's not unreasonable for anyone to think you did read it first. Anyway, I don't think you can do it onchip without using the watchdog timer.

As for your personal comment towards me, it's not that I think so highly of myself rather I just think poorly of you. Buck up, post a working example if you can.

While you're at it, show us how to calibrate the watchdog timer.

May 05, 2015
by BobaMosfet
BobaMosfet's Avatar

Noter,

It doesn't really matter if you think I restated your statement, you chose to make a sarcastic remark solely because it was me, and for no other actual reason. Not for the first time. Hence, it is indeed that you think highly of yourself, because you are always being sarcastic with me, and I rarely if ever say anything unkind towards you. Instead of proving my point again, the next time you wish to say anything to me, I refer you to the TOS on the posting screen, Item #1 which reads:

Be nice! NerdKits is a place where beginners should feel free to ask
questions. If you don't have anything constructive to add to a thread,
don't add anything at all.

As for calibrating the watchdog timer (which runs off the Calibrated Internal RC Oscillator), per the datasheet:

"8.6 Calibrated Internal RC Oscillator By default, the Internal RC OScillator provides an approximate 8.0 MHz clock. Though voltage and temperature dependent, this clock can be very accurately calibrated by the user. The device is shipped with the CKDIV8 Fuse programmed. See “System Clock Prescaler” on page 37 for more details."

Calibration options are available through the Atmel Flash Programmer GUI, also.

BM

Post a Reply

Please log in to post a reply.

Did you know that you can build a circuit to convert the "dit" and "dah" of Morse code back into letters automatically? Learn more...