Go Down

Topic: Arduino DUE PWM 60kHz Problem (Read 2994 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 ]

#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.

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../   


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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy