cancel
Showing results for 
Search instead for 
Did you mean: 

generate one 10-microsecond pulse followed by fifteen 2-microsecond pulses

okeycii
Visitor

Hi,

I want to generate a timeslot control signal consisting of one 10-microsecond pulse followed by fifteen 2-microsecond pulses.
I want the period to remain constant, aligned on the falling edge.
My problem is that before and after the long pulse, the period changes, and I don’t know how to fix it.

I have:

okeycii_0-1746110947051.jpeg

instead of:

okeycii_1-1746110991550.jpeg

 

I use two methods and i am not able to make both of them work.

Here is my code:

Method 1 : Timer1 16 in PWM mode 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if( htim->Instance == TIM16)
		{
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
			else
			{
				if(htim->Instance->RCR>0)
				{
					htim->Instance->RCR=0;
					htim->Instance->CCR1=g_TSC_Long_Low_Pulse_Duration-1;
				}
				else
				{
					htim->Instance->RCR=(g_TSC_Max_TimeSlotsToRun-1)-1;
					htim->Instance->CCR1=g_TSC_Short_Low_Pulse_Duration-1;
				}
			}
		}
}

 

Method 2: time base (Tim 6)

typedef enum {
    PULSE_LOW,
    PULSE_HIGH
} PulseState;

PulseState pulse_state = PULSE_LOW;
uint8_t ts_counter = 0;
bool is_long_pulse_done = false;


g_TSC_Full_Signal_Period = (uint32_t)((double) (1/((TS_ACQ_RATE_HERTZ) / HAL_RCC_GetSysClockFreq()) ));

	g_TSC_Short_Low_Pulse_Duration = (uint32_t)((double) (TS_SHORT_PULSE_DURATION_S * HAL_RCC_GetSysClockFreq()) );
	g_TSC_Short_High_Pulse_Duration = g_TSC_Full_Signal_Period - g_TSC_Short_Low_Pulse_Duration;

	g_TSC_Long_Low_Pulse_Duration = (uint32_t)((double) (TS_LONG_PULSE_DURATION_S * HAL_RCC_GetSysClockFreq()) );
	g_TSC_Long_High_Pulse_Duration = g_TSC_Full_Signal_Period - g_TSC_Long_Low_Pulse_Duration;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance == TIM6)
	{
	    switch (pulse_state)
	    {
	        case PULSE_LOW:
	            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);

	            if (!is_long_pulse_done)
	                __HAL_TIM_SET_AUTORELOAD(htim, g_TSC_Long_Low_Pulse_Duration-1);  // long LOW
	            else
	                __HAL_TIM_SET_AUTORELOAD(htim, g_TSC_Short_Low_Pulse_Duration-1);   // short LOW

	            pulse_state = PULSE_HIGH;
	            break;

	        case PULSE_HIGH:
	            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);

	            if (!is_long_pulse_done)
	            {
	                __HAL_TIM_SET_AUTORELOAD(htim, g_TSC_Long_High_Pulse_Duration-1);  // long HIGH
	                is_long_pulse_done = true;
	                ts_counter = 0;
	            }
	            else
	            {
	                __HAL_TIM_SET_AUTORELOAD(htim, g_TSC_Short_High_Pulse_Duration-1);  // short HIGH
	                ts_counter++;

	                if (ts_counter >= 15){
	                    is_long_pulse_done = false;
	                }
	            }
}

for the second method i have an extra problem, i can not have a pulse with less then 3 micro second width

Can somebody help me please?

5 REPLIES 5

You want the Period to be the same, but don't state WHAT it is.

Perhaps you can use PMW Mode 2, and modulate the width of the LOW portion?

Other alternative for patterns are TIM+DMA+GPIO->BSRR

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

i want a period of 25 microsecond.

If i modulate the low portion, all my pulses would have the same width and i do not want that to happen.

Can you explain more what you mean by TIM+DMA+GPIO->BSRR


@okeycii wrote:

If i modulate the low portion, all my pulses would have the same width and i do not want that to happen.


Would they?

If the period is fixed, and you modulate the low portion, then that means the high portion has to change - ie, your pulse widths do change!

QEF ?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
TDK
Guru

Set up the channel to toggle on match, leave the pulse value at 0 and set up the ARR field to be the duration of the high time, low time, high time, low time, etc...

{10, 25, 2, 25, 2, 25, ...}

If you feel a post has answered your question, please click "Accept as Solution".

It shouldn't be hard to maintain the period, if you change the duty of the space, the mark is tied to it,  no?

As TDK mentions Toggle Mode would also work, you'd need to ensure the polarity

You could use a TIM at a high rate to trigger a Memory-to-Memory DMA operation, moving patterns from a buffer to GPIO pins. The GPIO Banks are each 16-pins wide, the BSRR allows a single write pattern to make individual or groups of pins in pin SET or RESET. The BSRR is 32-bit wide, review in the Reference Manual. The DMA sequence length can be used in a circular mode to keep repeating the pattern.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..