[FM33LG0 series development board review] 04.PWM, RTC
[Copy link]
1. Introduction
PWM (Pulse Width Modulation) is the abbreviation of pulse width modulation. We can use GPIO plus delay to achieve it, or we can use the PWM function of the TIM timer to achieve waveform output with different periods and different duty cycles.
RTC (Real Time Clock) is a real-time clock. The FM33LG0 series chips have two RTC peripherals, namely RTCA and RTCB. RTCB can only use an external clock crystal to output a fixed 1Hz frequency for RTC timing. RTCA can choose different clock sources: XTLF or RCLP, and can be configured to generate periodic interrupts of different frequencies ( 1KHz , 256Hz , 64Hz , 16Hz , 4Hz , 1Hz). However, no matter whether it is RTCA or RTCB, after digital adjustment, the accuracy can reach +/-0.477ppm. And it is BCD time, with a complete perpetual calendar function, which is very convenient to use.
2. Function Implementation
Use the TIM_CH3 channel of the LPTIM16 timer, that is, the PC13 pin, to output a waveform with a frequency of 1KHz and a duty cycle of 50%; use the RTCB time to initialize the configuration and print out the current RTCB running date and time every 1 second;
3. Code implementation
LPTIM16 PWM
/*******************************************************************************
* [url=home.php?mod=space&uid=159083]@brief[/url] * @param
* @retval
* [url=home.php?mod=space&uid=1020061]@attention[/url] *******************************************************************************/
void LPTIM16_Init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
FL_LPTIM16_InitTypeDef LPTIM16_InitStruct;
FL_LPTIM16_OC_InitTypeDef LPTIM16_OC_InitStruct;
FL_LPTIM16_StructInit(&LPTIM16_InitStruct);
LPTIM16_InitStruct.clockSource = FL_CMU_LPTIM16_CLK_SOURCE_APBCLK;
LPTIM16_InitStruct.mode = FL_LPTIM16_OPERATION_MODE_NORMAL;
LPTIM16_InitStruct.prescalerClockSource = FL_LPTIM16_CLK_SOURCE_INTERNAL;
LPTIM16_InitStruct.prescaler = FL_LPTIM16_PSC_DIV8;
LPTIM16_InitStruct.autoReload = 1000 - 1;
LPTIM16_InitStruct.encoderMode = FL_LPTIM16_ENCODER_MODE_DISABLE;
LPTIM16_InitStruct.onePulseMode = FL_LPTIM16_ONE_PULSE_MODE_CONTINUOUS;
LPTIM16_InitStruct.triggerEdge = FL_LPTIM16_ETR_TRIGGER_EDGE_RISING;
LPTIM16_InitStruct.countEdge = FL_LPTIM16_ETR_COUNT_EDGE_RISING;
FL_LPTIM16_Init(LPTIM16, &LPTIM16_InitStruct);
FL_GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.pin = FL_GPIO_PIN_13;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_ENABLE;
FL_GPIO_Init(GPIOC, &GPIO_InitStruct);
LPTIM16_OC_InitStruct.OCPolarity = FL_LPTIM16_OC_POLARITY_NORMAL;
LPTIM16_OC_InitStruct.compareValue = 500 - 1;
FL_LPTIM16_OC_Init(LPTIM16, FL_LPTIM16_CHANNEL_1, &LPTIM16_OC_InitStruct);
FL_LPTIM16_Enable(LPTIM16);
}
RTCB: It should be noted that the RTC configuration and read values are expressed in BCD code, so when obtaining the date and time, the BCD code needs to be converted into hexadecimal numbers when printing the date and time; when setting the date and time, it needs to be converted into BCD code before setting;
When configuring the week, if you are not sure what day it is, you can set a value at random; after getting the date and time, it will automatically return the correct day of the week, NICE!!!
/*******************************************************************************
* @file RTC.c
* @author King
* [url=home.php?mod=space&uid=252314]@version[/url] V1.00
* [url=home.php?mod=space&uid=311857]@date[/url] 27-Nov-2021
* @brief ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#define __RTC_C__
/* Includes ------------------------------------------------------------------*/
#include "RTC.h"
#if RTC_ENABLE
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported function prototypes ----------------------------------------------*/
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
uint8_t RTC_HEXToBCD(uint8_t Data)
{
return (Data / 10) * 16 + (Data % 10);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
uint8_t RTC_BCDToHEX(uint8_t Data)
{
return (Data / 16) * 10 + (Data % 16);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void RTCB_Configure(void)
{
FL_RTCB_InitTypeDef RTCB_InitStruct = {0x21, 0x12, 0x12, 0x00, 0x19, 0x18, 0x25};
FL_RTCB_Init(RTCB, &RTCB_InitStruct);
FL_RTCB_Enable(RTCB);
NVIC_DisableIRQ(RTCx_IRQn);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void RTC_Configure(void)
{
RTCB_Configure();
TASK_Append(TASK_ID_RTC, RTC_Handler, 1000);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void RTC_Handler(void)
{
FL_RTCB_InitTypeDef RTCB_InitStruct;
FL_RTCB_GetTime(RTCB, &RTCB_InitStruct);
printf("\r\n20%02d-%02d-%02d",
RTC_BCDToHEX(RTCB_InitStruct.year ),
RTC_BCDToHEX(RTCB_InitStruct.month),
RTC_BCDToHEX(RTCB_InitStruct.day ));
switch(RTCB_InitStruct.week)
{
case 0 : printf(" SUN "); break;
case 1 : printf(" MON "); break;
case 2 : printf(" TUE "); break;
case 3 : printf(" WED "); break;
case 4 : printf(" THU "); break;
case 5 : printf(" FRI "); break;
case 6 : printf(" SAT "); break;
default:break;
}
printf("%02d:%02d:%02d",
RTC_BCDToHEX(RTCB_InitStruct.hour ),
RTC_BCDToHEX(RTCB_InitStruct.minute),
RTC_BCDToHEX(RTCB_InitStruct.second));
}
#endif
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
4. Operation results
When verifying the RTC function, you need to short-circuit VBAT and VCC on the development board to power the RTC peripherals of the MCU; use a logic analyzer to connect the PC13 pin header and GND on the development board to measure the frequency and duty cycle of the PWM output waveform. The results are shown in the figure below:
5. Project source code
Project_PWM_RTCB.zip
(359.1 KB, downloads: 13)
|