How to generate 32.768 kHz clock signal?

Hello,

I’m using a MAX30003 electrocardiogram chip and it requires me to input a 32.768 kHz clock signal into its FCLK pin. How can I generate such a signal using mbed (maybe using the PWM functions)? I’m using the nucleo-l152re board.
I found many guides on how to generate such a signal using an Arduino, so I’m assuming that the stm32 chip is more than capable of doing the same.

Thanks in advance!

You should be able to use a PwmOut with a period of 1/32768.0f seconds and a duty cycle of 0.5. The exact accuracy of this depends on your specific chip though.

Thanks for the reply!

I think the PWM functions only has a resolution down to 1 microsecond. If I input 1/32768 = 0.00003051 seconds = 3.051 microsecond, it would truncate everything after the decimal point and result in 3 microsecond period.

I heard that you can directly output a clock signal on the MCO pin of the STM32 from some internet discussions. How can I generate the clock this way?

Hello Richard,

Seems you have to use a hardware timer and call HAL functions to generate the clock signal rather than Mbed. I would recommend to build the project in STM32Cube IDE first. If you plan to move it to Mbed (in order to use some Mbed APIs too) you should configure the clock settings as specified in the Mbed file mbed-os/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/system_clock.c file. Also avoid using the timer TIMER5 which is already used by Mbed for the us_ticker (check in sys/mbed-os/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/us_ticker_data.h). You can find an example of generating clock signal with STM32Cube IDE here and porting to Mbed here.

Edit:

I think the PWM functions only has a resolution down to 1 microsecond. If I input 1/32768 = 0.00003051 seconds = 3.051 microsecond, it would truncate everything after the decimal point and result in 3 microsecond period.

There is a typo in your reasoning:
0.00003051 seconds = 30.51 microseconds (not 3.051 microseconds)

Best regards, Zoltan

1 Like

a simple method is to use the MCO, Master Clock Output. This output can be configured to route some internal clock to the MCO pin PA_8. The board has a 32 kHz crystal for RTC and you can activate the output with

HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_LSE, RCC_MCODIV_1);

somewhere in your code.
LSE is enabled when you use ThisThread::sleep_for or RTC in your program, otherwise it must be enabled with a few lines of code.
If its not working, then it may be a problem in the Mbed initialisation, I’ve just opened an issue for that.

1 Like

Thanks for the responses!
I got a test project set up in STM32CubeIDE and managed to use the HAL_RCC_MCOConfig function to output a 32.768kHz clock on the MCO pin. I’ll keep you all updated if I managed to get this working within mbed OS.

Hello again!
I added the HAL_RCC_MCOConfig line into a simple mbed test program, as follows:

#include <mbed.h>

DigitalOut LD1(LED1);
UnbufferedSerial pc(USBTX, USBRX);

char buf[] = {"Hello, mbed OS!\r\n"};

int main(){
	pc.baud(9600);
	HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_LSE, RCC_MCODIV_1);

	while(1){
		LD1 = !LD1;
		pc.write(buf, sizeof(buf));
		thread_sleep_for(1000);
	}
}

And my board did output a 32.768kHz clock on the MCO pin. However, it only outputs the clock in short bursts (about 1 burst per second, shown in the attached oscilloscope image), instead of continuously. Perhaps this is caused by some inner mbed OS mechanism (maybe certain clocks are turned off when the OS is idle)? How can I fix this?

Thank you all so much!

I guess the deep sleep is causing this, you can try to disable it by adding this as the first call in main():

sleep_manager_lock_deep_sleep();
1 Like

Yup, that solved the problem! Thanks.