My oscilloscope is not measuring the frequency of my wave accurately

I bought an oscilloscope from Amazon it is Hantek DSO5102P (Digital, 2 Channel, 100 MHz, 1 GSa/s)

I am trying to test it, I have an MSP430FR6989 development board (MSP-EXP430FR6989) and programmed it to toggle a pin (P4.7) every 0.5 ms to give me a square wave of period = 1 ms (f = 1 kHz).

This is the code for reference

#include <msp430.h>

#define ONE_MS  25;
#define ONE_SEC 25000;

#define ENABLE_PINS 0xFFFE

int main(void)
{
WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
PM5CTL0 = ENABLE_PINS;

//init Timer
TA0CTL |= TASSEL__ACLK;

TA0CCR0 = ONE_MS;
//Taclk = .02ms faclk = 50Khz
//count = 0.5 ms/.02 ms = 25
//count = 1 sec / .02 ms = 25000

TA0CTL |= MC__UP;//count till TA0CCR0

P4DIR |= BIT7;//P4.7 output
P4OUT |= BIT7;

while(1)
{
if((TA0CTL & TAIFG) == 1)//if flag is set
{
P4OUT ^= BIT7;//toggle P4.7 every 0.5ms or 0.5s
TA0CTL &= (~TAIFG);//clear the flag
}
}

return 0;
}


I probed the pin with reference to ground and pressed the AUTOSET button, it gave me a square wave of period = 1.39 ms (f = 720 Hz).

EDIT1

I checked the compensation of my probe, I connected the probe's lead to the PROBE COMP ~5 V @ 1 kHz connector and the reference lead to the PROBE COMP Ground connector and got this waveform.

END OF EDIT1

Is that normal for oscilloscopes?

The community's help is very much appreciated.

• Connect the tone to a speaker and compare its pitch with some musical instrument - or search Youtube for "1 kHz tone". Until you know your software is actually generating the right frequency you don't know the scope is wrong. – Brian Drummond Mar 17 '20 at 11:26
• @BrianDrummond, I calculated the necessary timer count to give me a 1ms square wave the MSP430's Timer A0 Clock Source was from the Auxiliary Clock (ACLK) which had a frequency of 50Khz (Taclk = 0.02 ms). t = count*Taclk, if t = 0.5 ms then count = 0.5 / 0.02 = 25. Every 0.5 ms the pin is toggled and this will give me a square wave with a period of 1 ms. – Forat Mar 17 '20 at 11:36
• Most oscilloscopes have a probe calibration (square wave) output and I would expect yours to be no exception. Have you measured that? – Peter Smith Mar 17 '20 at 11:37
• So there’s absolutely zero possibility that you made a mistake in your code. Yes, it must be that the oscilloscope designers made the most basic mistake possible! I wish I had that much confidence in anything I do. Sorry pal, chances that you didn’t make a mistake and the oscilloscope designers did is 1 in a million at the very least. – swineone Mar 17 '20 at 11:47
• From the documentation (section 2.5 of the development board user guide), ACLK is derived from the 32.768kHz oscillator at power up and will remain on that unless you change it via the ASEL bits in the CS register set (after writing the correct password). See section 3.3. of the microcontroller user guide. I do not see any of that in your code. – Peter Smith Mar 17 '20 at 12:48

The MSP430FR58xx, MSP430FR59xx, and MSP430FR6xx Family User's Guide says in section 3.2 that

the CS module default configuration is:

• LFXT is selected as the oscillator source for LFXTCLK. LFXTCLK is selected for ACLK (SELAx = 0) and ACLK is undivided (DIVAx = 0).

and in 3.2.2:

At power up, the LFXT clock defaults to "on" and is the source for ACLK. However, at power-up the LFXT pins default to general-purpose I/O mode, therefore, the LFXT clock remains disabled until the pins associated with LFXT are configured for LFXT operation.

3.2.8 says:

If LFXT is sourcing any system clock (ACLK, MCLK, or SMCLK) and a fault is detected, the system clock is automatically switched to LFMODCLK for its clock source.

3.1 says:

• MODCLK: Internal low-power oscillator with 5-MHz typical frequency. LFMODCLK is MODCLK divided by 128.

If the MODCLK were perfectly accurate, 5 MHz / 128 / 25 / 2 = 781.25 Hz.

The MSP430FR6989 datasheet says in table 5-25 that the MODCLK frequency can be anywhere between 4 MHz and 5.4 MHz. So the LFMODCLK frequency can be anywhere between 31.25 kHz and 42.19 kHz, so your PWM signal can be between 625 Hz and 844 Hz.

