XMC 4700 simple single shot timer for delay funtion

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User18316
Level 1
Level 1
Hello people!

I'm sorry to ask such a stupid question, but I'm stuck. 😞
I would like to create a simple delay function (without Dave).

Does anyone have a simple example with a single shot timer?
It doesn't have to do much just run for 500ms and count to 0.

Regards,
Stefan
0 Likes
2 Replies
User16529
Level 4
Level 4
First solution authored
See if the time.h library works.
You can try


clock_t start;
clock_t end;
int elapsed_time
start = clock();
elapsed_time = start * 1000 / CLOCKS_PER_SEC;

while(elapsed_time != 500)
{
end = clock() - start;
elapsed_time = end * 1000 / CLOCKS_PER_SEC;
}


I don't know if it could work, try it.
0 Likes
User18316
Level 1
Level 1
This is my (dirty) way of doing it.

delay.h FIle


#include
#include
#include
#include

#define SLICE_PTR CCU40_CC40
#define MODULE_PTR CCU40
#define MODULE_NUMBER (0U)
#define SLICE_NUMBER (0U)

void delayMilliseconds(uint16_t MilliSeconds);



delay.c File

#include "delay.h"

bool _isInit = false;

XMC_CCU4_SLICE_COMPARE_CONFIG_t SLICE0_config =
{
.timer_mode = (uint32_t) XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA,
.monoshot = (uint32_t) true,
.shadow_xfer_clear = (uint32_t) 0,
.dither_timer_period = (uint32_t) 0,
.dither_duty_cycle = (uint32_t) 0,
.prescaler_mode = (uint32_t) XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
.mcm_enable = (uint32_t) 0,
.prescaler_initval = XMC_CCU4_SLICE_PRESCALER_32768, /* in this case, prescaler = 2^10 */
.float_limit = (uint32_t) 0,
.dither_limit = (uint32_t) 0,
.passive_level = (uint32_t) XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.timer_concatenation = (uint32_t) 0
};



void initTimer()
{
/* Ensure fCCU reaches CCU40 */
XMC_CCU4_SetModuleClock(MODULE_PTR, XMC_CCU4_CLOCK_SCU);

XMC_CCU4_Init(MODULE_PTR, XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR);

/* Get the slice out of idle mode */
XMC_CCU4_EnableClock(MODULE_PTR, SLICE_NUMBER);

/* Start the prescaler and restore clocks to slices */
XMC_CCU4_StartPrescaler(MODULE_PTR);

/* Initialize the Slice */
XMC_CCU4_SLICE_CompareInit(SLICE_PTR, &SLICE0_config);

/* Program a very large value into Period Match register*/
XMC_CCU4_SLICE_SetTimerPeriodMatch(SLICE_PTR, 0xffff);
XMC_CCU4_SLICE_SetTimerCompareMatch(SLICE_PTR, 0);

/* Enable shadow transfer */
XMC_CCU4_EnableShadowTransfer(MODULE_PTR, XMC_CCU4_SHADOW_TRANSFER_SLICE_0);

/* Start timer*/
XMC_CCU4_SLICE_StopTimer(SLICE_PTR);
//XMC_CCU4_SLICE_StartTimer(SLICE_PTR);
_isInit = true;

}

void delayMilliseconds(uint16_t MilliSeconds)
{
uint16_t Ticks = 0;
Ticks = (double)MilliSeconds / 1000 * SystemCoreClock / (double)32768;

if(!_isInit)
initTimer();

XMC_CCU4_SLICE_ClearTimer(SLICE_PTR);
XMC_CCU4_SLICE_SetTimerPeriodMatch(SLICE_PTR, Ticks);
XMC_CCU4_SLICE_SetTimerCompareMatch(SLICE_PTR, 0);

/* Enable shadow transfer */
XMC_CCU4_EnableShadowTransfer(MODULE_PTR, XMC_CCU4_SHADOW_TRANSFER_SLICE_0);
XMC_CCU4_SLICE_StartTimer(SLICE_PTR);

while(XMC_CCU4_SLICE_IsTimerRunning(SLICE_PTR))
{}

}
0 Likes