Frequency changing

Hi
In this generator frequency can be changed manually by changing # of SAMPLES , I trying to do that by buttons and j , so far no luck.

#include "LiquidCrystal.h"
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);


///////////////////////////
int j;
#define SAMPLES 90
//#define SAMPLES j
///////////////////////////


#include <libmaple/dma.h>

dma_tube_config dma_cfg;

int flag1 = 0;
int out1 = PB7;
int val1[SAMPLES];


int amp = 50;
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / SAMPLES;
//float stp = 7.8539/SAMPLES;
int ret = 17;

timer_dev *dev1 = PIN_MAP[out1].timer_device;

uint8 cc_channel1 = PIN_MAP[out1].timer_channel;


void fun()
{
  flag1++;
}

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);

}

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);

}

void dma_start()
{
  dma_attach_interrupt(DMA1, DMA_CH4, fun);

  dma_enable(DMA1, DMA_CH4);
  timer_resume(dev1);


  dma_enable(DMA1, DMA_CH2);//
  //  timer_resume(dev2);
}

void init_wave()
{
  int i;
  for (i = 0; i < SAMPLES; i++)
  {
    val1[i] = 50 + amp * sin(stp * i);

  }
}


void setup() {


  lcd.begin(16, 2);

  int i;
int j;

  pinMode(out1, PWM);
  pinMode(PB13, INPUT_PULLDOWN);
  pinMode(PB12, INPUT_PULLDOWN);


  timer_conf();
  dma_conf();
  dma_start();

  init_wave();
}

void loop()
{

  lcd.setCursor(0, 1);
  lcd.print("j = ");
  lcd.setCursor(4, 1);
  lcd.print(j);

  delay(100);

}


//////////////////////////////////
//void j()
void SAMPLES _ j()
{
    if (digitalRead(PB12) == HIGH)
   
  {
    if (j < 200)
      // if (i < 25)
    {
      j++;

    }
  }

  if (digitalRead(PB13) == HIGH)

  {
    if (j > 0)
    {
      j--;

    }
  }
}
/////////////////////////////

error
void_sample_j:6:17: error: expected unqualified-id before numeric constant
#define SAMPLES 88
^
/Users/Documents/Arduino/void_sample_j/void_sample_j.ino:123:6: note: in expansion of macro ‘SAMPLES’
void SAMPLES _ j()
^~~~~~~
Multiple libraries were found for “LiquidCrystal.h”
Used: /Users/Documents/Arduino/hardware/Arduino_STM32-master-3/STM32F1/libraries/LiquidCrystal
Not used: /Users/tedkor/Desktop/Arduino.app/Contents/Java/libraries/LiquidCrystal
exit status 1
expected unqualified-id before numeric constant

void SAMPLES _ j() What’s that?

my attempt

79galinakorczak:
my attempt

To do what?
It makes no sense.
“SAMPLES” shouldn’t be there, and neither should the underscore.

‘j’ is a bad name for a global variable representing a number of samples. Maybe call it something like ‘Samples’. If you are reading or writing samples in an array, ‘Samples’ can’t be larger than the size of the array.

Maybe something like this:

#include "LiquidCrystal.h"
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);


///////////////////////////
#define MAX_SAMPLES 200
int Samples = 90;
///////////////////////////


#include <libmaple/dma.h>


dma_tube_config dma_cfg;


int flag1 = 0;
int out1 = PB7;
int val1[MAX_SAMPLES];


int amp = 50;
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / MAX_SAMPLES;
//float stp = 7.8539/MAX_SAMPLES;
int ret = 17;


timer_dev *dev1 = PIN_MAP[out1].timer_device;


uint8 cc_channel1 = PIN_MAP[out1].timer_channel;




void fun()
{
  flag1++;
}


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);
}


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);


}


void dma_start()
{
  dma_attach_interrupt(DMA1, DMA_CH4, fun);


  dma_enable(DMA1, DMA_CH4);
  timer_resume(dev1);


  dma_enable(DMA1, DMA_CH2);//
  //  timer_resume(dev2);
}


void init_wave()
{
  for (int i = 0; i < MAX_SAMPLES; i++)
  {
    val1[i] = 50 + amp * sin(stp * i);
  }
}




void setup()
{
  lcd.begin(16, 2);


  pinMode(out1, PWM);
  pinMode(PB13, INPUT_PULLDOWN);
  pinMode(PB12, INPUT_PULLDOWN);


  timer_conf();
  dma_conf();
  dma_start();


  init_wave();
}


void loop()
{
  ReadButtons();
  dma_conf();  // Update the number of samples
  
  lcd.setCursor(0, 1);
  lcd.print("Samples = ");
  lcd.print(Samples);


  delay(100);
}




//////////////////////////////////
void ReadButtons()
{
  if (digitalRead(PB12) == HIGH)
  {
    if (Samples < MAX_SAMPLES)
    {
      Samples++;
    }
  }


  if (digitalRead(PB13) == HIGH)
  {
    if (Samples > 0)
    {
      Samples--;
    }
  }
}


/////////////////////////////

Sine wave is shown for split of the second after uploading

79galinakorczak:
Sine wave is shown for split of the second after uploading

Sounds like something that is supposed to repeat is not repeating. Did the sketch work before you tried to vary the frequency?

@79galinakorczak, seems like fairly sophisticated code (DMA, hardware timers, etc). Did you write it?

before modification, sine on PB7

#include "LiquidCrystal.h"
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

///////////////////////////
int j;
#define SAMPLES 88
//#define SAMPLES j
///////////////////////////

#include <libmaple/dma.h>

dma_tube_config dma_cfg;

int flag1 = 0;
int out1 = PB7;
int val1[SAMPLES];


int amp = 50;
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / SAMPLES;
//float stp = 7.8539/SAMPLES;
int ret = 17;

timer_dev *dev1 = PIN_MAP[out1].timer_device;

uint8 cc_channel1 = PIN_MAP[out1].timer_channel;


void fun()
{
  flag1++;
}

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);

}

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);

}

void dma_start()
{
  dma_attach_interrupt(DMA1, DMA_CH4, fun);

  dma_enable(DMA1, DMA_CH4);
  timer_resume(dev1);


  dma_enable(DMA1, DMA_CH2);//
  //  timer_resume(dev2);
}

void init_wave()
{
  //int i;
  for (int i = 0; i < SAMPLES; i++)
  {
    val1[i] = 50 + amp * sin(stp * i);

  }
}


void setup() {


  lcd.begin(16, 2);

  int i;
  //int j;

  pinMode(out1, PWM);
  pinMode(PB13, INPUT_PULLDOWN);
  pinMode(PB12, INPUT_PULLDOWN);


  timer_conf();
  dma_conf();
  dma_start();

  init_wave();
}

void loop()
{

  lcd.setCursor(0, 1);
  lcd.print("j = ");
  lcd.setCursor(4, 1);
  lcd.print(j);

  delay(100);

}

gfvalvo:
@79galinakorczak, seems like fairly sophisticated code (DMA, hardware timers, etc). Did you write it?

I find it on net

From looking at the code it appears that changing SAMPLES is NOT the way to change frequency. It will change the frequency but only by throwing out part of the sine wave.

The proper way to change frequency is "timer_set_reload(dev1, count);". The value 'count' is the number of clock ticks per sample. That would be the number of clock ticks per cycle divide by the number of samples. That would be (72 MHz / desiredFrequency) / SAMPLES.

Thanks for explanation

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.