ผม ขน เล็บ ฟัน หนัง
Arduino for STM32
Everything relating to using STM32 boards with the Arduino IDE
Skip to content
Search…
Search Advanced search
Quick links
Unanswered topics
Active topics
Search
The team
FAQ
Login
Home Board index Arduino for STM32 Projects
Search
[SOLVED] 3 channel PWM generator using timer-triggered DMA
Post Reply
Print view
Search this topic…
Search Advanced search
40 posts
Previous
1
2
3
4
ted
Posts: 312
Joined: Sun Jul 16, 2017 9:57 pm
Re: STM32 Timers
Quote
Post by ted » Fri Jul 06, 2018 8:51 pm
This two lines are causing the problems.
Code: Select all
//timer_dma_enable_req(dev3, cc_channel3);//
Code: Select all
//ret = dma_tube_cfg(DMA1, DMA_CHX, &dma_cfg);
Top
User avatar
Rick Kimball
Posts: 1400
Joined: Tue Apr 28, 2015 1:26 am
Location: Eastern NC, US
Contact:
Contact Rick Kimball
Website
Re: STM32 Timers
Quote
Post by Rick Kimball » Fri Jul 06, 2018 9:01 pm
@stevestrong gave you the answer on which pins to use back here:
viewtopic.php?f=19&t=3820#p46900
#if 1
static const int WS281X_PIN = PB1;
#define DMA_REQ_SRC_TIMX_CHNX DMA_REQ_SRC_TIM3_CH4
#define TIMER_DMA_BASE_CCRX TIMER_DMA_BASE_CCR4
#define DMA_CHX DMA_CH3
#elif 0
static const int WS281X_PIN = PB7;
#define DMA_REQ_SRC_TIMX_CHNX DMA_REQ_SRC_TIM4_CH2
#define TIMER_DMA_BASE_CCRX TIMER_DMA_BASE_CCR2
#define DMA_CHX DMA_CH4
#elif 0
static const int WS281X_PIN = PA8;
#define DMA_REQ_SRC_TIMX_CHNX DMA_REQ_SRC_TIM1_CH1
#define TIMER_DMA_BASE_CCRX TIMER_DMA_BASE_CCR1
#define DMA_CHX DMA_CH2
#elif 0
static const int WS281X_PIN = PB0;
#define DMA_REQ_SRC_TIMX_CHNX DMA_REQ_SRC_TIM3_CH3
#define TIMER_DMA_BASE_CCRX TIMER_DMA_BASE_CCR3
#define DMA_CHX DMA_CH2
#endif
-rick
Top
ted
Posts: 312
Joined: Sun Jul 16, 2017 9:57 pm
Re: STM32 Timers
Quote
Post by ted » Fri Jul 06, 2018 10:32 pm
I changed to PB1, no conflicts and no signal on PB1.
Code: Select all
#define SAMPLES 100
#include
dma_tube_config dma_cfg, dma_cfg2, dma_cfg3;
/*
///////////////
// PB0 TIM3 CH3 uses DMA CH2
#define DMA_REQ_SRC_TIMX_CHX DMA_REQ_SRC_TIM3_CH3
#define TIMER_DMA_BASE_CCRX TIMER_DMA_BASE_CCR3
#define DMA_CHX DMA_CH2
/////////////////
*/
////////////////////////
//static const int WS281X_PIN = PB1;
#define DMA_REQ_SRC_TIMX_CHNX DMA_REQ_SRC_TIM3_CH4
#define TIMER_DMA_BASE_CCRX TIMER_DMA_BASE_CCR4
#define DMA_CHX DMA_CH3
////////////////////////
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int out1 = PB7;
int out2 = PA8;
int out3 = PB1;
int val1[SAMPLES];
int val2[SAMPLES];
int val3[SAMPLES];
int16 shift = 0;
int amp = 35;
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / SAMPLES;
int ret = 17;
timer_dev *dev1 = PIN_MAP[out1].timer_device;
timer_dev *dev2 = PIN_MAP[out2].timer_device;
uint8 cc_channel1 = PIN_MAP[out1].timer_channel;
uint8 cc_channel2 = PIN_MAP[out2].timer_channel;
///////////////////////////////
timer_dev *dev3 = PIN_MAP[out3].timer_device;
uint8 cc_channel3 = PIN_MAP[out3].timer_channel;
//////////////////////////
void fun()
{
flag1++;
}
void fun2()
{
flag2++;
}
void fun3()
{
flag3++;
}
void timer_conf()
{
//T4
timer_dma_set_base_addr(dev1, TIMER_DMA_BASE_CCR2);
timer_dma_set_burst_len(dev1, 1);
timer_dma_enable_req(dev1, cc_channel1);
timer_set_reload(dev1, 102);
timer_set_prescaler(dev1, 0);
//T2
timer_dma_set_base_addr(dev2, TIMER_DMA_BASE_CCR1);
timer_dma_set_burst_len(dev2, 1);
timer_dma_enable_req(dev2, cc_channel2);
timer_set_reload(dev2, 102);
timer_set_prescaler(dev2, 0);
////////////////////////////////////
timer_dma_set_base_addr(dev3, TIMER_DMA_BASE_CCR4); //
timer_dma_set_burst_len(dev3, 1);
// conflict #1
timer_dma_enable_req(dev3, cc_channel3);//
timer_set_reload(dev3, 102);
timer_set_prescaler(dev3, 0);
///////////////////////////////////
}
void dma_conf()
{
dma_init(DMA1);
/* T4C2 DMA C4 */
dma_cfg.tube_dst = &(dev1->regs.gen->DMAR);
dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
dma_cfg.tube_src = val1;
dma_cfg.tube_src_size = DMA_SIZE_32BITS;
dma_cfg.tube_nr_xfers = SAMPLES;
dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;
dma_cfg.tube_req_src = DMA_REQ_SRC_TIM4_CH2;
dma_cfg.target_data = 0;
ret = dma_tube_cfg(DMA1, DMA_CH4, &dma_cfg);
/* T1C1 DMA C2 */
dma_cfg.tube_dst = &(dev2->regs.gen->DMAR);
dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
dma_cfg.tube_src = val2;
dma_cfg.tube_src_size = DMA_SIZE_32BITS;
dma_cfg.tube_nr_xfers = SAMPLES;
dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;
dma_cfg.tube_req_src = DMA_REQ_SRC_TIM1_CH1;
dma_cfg.target_data = 0;
ret = dma_tube_cfg(DMA1, DMA_CH2, &dma_cfg);
///////////////////////
/* T3C3 DMA C2 */
dma_cfg.tube_dst = &(dev3->regs.gen->DMAR);
dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
dma_cfg.tube_src = val3;
dma_cfg.tube_src_size = DMA_SIZE_32BITS;
dma_cfg.tube_nr_xfers = SAMPLES;
dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;
//dma_cfg.tube_req_src = DMA_REQ_SRC_TIMX_CHX; //
dma_cfg.tube_req_src = DMA_REQ_SRC_TIM3_CH4; //
dma_cfg.target_data = 0;
// conflict #2
ret = dma_tube_cfg(DMA1, DMA_CH3, &dma_cfg);
//////////////////////
}
void dma_start()
{
dma_attach_interrupt(DMA1, DMA_CH4, fun);
dma_enable(DMA1, DMA_CH4);
timer_resume(dev1);
dma_attach_interrupt(DMA1, DMA_CH2, fun2);
dma_enable(DMA1, DMA_CH2);
timer_resume(dev2);
////////////////////////////
dma_attach_interrupt(DMA1, DMA_CH3, fun3);
dma_enable(DMA1, DMA_CH4);
timer_resume(dev3);
////////////////////////////
}
void init_wave()
{
int i;
for (i = 0; i < SAMPLES; i++)
{
val1[i] = 50 + amp * sin(stp * i);
val2[i] = val1[i];
val3[i] = val1[i];
}
}
void setup() {
int i;
pinMode(out1, PWM);
pinMode(out2, PWM);
pinMode(out3, PWM);
timer_conf();
dma_conf();
dma_start();
init_wave();
}
void loop() {
}
Last edited by ted on Fri Jul 06, 2018 10:36 pm, edited 1 time in total.
Top
User avatar
Rick Kimball
Posts: 1400
Joined: Tue Apr 28, 2015 1:26 am
Location: Eastern NC, US
Contact:
Contact Rick Kimball
Website
Re: STM32 Timers
Quote
Post by Rick Kimball » Fri Jul 06, 2018 10:33 pm
I don't think we can help you ... we have explained it 6 ways from Sunday
-rick
Top
ted
Posts: 312
Joined: Sun Jul 16, 2017 9:57 pm
Re: STM32 Timers
Quote
Post by ted » Fri Jul 06, 2018 10:40 pm
Thanks Rick for your help, I will try to solve that problem.
Regards
Ted
Top
ted
Posts: 312
Joined: Sun Jul 16, 2017 9:57 pm
Re: STM32 Timers
Quote
Post by ted » Fri Jul 06, 2018 10:41 pm
Thanks all of you
Top
User avatar
Rick Kimball
Posts: 1400
Joined: Tue Apr 28, 2015 1:26 am
Location: Eastern NC, US
Contact:
Contact Rick Kimball
Website
Re: STM32 Timers
Quote
Post by Rick Kimball » Fri Jul 06, 2018 10:59 pm
Tested and works:
Code: Select all
#define SAMPLES 100
#include
dma_tube_config dma_cfg, dma_cfg2, dma_cfg3;
int val1[SAMPLES];
int val2[SAMPLES];
int val3[SAMPLES];
int amp = 35;
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / SAMPLES;
int ret = 17;
int out1 = PB7; // TIM4_CH2 DMA_CH4
timer_dev *dev1 = PIN_MAP[out1].timer_device;
int out2 = PA8; // TIM1_CH1 DMA_CH2
timer_dev *dev2 = PIN_MAP[out2].timer_device;
int out3 = PB1; // TIM3_CH4 DMA CH3
timer_dev *dev3 = PIN_MAP[out3].timer_device;
void timer_conf()
{
// PB7 TIM4_CH2 DMA_CH4
timer_dma_set_base_addr(dev1, TIMER_DMA_BASE_CCR2);
timer_dma_set_burst_len(dev1, 1);
timer_dma_enable_req(dev1, PIN_MAP[out1].timer_channel);
timer_set_reload(dev1, 102);
timer_set_prescaler(dev1, 0);
// PA8 TIM1_CH1 DMA_CH2
timer_dma_set_base_addr(dev2, TIMER_DMA_BASE_CCR1);
timer_dma_set_burst_len(dev2, 1);
timer_dma_enable_req(dev2, PIN_MAP[out2].timer_channel);
timer_set_reload(dev2, 102);
timer_set_prescaler(dev2, 0);
// PB1 TIM3_CH4 DMA CH3
timer_dma_set_base_addr(dev3, TIMER_DMA_BASE_CCR4); //
timer_dma_set_burst_len(dev3, 1);
timer_dma_enable_req(dev3, PIN_MAP[out3].timer_channel);//
timer_set_reload(dev3, 102);
timer_set_prescaler(dev3, 0);
}
void dma_conf()
{
dma_init(DMA1);
// PB7 TIM4_CH2 DMA_CH4
dma_cfg.tube_dst = &(dev1->regs.gen->DMAR);
dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
dma_cfg.tube_src = val1;
dma_cfg.tube_src_size = DMA_SIZE_32BITS;
dma_cfg.tube_nr_xfers = SAMPLES;
dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC;
dma_cfg.tube_req_src = DMA_REQ_SRC_TIM4_CH2;
dma_cfg.target_data = 0;
ret = dma_tube_cfg(DMA1, DMA_CH4, &dma_cfg);
// PA8 TIM1_CH1 DMA_CH2
dma_cfg.tube_dst = &(dev2->regs.gen->DMAR);
dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
dma_cfg.tube_src = val2;
dma_cfg.tube_src_size = DMA_SIZE_32BITS;
dma_cfg.tube_nr_xfers = SAMPLES;
dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC;
dma_cfg.tube_req_src = DMA_REQ_SRC_TIM1_CH1;
dma_cfg.target_data = 0;
ret = dma_tube_cfg(DMA1, DMA_CH2, &dma_cfg);
// PB1 TIM3_CH4 DMA CH3
dma_cfg.tube_dst = &(dev3->regs.gen->DMAR);
dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
dma_cfg.tube_src = val3;
dma_cfg.tube_src_size = DMA_SIZE_32BITS;
dma_cfg.tube_nr_xfers = SAMPLES;
dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC;
dma_cfg.tube_req_src = DMA_REQ_SRC_TIM3_CH4; //
dma_cfg.target_data = 0;
ret = dma_tube_cfg(DMA1, DMA_CH3, &dma_cfg);
}
void dma_start()
{
// PB7 TIM4_CH2 DMA_CH4
dma_enable(DMA1, DMA_CH4);
timer_resume(dev1);
// PA8 TIM1_CH1 DMA_CH2
dma_enable(DMA1, DMA_CH2);
timer_resume(dev2);
// PB1 TIM3_CH4 DMA CH3
dma_enable(DMA1, DMA_CH3);
timer_resume(dev3);
}
void init_wave()
{
int i;
for (i = 0; i < SAMPLES; i++)
{
val1[i] = 50 + amp * sin(stp * i);
val2[i] = val1[i];
val3[i] = 50 + amp * sin(stp * i);
}
}
void setup() {
pinMode(out1, PWM);
pinMode(out2, PWM);
pinMode(out3, PWM);
timer_conf();
dma_conf();
dma_start();
init_wave();
}
void loop() {
}
-rick
Top
ted
Posts: 312
Joined: Sun Jul 16, 2017 9:57 pm
Re: STM32 Timers
Quote
Post by ted » Fri Jul 06, 2018 11:44 pm
Thanks Rick, you are the best.
There is small issue with phase correction,comparing to PB7, PB1 is shifted approximately 10 deg. and PA8 60 deg, I think I can manage this.
Thanks again.
I did this - no changes.
Code: Select all
{
val1[i] = 50 + amp * sin(stp * i);
//val2[i] = val1[i];
val2[i] = 50 + amp * sin(stp * i);
val3[i] = 50 + amp * sin(stp * i);
}
Top
ted
Posts: 312
Joined: Sun Jul 16, 2017 9:57 pm
Re: STM32 Timers - Solved by Mr. Rick
Quote
Post by ted » Sat Jul 07, 2018 12:29 am
Solved by Mr. Rick
Top
Col68
Posts: 72
Joined: Thu Mar 15, 2018 2:37 pm
Re: STM32 Timers - Solved by Mr. Rick
Quote
Post by Col68 » Sun Jul 08, 2018 4:14 pm
ted wrote: ↑
Sat Jul 07, 2018 12:29 am
Solved by Mr. Rick
Congratulations and good luck :)
when i saw Rick assist you, i thought "he will succeed" because Rick is too strong.
Respect for ☆ Rick ☆
Top
Post Reply
Print view
Display:
All posts
Sort by:
Post time
Direction:
Ascending
40 posts
Previous
1
2
3
4
Return to “Projects”
Jump to
New users start here
↳ Forum rules, FAQs and HowTo's
↳ Let us know a bit about you and your projects
Arduino for STM32
↳ Builds and Announcements
↳ General discussion
↳ Libraries & Hardware
↳ Working / ported libraries
↳ Problems with libraries
↳ Libary request
↳ Hardware
↳ Projects
↳ Ideas & suggestions
↳ Code snipplets
↳ Installation and OS related
↳ Windows
↳ OSX
↳ Linux
↳ IDE's
↳ Off topic
↳ Postbag
↳ PR's bugs and enhancements
↳ Dead Thread Graveyard
Boards
↳ STM32F103 Boards
↳ STM Nucleo boards
↳ Maple & Maple mini etc
↳ All other boards
↳ Custom design boards
↳ STM32F4 Boards
↳ STM32F3 Boards
↳ GD32F103 boards
Bootloaders and Cores
↳ Cores
↳ USB bootloader
↳ CubeMX and HAL
↳ STM Core
↳ STM core: Bugs and enhancements
↳ STM32generic
↳ STM8
↳ LibMaple
Libraries and Hardware
↳ STM Core
↳ LibMaple Core
↳ Core agnostic libraries
Uploaders and debuggers
↳ STLink
↳ USB to Serial adaptors
↳ Black Magic Probe & other
Home Board index
All times are UTC
Delete all board cookies
The team
Contact us
Powered by phpBB® Forum Software © phpBB Limited
ความคิดเห็น
แสดงความคิดเห็น