In a recent build I've been moving my code to using registers instead of the built in functions and I've stumbled across an odd phenomenon. If I substitute the pinMode line below for the DDRD line below, the output pin has a distinctive slope when it is cleared.
DDRD |= 0x20;
pinMode(5, OUTPUT);
In my current build, I'm setting the pin then a timer is setup for 60us, after which the pin is cleared. This pulse (set and clear) is visible on both attached graphs but the one has a prominent slope when the pin is cleared. Please note that no hardware was changed between these two graphs.
I've done some research into pinMode() and the only difference I can see is that interrupts are disabled during the DDR assignment within pinMode().
I've tested adding the interrupt disable around the DDRD line in my code with no change in result. I've also tested running the pulse longer (1ms) and the slope is still there.
Can anyone explain why these two lines don't produce the same results?
EDIT:
Something else to note, the rise time has a distinctive curve when using DDR. When using pinMode, the rise time is much quicker. If I didn't know that it was coming from a digital pin, I would think the pin was analog.
The main difference between pinMode and accessing the registers directly is the timing. If you use pinMode the Arduino reads the translation vom the Arduino pin number to the register/bit pair from the flash memory which needs some time.
To give you any feedback on the pictures you posted, you have to post the code that produced them. Small excerpts might be the only difference between two sketches but the rest of the code is usually even more important than the posted parts.
PORTD |= 0x20;
//Setup timer for first stage of test
//First step is to end 50kHz pulse
cli();
TCNT1 = 0x0000;
OCR1A = 0x0078; //0078 ~= 60us; 3 pulses at 50kHz
sei();
nextState = false;
// do nothing while waiting for 50kHz to turn off
while (!nextState) {
}
nextState = false;
// //Timer has triggered; stop firing the SCR
// digitalWrite(pinMuxEnable, 0);
PORTD &= 0xDF;
The interrupt associated with OCR1A toggles nextState to advance the code. Bear in mind nothing in this part of the code changed between the two graphs.
Like most programming issues, the problem was self-generated. It took some rubber-duck debugging and writing out discrete bits (1100 vs C) to find it but later on in the code, I set the DDR again and ended up setting this pin as an input.