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.
/*
Copyright (c) 2019 garretlab.
Added source code explanation by garretlab.
*//*
wiring_pulse.c - pulseIn() function
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/