Таймеры STM32

gal
Offline
Зарегистрирован: 08.06.2018
Здраствуйте.
 
Я пытаюсь добавить третий канал к этому генератору, к сожалению, у меня ничего нет на 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() {

}


 

 

b707
Offline
Зарегистрирован: 26.05.2017

я могу ошибаться, но у вас в процедуре dma_start() на одно и то же прерывание DMA1 DMA_CH4 повешено сразу две функции. Думаю, это ошибка.

И что-то мне кажется, что код вы, как всегда,  нашли в инете и в нем ни буквы не понимаете...

gal
Offline
Зарегистрирован: 08.06.2018

Изучаю тимеры, сделал так как это сделано для двух первых тимеров, пока испрвить не получилось.

gal
Offline
Зарегистрирован: 08.06.2018

Пришел выводу что надо поменять ДМА 1 на ДМА 2, но есть error. помогите исправить. 

error:

C:\Users\OWNER\Desktop\DMA_2_3_CH\DMA_2_3_CH.ino: In function 'void dma_conf()':
 
DMA_2_3_CH:104: error: 'DMA2' was not declared in this scope
 
    dma_init(DMA2);
 
             ^
 
C:\Users\OWNER\Desktop\DMA_2_3_CH\DMA_2_3_CH.ino: In function 'void dma_start()':
 
DMA_2_3_CH:135: error: 'DMA2' was not declared in this scope
 
   dma_attach_interrupt(DMA2, DMA_CH4, fun3);  //
 
                        ^
 
exit status 1
'DMA2' was not declared in this scope
 
#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()
{
}

 

b707
Offline
Зарегистрирован: 26.05.2017

если это stm32F103 - в этой плате нет DMA2

судя по коду, вы пытаетесь добавить третий канал, просто скопировав код от одного из двух первых. Так у вас ничего не получится. У каждого канала должен быть свой таймер. свой девайс и свое прерывание - иначе ничего работать не будет.

gal
Offline
Зарегистрирован: 08.06.2018
Да это stm32F103.
Там только один ДМА ?