Go Down

Topic: Arduino DUE PWM 60kHz Problem (Read 2613 times) previous topic - next topic

mg0012

Hello,
I am a newby in Arduino and sorry for asking questions like this.
So far I, tried to get a PWM signal with 80% Duty Cycle (=204) and a frequency of 60000Hz.
I don't know how to change register entries in the SAMX3E8. Do you have an example for the DUE or can me help anyhow?
The program is below.
Best,
Mike

void setup() {
pinMode(13, OUTPUT);
}

void loop() {
  analogWrite(13,204);
}

mg0012

void setup()  {
  pinMode(9, OUTPUT);
  analogWrite(9, 204);
  PWMC_ConfigureClocks(60000 *255, 0, VARIANT_MCK);
}

void loop()  {

}

I can't set the Frequency of 60000Hz, the result of PWMC_ConfigureClocks is a Frequency of 65000Hz .. Maybe there is an Overflow.

Any ideas?

randomvibe


I recommend the following library:

http://forum.arduino.cc/index.php?topic=144446.msg1149044#msg1149044

Above approximately 40khz, I notice that what is commanded is not what is received.  You just need to adjust the programmed frequency to get what you need.  I test several values, and this is what happens:

http://forum.arduino.cc/index.php?topic=146947.msg1444058#msg1444058

mg0012

I used the manual from SAM 3xae:

http://www.atmel.com/Images/doc11057.pdf (page 1020)

and find out, that i have to set the values DIVA and PREA in PMW_CLK on address 0x40094000.
DIVA is working, but PREA is not changing anything. Do I make a mistake with the address?


#define DIVA   (*(volatile unsigned int *) 0x40094000)
#define PREA   (*(volatile unsigned int *) 0x40094008)

#define WPSWS0   (*(volatile unsigned int *) 0x400940E8)
#define WPHWS0   (*(volatile unsigned int *) 0x400940F0)

void setup() {
  pinMode(6, OUTPUT);
  analogWrite(6,205);


  DIVA = 0b00001011;
  PREA = 0b0110;
 
 
  WPHWS0 = 0;
  WPSWS0 = 0;
}

void loop() {
  delay(500);
}

mg0012

NOBODY wanted to help.. POOR!!!!

Anyway, to fulfill these question my final solution:

#define PWM_CLK_E    (*(volatile unsigned long int *) 0x40094000)  // page 1020
#define PWM_WPSR_E   (*(volatile unsigned long int *) 0x400940E8)  // page 1053
#define PWM_CPRD7_E  (*(volatile unsigned long int *) 0x400942EC)  // Channel7 == PIN6  page 1062

void setup() {

  pinMode(6, OUTPUT);
  analogWrite(6,205);
  PWM_WPSR_E &= 0b11111111111111111111011011110110; //WPHWS0=0 WPSWS0=0 PHWS3=0 WPSWS3=0
  PWM_CLK_E   = 0b00000000000001000000000000000100; //DIVA= PREA= DIVB= PREB=
  PWM_CPRD7_E = 0x015E; // 350
                 
}

void loop() {

}

MarkT

#5
Dec 16, 2013, 07:05 pm Last Edit: Dec 16, 2013, 07:44 pm by MarkT Reason: 1
You don't need to #define anything, its all predefined in the system.  The best place
to learn about driving PWM is the libsam includes and sources:

In your Arduino distribution go to .../hardware/arduino/sam/system/libsam/source/pwmc.c
and .../hardware/arduino/sam/system/libsam/include/pwmc.h

[edit:  after a bit of delving, this sets up PWM channel 0 to drive Arduino pin 34:

Code: [Select]
void setup() {
  // put your setup code here, to run once:
  pmc_enable_periph_clk (PWM_INTERFACE_ID) ;  // turn on clocking to PWM unit

  PWMC_ConfigureChannel (PWM, 0, 1, 0, 0) ; // PWM channel 0, clock = MCLK/2 = 42MHz
  PWMC_SetPeriod (PWM, 0, 700) ;  // period = 700 pwm clocks (60kHz)
  PWMC_SetDutyCycle (PWM, 0, 80*700/100) ;  // duty set to 80%
  PWMC_EnableChannel (PWM, 0) ;   // enable

  // Configure pin 34 (PC2) to be driven by peripheral B (PWM channel 0 L)
  PIOC->PIO_PDR = 1<<2 ;  // disable PIO control
  PIOC->PIO_IDR = 1<<2 ;   // disable PIO interrupts
  PIOC->PIO_ABSR |= 1<<2 ;  // switch to B peripheral

}

void loop() {
  // put your main code here, to run repeatedly:

}

]
[ I won't respond to messages, use the forum please ]

maharaj_44

#6
Feb 27, 2014, 05:45 am Last Edit: Feb 27, 2014, 05:46 am by maharaj_44 Reason: 1
Hello,
i want to generate a PWM wave having a period of 20 ms, with a pulse being ON for 1ms to 2ms. I have used the above code of PWMC controller of SAM3X8E for getting the result, but i am not getting the desired output.
I have used 84MHz clock with a pre-scaler of 2. The frequency is 50Hz.

PWMC_ConfigureChannel (PWM, 7, 2, 0, 0) ;  //on channel 7 of PWM and pin 6 of Due
PWMC_SetPeriod (PWM, 7, 840000);  //84Mhz/2/50
PWMC_SetDutyCycle (PWM, 7, 50*840000/100) ;

On the Oscilloscope, i am getting a 1.5 ms pulse but the period is not about 20ms. Can anybody please have a look at this issue.

Will be appreciated..
Thanks.

Patouf

If you are trying to control a servo or an ESC, maybe you should use the servo library provided with the arduino IDE:http://arduino.cc/en/Reference/Servo
L.C.

maharaj_44

You got it Right, i want to control a 180 degree servo motor having it's neutral at 90 degree. By giving a pulse of 1ms to 2ms, i want it to rotate it to 90 degree and then again back to 180 degree.
i have already referred to the servo library of Arduino, but i want it to be controlled using PWM Controller of SAM 3X8E. Till now i have studied that a servo requires a pulse every 20 ms, independent of what is duty cycle or the on time.

I have the requirement to generate a pulse of 1.5ms at a frequency of 50Hz and then pulse should be off for around 18 ms. If the frq. is 50Hz, then the period should be 20ms, but after coding, in the oscilloscope, i am not getting a period of 20ms. Also, i am confused regarding what should be the pre-scaler value to be used in Due to pre-scale the clock of 84Mhz, and the calculation of the period done in the PWMC_SetPeriod function.
PWMC.c is the source file which i am referring for all this purpose.

please help me to solve his issue.

Thanks../   

Feedorafk


NOBODY wanted to help.. POOR!!!!

Anyway, to fulfill these question my final solution:

#define PWM_CLK_E    (*(volatile unsigned long int *) 0x40094000)  // page 1020
#define PWM_WPSR_E   (*(volatile unsigned long int *) 0x400940E8)  // page 1053
#define PWM_CPRD7_E  (*(volatile unsigned long int *) 0x400942EC)  // Channel7 == PIN6  page 1062

void setup() {

  pinMode(6, OUTPUT);
  analogWrite(6,205);
  PWM_WPSR_E &= 0b11111111111111111111011011110110; //WPHWS0=0 WPSWS0=0 PHWS3=0 WPSWS3=0
  PWM_CLK_E   = 0b00000000000001000000000000000100; //DIVA= PREA= DIVB= PREB=
  PWM_CPRD7_E = 0x015E; // 350
                 
}

void loop() {

}


Hi mg0012,

where did you find out that channel 7 == pin 6?

Go Up