2012-08-22 08:22 AM
Hi
The objective is to create avariable frequency
pulse train with as little CPU intervention as possible. This was quite straightforward with the TMS320 TI MCU. It had a feature called ''PWM chopper'' where it was possible to configure frequency, pulse width, duty cycle and number of pulses. To achieve the same kind of functionality with the STM32F4, the idea that first came to mind was to use the Advanced Control Timer & DMA peripheral. A table which consists of the timer periods that define the pulse train characteristics is setup in RAM. The have the DMA transfer these values to the timer compare register using memory increment mode. The timer output pin is configured to toggle at every compare match. Also, it is desired to have control of the time interval between each consecutive pulse train. Therefore a timer capture/compare interrupt is enabled. In the interrupt, the pulse train starting time (first positive flank) is defined as: Current time (time when the interrupt occurs) + A settable delay The time when the next interrupt occurs is also settable. The questions are: 1) Is the method described above possible with the STM32F4? 2) Are there any other ways to get the same result?2014-03-12 07:42 PM
if u are familiar with working of USART, can u help me?
If you want help with USART code, please start a new thread, and state the issue2014-03-23 10:28 PM
Dear Joseph,
Sorry for late reply as my board got spoiled so I am busy to make it up . Yes I am familiar with USART and I can help you .2014-08-28 06:59 PM
I am using timer1 channel 1 as output compare, to generate a pulse of variable period.
The output mode is set to toggle mode and the polarity is set to active high. T
he capture register is set to delay period and then in next capture register set to first period and next period will be updated after the one pulse is completed.
I is correct expected output. II is wrong in this case the wrong ramp profile and driver consider wrong first step .As driver considers first rising edge as first step2014-08-28 07:20 PM
The use of DMA would depend on what frequency you want to generate and how practical it is to interrupt.
With toggle mode you get to control where the edge transitions are placed with respect to the time base of the counter, if you want a longer lead in, then push out the edge further.2014-09-08 09:29 AM
2015-03-17 01:13 AM
Hello Clif
Thanks for you job, has been the better help for my. In the using this code, I had a problem. I need recharge a table with values. These values range from 0 degrees to 90 degrees . The following interruption values are 90 to 180 are loaded and so on. . I do not work.If I leave the same table if the recharge bienpero if no alternative. Each table has 19 values ranging from 0-5000 us and complete the following period until the 10000 usg.I need help thanks in advance2015-03-17 02:22 AM
Hello,
Just a remark, as I noticed this thread is still active. There is now a STM32 (the STM32F334) with a built-in chopper mode for PWM, in the High-Resolution Timer (HRTIM). Best regards, Vincent2015-03-17 07:40 AM
Hello Clif
Thanks for you job, has been the better help for my. In the using this code, I had a problem. I need recharge a table with values. These values range from 0 degrees to 90 degrees . The following interruption values are 90 to 180 are loaded and so on. . I do not work. If I leave the same table if the recharge bienpero if no alternative. Each table has 19 values ranging from 0-5000 us and complete the following period until the 10000 usg.
I need help thanks in advanceClive!You'll need to modify the length of the DMA transfer to the portion of the phase you want to supply data for. You can also use the HT (Half Transfer) and TC (Terminal Count) interrupts of the DMA to split the buffer in half and allow you to build the next table of data while the current one is being dispatched.
2015-03-18 04:54 AM
Sorry Clive,
The spellchecker playing tricks on me. It's the price you pay for not knowing English well. The DMA is well sized and interrupt each half. From serious table ideal, I do not know how. Could you give me an example. Anyway you step the code that I modified.uint16_t SRC_Buffer [SPWM_ELEMENTS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint16_t Tabla_Buffer [5][DISPAROS] = {
{270 , 319 , 539 , 591 , 829 , 898 , 1159 , 1239 , 1504 , 1593 , 1855 , 1951 , 2210 , 2310 , 2565 , 2669 , 2922 , 3028 , 3280 }, // K = 0.3
{251 , 316 , 523 , 594 , 816 , 908 , 1145 , 1252 , 1488 , 1607 , 1838 , 1965 , 2192 , 2325 , 2547 , 2685 , 2904 , 3045 , 3262 }, // K = 0.4
{233 , 314 , 508 , 599 , 803 , 918 , 1130 , 1264 , 1472 , 1620 , 1821 , 1980 , 2174 , 2341 , 2529 , 2702 , 2886 , 3062 , 3244 }, // K = 0.5
{216 , 314 , 495 , 606 , 791 , 929 , 1116 , 1276 , 1456 , 1633 , 1803 , 1993 , 2155 , 2355 , 2510 , 2718 , 2867 , 3079 , 3226 }, // K = 0.6
{199 , 314 , 481 , 613 , 779 , 940 , 1102 , 1287 , 1439 , 1645 , 1784 , 2006 , 2135 , 2369 , 2489 , 2733 , 2847 , 3096 , 3208 } // K = 0.7
};
void TIM1_CC_IRQHandler(void)
{
static bool semiciclo;
/* check if the TIM1_CC4 interrupt has occurred */
if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET)
{
/* clear the TIM1_CC4 interrupt pending bits */
TIM_ClearITPendingBit(TIM1, TIM_IT_CC4);
}
TIM1->CNT = 0; /* Reset the counter back to zero */
/* Set up data for DMA-transfer */
semiciclo = !semiciclo;
if (semiciclo)
{
TIM1->CCR1 = SRC_Buffer[0] = Tabla_Buffer [Tabla][0];
SRC_Buffer[1] = Tabla_Buffer [Tabla][1];
SRC_Buffer[2] = Tabla_Buffer [Tabla][2];
SRC_Buffer[3] = Tabla_Buffer [Tabla][3];
SRC_Buffer[4] = Tabla_Buffer [Tabla][4];
SRC_Buffer[5] = Tabla_Buffer [Tabla][5];
SRC_Buffer[6] = Tabla_Buffer [Tabla][6];
SRC_Buffer[7] = Tabla_Buffer [Tabla][7];
SRC_Buffer[8] = Tabla_Buffer [Tabla][8];
SRC_Buffer[9] = Tabla_Buffer [Tabla][9];
SRC_Buffer[10] = Tabla_Buffer [Tabla][10];
SRC_Buffer[11] = Tabla_Buffer [Tabla][11];
SRC_Buffer[12] = Tabla_Buffer [Tabla][12];
SRC_Buffer[13] = Tabla_Buffer [Tabla][13];
SRC_Buffer[14] = Tabla_Buffer [Tabla][14];
SRC_Buffer[15] = Tabla_Buffer [Tabla][15];
SRC_Buffer[16] = Tabla_Buffer [Tabla][16];
SRC_Buffer[17] = Tabla_Buffer [Tabla][17];
SRC_Buffer[18] = Tabla_Buffer [Tabla][18]; //(5000 + (5000 - Tabla_Buffer [Tabla][18]));/*Pulso central entre 60º y 120º */;
GPIO_WriteBit(GPIOE,GPIO_Pin_9,Bit_SET);
}
else
{
TIM1->CCR1 = SRC_Buffer[0] = (5000 - Tabla_Buffer [Tabla][18]);
SRC_Buffer[1] = (5000 - Tabla_Buffer [Tabla][17]);
SRC_Buffer[2] = (5000 - Tabla_Buffer [Tabla][16]);
SRC_Buffer[3] = (5000 - Tabla_Buffer [Tabla][15]);
SRC_Buffer[4] = (5000 - Tabla_Buffer [Tabla][14]);
SRC_Buffer[5] = (5000 - Tabla_Buffer [Tabla][13]);
SRC_Buffer[6] = (5000 - Tabla_Buffer [Tabla][12]);
SRC_Buffer[7] = (5000 - Tabla_Buffer [Tabla][11]);
SRC_Buffer[8] = (5000 - Tabla_Buffer [Tabla][10]);
SRC_Buffer[9] = (5000 - Tabla_Buffer [Tabla][9]);
SRC_Buffer[10] = (5000 - Tabla_Buffer [Tabla][8]);
SRC_Buffer[11] = (5000 - Tabla_Buffer [Tabla][7]);
SRC_Buffer[12] = (5000 - Tabla_Buffer [Tabla][6]);
SRC_Buffer[13] = (5000 - Tabla_Buffer [Tabla][5]);
SRC_Buffer[14] = (5000 - Tabla_Buffer [Tabla][4]);
SRC_Buffer[15] = (5000 - Tabla_Buffer [Tabla][3]);
SRC_Buffer[16] = (5000 - Tabla_Buffer [Tabla][2]);
SRC_Buffer[17] = (5000 - Tabla_Buffer [Tabla][1]);
SRC_Buffer[18] = (5000 - Tabla_Buffer [Tabla][0]);
GPIO_WriteBit(GPIOE,GPIO_Pin_9,Bit_RESET);
}
/* Next interrupt to occur after 5 ms */
TIM1->CCR4 = 5000;
}
Need guidance on HT (Half Transfer) and TC (Terminal Count) may be the solution.
Very grateful for your prompt reply. I hope your coments.
DMA_InitStructure.DMA_Channel = DMA_Channel_6;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(TIM1_CCR1_ADDRESS);
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)SRC_Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = SPWM_ELEMENTS; // Nº data items to transfer
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream1, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream1, ENABLE); // enable DMA2_Stream1
2015-03-21 01:41 PM
Hi Clive1
I found Looking forDMA_ITConfig (DMAx_Channelx, DMA_IT_TC | DMA_IT_HT | DMA_IT_TE, DISABLE);
I guess you meant this.
I do not see how to use it for my program.