Using interrupts on the Due

Hi,

New to programming and I’ve read several other forum post here about the subject but find my questions unanswered.

I wish to check Pin 40 for change and duplicate the input on output Pin 25, generate PWM and operate and update a screen. The screen should have lowest priority.

This is my code so far.

////////Libaries included///////
/////////////////////////////////
#include “pwm_lib.h”
#include “tc_lib.h”
#include “U8glib.h”
/////////////////////////////////
/////////////////////////////////

////////Definitions//////////////
/////////////////////////////////
using namespace arduino_due::pwm_lib;

#define PWM_PERIOD_PIN_35 1333333 // hundredth of usecs (1e-8 secs). 1562.5 gives 64KHz. 6250 gives 16KHz. 1333333 gives 75Hz.
#define PWM_DUTY_PIN_35 666666.5 // 10 usecs in hundredth of usecs (1e-8 secs)

#define PWM_PERIOD_PIN_42 6250 // hundredth of usecs (1e-8 secs). 1562.5 gives 64KHz. 6250 gives 16KHz.
#define PWM_DUTY_PIN_42 3125 // 10 usecs in hundredth of usecs (1e-8 secs)

// Enables the OLED screen with correct OUTPUT
U8GLIB_NHD31OLED_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9

// defining pwm object using pin 35, pin PC3 mapped to pin 35 on the DUE
// this object uses PWM channel 0
pwm<pwm_pin::PWMH0_PC3> pwm_pin35;

// defining pwm objetc using pin 42, pin PA19 mapped to pin 42 on the DUE
// this object used PWM channel 1
pwm<pwm_pin::PWMH1_PA19> pwm_pin42;

uint8_t offset = 0;

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

////////Functions////////////////
/////////////////////////////////

void draw(void) {
// graphic commands to redraw the complete screen should be placed here
u8g.setFont(u8g_font_unifont);
u8g.drawStr( 0+0, 20+0, “Hello!”);
u8g.drawStr( 0+2, 20+16, “Hello!”);

u8g.drawBox(0, 0, 3, 3);
u8g.drawBox(u8g.getWidth()-6, 0, 6, 6);
u8g.drawBox(u8g.getWidth()-9, u8g.getHeight()-9, 9, 9);
u8g.drawBox(0, u8g.getHeight()-12, 12, 12);
}

void setup() {
// put your setup code here, to run once:
pinMode(25, OUTPUT); // Pin 25 as OUTPUT
pinMode(40, INPUT); // Pin 40 as INPUT
//attachInterrupt(digitalPinToInterrupt(40), test1, HIGH);
//attachInterrupt(digitalPinToInterrupt(40), test2, LOW);
//PIOC->PIO_ODR = PIO_PC8; //Pin C8/40 as INPUT
}

void loop() {
// put your main code here, to run repeatedly:
// starting PWM signals on Pin 35 and Pin 42
pwm_pin35.start(PWM_PERIOD_PIN_35,PWM_DUTY_PIN_35);
pwm_pin42.start(PWM_PERIOD_PIN_42,PWM_DUTY_PIN_42);

while(1)
{
/rotate();
// picture loop
u8g.firstPage();
do {
draw();
} while( u8g.nextPage() );
/

if((PIOC->PIO_PDSR & PIO_PC8) == PIO_PC8) // Check INPUT on Pin 40
{
REG_PIOD_SODR = 0x1 << 0; // Set digital Pin 25 HIGH
}
else
{
REG_PIOD_CODR = 0x1 << 0; // Set digital Pin 25 LOW
}
}
}

void rotate(void) {
static uint8_t dir = 0;
static unsigned long next_rotation = 0;

if ( next_rotation < micros() )
{
switch(dir) {
case 0: u8g.undoRotation(); break;
case 1: u8g.setRot90(); break;
case 2: u8g.setRot180(); break;
case 3: u8g.setRot270(); offset = ( offset + 1 ) & 0x0f; break;
}

dir++;
dir &= 3;
next_rotation = micros();
next_rotation += 10;
}
}
/////////////////////////////////
/////////////////////////////////

sketch_mar21a.ino (3.64 KB)

Hi Lentaro,

Maybe I can help?

If you want to duplicate HIGH LOW from PIN40 to PIN25 will this do the trick for you?

digitalWrite(25, digitalRead(40));

As for the other requests what are you trying to accomplish?

I suggest you to split your program into smaller ones.

Stepwise:

Make a program to read input pin 40 and duplicate the output on pin 25, once this one works, add a function to generate PWM pulses on pin 35 and 42. Once all this works, operate a screen.

You have several simple ways to debug: via the Serial port and the built in led. Of course a scope would be a must.

If you decide to avoid TC and PWM libraries for this simple code (however very good ones), and want to understand how the Sam3x8e works, you can find example sketches in the DUE sub forum of this forum either for PWM or Timer Counter programming.