If you want to source ACLK from the 32.768 kHz crystal, you have to initialize the pin and the oscillator correctly (it's more complex than setting a few register bits; see the TI code examples).

If you want to use the DCO as clock source, you have to use SMCLK instead of ACLK.

• This is the route I was going down, but I got interrupted. +1 for a detailed trace of what is going on here. – Arsenal Mar 18 '20 at 10:20

The community's help is very much appreciated.

The time-base setting (orange box added by me) is 400 us. I've also over-laid vertical red lines on your screen shot. Each red line highlights the graticule shown in your screen shot. I've changed colours to make things clearer.

I count about 3.5 x 400 us graticules (orange arrow) and this is a total period of 1400 us. That is a frequency of 714 Hz.

My oscilloscope is not measuring the frequency of my wave accurately

I bet it is.

• My money is on the scope, too – Scott Seidman Mar 17 '20 at 12:12
• I dd a bit of digging - see my latest comment (my money is on the scope being correct as well). – Peter Smith Mar 17 '20 at 12:51

Now being a little more productive than I was in my comment, and trying to solve your X problem rather than the Y problem you asked about (see XY problem), there's almost certainly an error either in your calculation of the timer constants, or in your initialization of the MCU's clock. Since I haven't used the MSP430 in ages I can't help you with that.

However, to help you start off your debugging session, I see that there's a 4 MHz oscillator in the board, as well as an internal oscillator with 10 different frequencies (1 MHz, 2.667 MHz, 3.5 MHz, 4 MHz, 5.333 MHz, ..., 21 MHz and 24 MHz). If the program shown is your complete program, then it doesn't look like any clock initializations were performed. Have a look at the MCU's reference manual and see how the clock is initialized by default. Probably the frequency is different from what you're expecting; maybe you assumed the 4 MHz external oscillator would be automatically used, while by default the MCU uses one of the frequencies above. Certainly, in the STM32 which I'm familiar with, you need to run some initialization code to use the external oscillator, since at bootup only the internal oscillator is configured.

Just so you know, that's not an unusual error. Often I've had frequency errors in my STM32 projects when I forgot to change a certain constant, HSE_VALUE, to match the 8 MHz crystal in my boards from the default of 25 MHz in ST's supplied code.

Which clock path did you intend to select? These modern MCUs have a zillion options.

I believe that this is the default path (in red).

32768/25 = 1310 Hz

Toggling at 1310 Hz yields 655 Hz. Not exactly what you are seeing, but you get the idea. You need to verify that every mux and divider is set appropriately along the intended path.

Edit: I have a MSP430FR5994 (similar to your MCU, they share the same user's guide) running on my bench, so I can easily test your software. I get 722 Hz. I know that if you use an interrupt, the count is exact. You are polling, which could still work depending on how you poll and clear. I don't see the minor discrepancy yet.

Also, if you are going to use the LF oscillator, check to see if Q1 is installed. The schematic leads me to believe that it is optional, but TI sometimes changes little details from rev to rev.

http://www.ti.com/lit/ug/slau367o/slau367o.pdf - figure 3-1

Edit2: Thanks to the tip from CL, I finally have something working. It doesn't do what you expect, since it uses LFXT. Depending on how accurate you need 5 mS, you may not be able to use LFXT.

It produces 32786/25/2 = 655 Hz.

If you are trying something new, always start with a known good code example. TI is a usually a good source, but I have found issues with their code examples.

#define ENABLE_PINS 0xFFFE
int main(void)

{

WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
PM5CTL0 = ENABLE_PINS;

PJSEL0 |= BIT4 | BIT5;      // Set shared IO to use 32.678 kHz XTAL

// Startup clock system with max DCO setting ~8MHz
CSCTL0_H = CSKEY_H;                     // Unlock CS registers
CSCTL1 = DCOFSEL_3 | DCORSEL;           // Set DCO to 8MHz
CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;   // CLKA = LFXT; SMCLK & MCLK = DCO
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;   // Set all dividers to 1
CSCTL4 &= ~( LFXTOFF );                 // Enable LFXT

// Wait until oscillators settle down
do
{
CSCTL5 &= ~(LFXTOFFG );             // Clear LFXT fault flag
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG);              // Test oscillator fault flag

CSCTL0_H = 0;                           // Lock CS registers

//init Timer
TA0CTL |= TASSEL__ACLK;

TA0CCR0 = 24;                    // Set to 1 less than the period than you desire

TA0CTL |= MC__UP;     //count till TA0CCR0

P4DIR |= BIT7;    //P4.7 output
P4OUT |= BIT7;

TA0R = 0;                                // Reset timer A
TA0CCTL0 = CCIE;                         // TACCR0 interrupt enabled

while(1)
{
if((TA0CTL & TAIFG) == 1)   //if flag is set
{
P4OUT ^= BIT7;          //toggle P4.7
TA0CTL &= (~TAIFG);     //clear the flag
}
}

return 0;

• I think you nailed it. On the STM32, the internal 40 (?) kHz low-frequency oscillator can actually vary from 30 to 60 kHz. So, getting 719 Hz out of a nominal 655 Hz looks like a very promising explanation to what the OP is seeing. – swineone Mar 17 '20 at 12:47
• Upon reading the datasheet and evaluation board's manual, I'm a bit more confused. LFXT is meant to be an external crystal, and looking at the board's manual, none seems to be connected. In that case, the manual says ACLK's source should be "LFXTCLK when LFXT available, otherwise VLOCLK." So it's supposed to be VLOCLK, yet the datasheet claims VLO's frequency is 6 to 14 kHz with a nominal 9.4 kHz, and in this case the calculations wouldn't work out. Still, I'm sure we're on the right track. – swineone Mar 17 '20 at 12:54
• Often, we have to load counters with a value that is not the actual divider (divider +/-1 or +/-2 is common). If this device (no, I have not delved into it yet) counter actually does loaded count - 2 it gets really close to what the OP is seeing from the 32.768kHz clock. – Peter Smith Mar 17 '20 at 14:22
• @PeterSmith - from experience I know that the count is exact for this MCU, if you use an interrupt. The OP is polling, so that could be the difference. – Mattman944 Mar 17 '20 at 15:40
• Actually it looks like the answer by @CL. is the correct one. – swineone Mar 17 '20 at 16:54