unsignedlongpulseIn(uint8_tpin,uint8_tstate,unsignedlongtimeout){// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
uint8_tbit=digitalPinToBitMask(pin);uint8_tport=digitalPinToPort(pin);uint8_tstateMask=(state?bit:0);// convert the timeout from microseconds to a number of times through
// the initial loop; it takes approximately 16 clock cycles per iteration
unsignedlongmaxloops=microsecondsToClockCycles(timeout)/16;unsignedlongwidth=countPulseASM(portInputRegister(port),bit,stateMask,maxloops);// prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
if(width)returnclockCyclesToMicroseconds(width*16+16);elsereturn0;}
The inputs are pin, state and timeout. The types are uint8_t, uint8_t and unsigned long respectively. The return is unsigned long.
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
uint8_tbit=digitalPinToBitMask(pin);uint8_tport=digitalPinToPort(pin);
It sets stateMask and maxloops.
8
9
10
11
12
uint8_tstateMask=(state?bit:0);// convert the timeout from microseconds to a number of times through
// the initial loop; it takes approximately 16 clock cycles per iteration
unsignedlongmaxloops=microsecondsToClockCycles(timeout)/16;
The stateMask is a variable to check if the bit coresponds to the pin is 0 or 1. When the state is 0, it is set to 0 to measure the time of LOW state. If the state i not 0, it is set to bitmask of the pin.
The maxloops is the maximum loop numbers. The timeout(micro seconds) input parameter is converted to clock ticks using microsecondsToClockCycles(). See the comment in the source code.
The countPulseASM() is called to get how many it looped with the specified state.
16
17
18
19
20
21
// prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
if(width)returnclockCyclesToMicroseconds(width*16+16);elsereturn0;}
If the width is not 0, converts the width to microseconds using clockCyclesToMicroseconds() then retrun the value.