Таймеры STM32
- Войдите на сайт для отправки комментариев
Пнд, 02/07/2018 - 22:05
Здраствуйте.
Я пытаюсь добавить третий канал к этому генератору, к сожалению, у меня ничего нет на PB1, два канала работают правильно.
Где ошибка?
#define SAMPLES 100
#include <libmaple/dma.h>
dma_tube_config dma_cfg, dma_cfg2, dma_cfg3 ;
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int out1 = PB7;
int out2 = PA8;
int out3 = PB1;
//int out3 = PA7;
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;
//120 deg = stp/3
int ret = 17;
timer_dev *dev1 = PIN_MAP[out1].timer_device;
timer_dev *dev2 = PIN_MAP[out2].timer_device;
timer_dev *dev3 = PIN_MAP[out3].timer_device;
uint8 cc_channel1 = PIN_MAP[out1].timer_channel;
uint8 cc_channel2 = PIN_MAP[out2].timer_channel;
uint8 cc_channel4 = PIN_MAP[out3].timer_channel;
void fun()
{
flag1++;
}
void fun2()
{
flag2++;
}
void fun3()
{
flag3++;
}
//////////////////////////////////////////////////////////
void timer_conf()
{
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);
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);
// 3 channel
///////////////////////////////////////////////////////////////////
timer_dma_set_base_addr(dev3, TIMER_DMA_BASE_CCR1);
/////////////////////////////////////////////////////////////////
timer_dma_set_burst_len(dev3, 1);
timer_dma_enable_req(dev3, cc_channel4);
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 C3 */
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_TIM1_CH2;
dma_cfg.target_data = 0;
////////////////////////////////////////////
}
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_CH4, 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] = 50 + amp * cos(stp * i);
val3[i] = 50 + amp * sin(stp * i);
}
}
void get_wave(int16 shift)
{
int i;
for (i = 0; i < SAMPLES; i++)
{
val2[i] = 50 + amp * sin( stp * i + shift * 0.1 * 6.2831 / 360);
}
}
*/
void setup() {
int i;
pinMode(out1, PWM);
pinMode(out2, PWM);
pinMode(out3, PWM);
Serial.begin(9600);
timer_conf();
dma_conf();
dma_start();
init_wave();
// get_wave(shift);
}
void loop() {
}
я могу ошибаться, но у вас в процедуре dma_start() на одно и то же прерывание DMA1 DMA_CH4 повешено сразу две функции. Думаю, это ошибка.
И что-то мне кажется, что код вы, как всегда, нашли в инете и в нем ни буквы не понимаете...
Изучаю тимеры, сделал так как это сделано для двух первых тимеров, пока испрвить не получилось.
Пришел выводу что надо поменять ДМА 1 на ДМА 2, но есть error. помогите исправить.
error:
#define SAMPLES 100 #include <libmaple/dma.h> //dma_tube_config dma_cfg, dma_cfg2, dma_cfg3; dma_tube_config dma_cfg, dma_cfg2, dma_cfg3; int flag1 = 0; int flag2 = 0; int flag3 = 0; int out1 = PB7; int out2 = PA8; //int out3 = PA2; // Timer #2, Channel #3 int out3 = PA3; // Timer #2, Channel #4 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; timer_dev *dev3 = PIN_MAP[out3].timer_device; uint8 cc_channel1 = PIN_MAP[out1].timer_channel; uint8 cc_channel2 = PIN_MAP[out2].timer_channel; uint8 cc_channel4 = PIN_MAP[out3].timer_channel; void fun() { flag1++; } void fun2() { flag2++; } void fun3() { flag3++; } void timer_conf() { 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); 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_CCR1); // ????????? timer_dma_set_base_addr(dev3, TIMER_DMA_BASE_CCR1); timer_dma_set_burst_len(dev3, 1); timer_dma_enable_req(dev3, cc_channel4); // timer_set_reload(dev3, 102); timer_set_prescaler(dev3, 0); ////////////////////////////// } void dma_conf() { dma_init(DMA1); /* T4C2 DMA C4 , timer #4*/ 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, Timer #1*/ 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); /////////////////////////////////// dma_init(DMA2); /* T2C1 DMA C3, Timer #2*/ 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_TIM2_CH4; // dma_cfg.target_data = 0; // ret = dma_tube_cfg(DMA1, DMA_CH4, &dma_cfg); // ret = dma_tube_cfg(DMA2, DMA_CH4, &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(DMA2, DMA_CH4, fun3); // dma_enable(DMA2, 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] = 50 + amp * cos(stp * i); val3[i] = 50 + amp * sin(stp * i); } } void setup() { int i; pinMode(out1, PWM); pinMode(out2, PWM); pinMode(out3, PWM); timer_conf(); dma_conf(); dma_start(); init_wave(); } void loop() { }если это stm32F103 - в этой плате нет DMA2
судя по коду, вы пытаетесь добавить третий канал, просто скопировав код от одного из двух первых. Так у вас ничего не получится. У каждого канала должен быть свой таймер. свой девайс и свое прерывание - иначе ничего работать не будет.