Go Down

Topic: Due Help on direct port access with PWM (Read 108 times) previous topic - next topic


Hello everyone,

This is my first time posting on this forum. So, recently I purchased the Arduino Due after months of tinkering with the Uno. When using the Uno, port manipulation was a bit easier using DDR and PORTx. When I made the jump from an AVR board to an ARM, I was stuck on how to do port manipulation for the Due. I first started with a simple blinking LED program to understand how to set and clear bits. The simple code is shown below.

Code: [Select]
void setup() {
  REG_PIOB_PER = (1<<25);  //Can also use bit mask - 0x1<<25
  REG_PIOB_OER = (1<<25);  //Can also use REG_PIOB_OER = PIO_OER_P25

void loop() {

  REG_PIOB_SODR = (1<<25);
  REG_PIOB_CODR = (1<<25);


Now I want to write a program that will use PWM on the LED. After a little research, I found that each I/O pin can have be multiplexed to have two functions. What is multiplexing and how can it be done in a simple example? Also, how can I write a program to set up PWM using low-level programming?


Hello btt92

[quote ]

 I found that each I/O pin can have be multiplexed to have two functions[/quote]

You have the explanation of this chap 9.3 of Sam3x datasheet.

For PWM programming, here is an example :

Code: [Select]

void setup () {
  // PWM Set-up on pin PC7 (Arduino Pin 39): see Datasheet chap. 38.5.1
  // Select Instance=PWM; Signal=PWMH2 (channel 2); I/O Line=PC7 (P7, Arduino pine 39, see pinout diagram) ; Peripheral=B

  PMC->PMC_PCER1 |= PMC_PCER1_PID36;                   // PWM on

  REG_PIOC_ABSR |= PIO_ABSR_P7;                        // Set PWM pin perhipheral type B

  REG_PIOC_PDR |= PIO_PDR_P7;                          // Set PWM pin to an output

  REG_PWM_ENA = PWM_ENA_CHID2;                         // Enable the PWM channel 2 (see datasheet page 973)
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(42);    // Set the PWM clock rate to 2MHz (84MHz/42). Adjust DIVA for the resolution you are looking for
  REG_PWM_CMR2 = PWM_CMR_CALG |PWM_CMR_CPRE_CLKA;      // The period is left aligned, clock source as CLKA on channel 2

  REG_PWM_CPRD2 = 1000000;                             // Channel 2 : Set the PWM frequency 2MHz/(2 * CPRD) = F ; 1< CPRD < 2exp24  -1 ; here CPRD = 10 exp 6

  REG_PWM_CDTY2 = 200000;                              // Channel 2: Set the PWM duty cycle to x%= (CDTY/ CPRD)  * 100 % , CDTY = 2 * 10 exp 5

 // Alternatively, you can use this format :  PWM->PWM_CH_NUM[2].PWM_CPRD = 1000000 ;                   
 // In this example, Frequency is 1 HZ with a DT of 20% so you can see it with an LED attached to pin 39 with a resistor 

void loop() {


So, from my understanding, all the pins on the due are controlled by the PIO controllers that are capable of controlling 32 lines(pins). Each pin ( or line) can do two functions which are chosen from the start and once a peripheral function is chosen, you can not reset to the other function. Is that pretty much how it is? Thank you for the reply, the example worked well!

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!

via Egeo 16
Torino, 10131