'Include "_FuncionesCapturaAnchoPulso.bas"
'FUNCIONES PARA LA LECTURA DEL ANCHO DE UN PULSO CON TMR1 ******
'By COS, 04/11/2018, 06/2014, 12/2013, Pic Simulator IDE v7.48 ********************
'************************************************************************************************
'************************************************************************************************
'FUNCIONES PARA LA LECTURA DEL ANCHO DE UN PULSO:
'************************************************************************************************
'_PinPulseWidthIn, _SetUp_PulseWidthIn(), _GetPulseWidthIn(), _PulseWidthIn()
'************************************************************************************************
'Symbol _PinPulseWidthIn = Pin, Asigna pin entrada del pulso a medir (GPx)
'_SetUp_PulseWidthIn(_Mhz)'Configura la función, el reloj y Tmr1
'_GetPulseWidthIn(_Flanco, _Tiempo de espera máximo) 'Devuelve tiempo en uSeg.
'_PulseWidthIn(_Mhz, _Flanco, _Tiempo de espera máximo, _Control)'Función principal.
'*************************************************************************************************
'**********************************************************************************
Symbol _pinpulsewidthin = RB4  'Se asigna pin para la lectura de la señal.
'La función configura el pin elegido como entrada.
'Call _setup_pulsewidthin(8)  'Inicializa función _pulsewidthin (oscilador y TMR1).
'**********************************************************************************
'Funcion para la configuración de reloj y TMR1.
'_mhz = Mhz del reloj del sistema.
'Call _setup_pulsewidthin(Mhz reloj).
'Activar la función auxiliar solo cuando se use
'----------------------------------------------------------------------------------
Proc _setup_pulsewidthin(_mhz As Byte)
	Call _pulsewidthin(_mhz, 0, 0, 1)
End Proc                                          
'----------------------------------------------------------------------------------
'Retorna una lectura en uSeg. que corresponde al ancho de la señal bajo medida
'_Getpulsewidthin = retorna la lectura en uSeg. en una variable tipo Long
'_phl = 1 lectura cuando la señal es 1, = 0 lectura cuando la señal es 0.
'_waitms = tiempo máximo de espera y tiempo máximo para la lectura.
'Lectura = _Getpulsewidthin(Flanco, Tiempo espera máximo)
'Activar la función auxiliar solo cuando se use
'----------------------------------------------------------------------------------
Function _getpulsewidthin(_phl As Bit, _waitms As Word) As Long
	_getpulsewidthin = _pulsewidthin(0, _phl, _waitms, 0)
End Function                                      
'----------------------------------------------------------------------------------
'Función principal para la lectura de un ancho de pulso externo.
'Devuelve un dato tipo Long en uSeg.
'_mhz = Mhz del reloj del sistema.
'_phl = 1 a medir desde flanco positivo, = 0 a medir desde flanco bajo.
'_waitms = Tiempo de espera y máximo ancho de lectura del pulso.
'_ctrl = configuración.
'Call _getpulsewidthin(Mhz reloj, Flanco, Espera máxima, Control).
'_getpulsewidthin > de 0 lectura en mm, = 0 error de lectura.
'Symbol _pinpulsewidthin = RB4  'Se asigna pin por donde se aplicará la señal.
Function _pulsewidthin(_mhz As Byte, _phl As Bit, _waitms As Word, _ctrl As Byte) As Long
	Dim _regtimer1mseg As Word
	Dim _conta As Word
	Dim _conta1 As Word
	Dim _aux_mhz As Byte

	_pulsewidthin = 0  'Se marca error de lectura por defecto
	_conta = _waitms
	_conta1 = _waitms

	If _ctrl = 1 Then  'Inicializa la función
		ConfigPin _pinpulsewidthin = Input  'Pin como entrada
		'Factor corrección a mSeg.
		_aux_mhz = _mhz / 4
		_regtimer1mseg = 65535 - (_aux_mhz * 1000)
		Call _setup_timer1(_tmr1_internal, _tmr1_div1)  'Configura el timer1
		Call _timer1(True)  'Activa el timer1
		'Call _disable_interrupts(_int_timer1)  'Desactiva las interrupciones del Timer1
		Exit  'Fuerza la salida de la función
	Endif

	If _waitms = 0 Then Exit  'No se cuenta, se sale
	
	'Se espera hasta flanco correcto.
	Call _set_timer1(_regtimer1mseg)  'Carga el timer para que cuente 1mSeg.
	While _pinpulsewidthin <> _phl  'Se espera hasta que el flanco sea el correcto
		If _tmr1if = True Then  'Decrementa tiempo si desbordó el Timer
			Call _set_timer1(_regtimer1mseg)  'Carga el timer para que cuente 1mSeg.
			_conta1 = _conta1 - 1  'Descueta tiempo
			If _conta1 = 0 Then Exit  'Se sobrepaso el tiempo y se sale
		Endif
	Wend
	
	'Se inicia la lectura
	Call _set_timer1(_regtimer1mseg)  'Carga el timer para que cuente 1mSeg.
	While _pinpulsewidthin = _phl  'Se espera hasta que el sensor indique fin de lectura
		If _tmr1if = True Then  'Decrementa tiempo si desbordó el Timer
			Call _set_timer1(_regtimer1mseg)  'Carga el timer para que cuente 1mSeg.
			_conta = _conta - 1  'Descuenta tiempo
			If _conta = 0 Then Exit  'Se sobrepaso el tiempo y se sale
		Endif
	Wend

	'Se asigna la lectura en uSegundos.
	_pulsewidthin = _get_timer1()  'Asigna la lectura del Timer
	_pulsewidthin = 65535 - _pulsewidthin  'Última lectura
	_conta1 = _aux_mhz * 1000  'Factor oscilador reloj
	_pulsewidthin = _conta1 - _pulsewidthin  'Tic contados por el timer, ultima lectura
	_pulsewidthin = _pulsewidthin / _aux_mhz  'Ultima lectura en uSeg.
	_conta = (_waitms - _conta) * 1000  'Pasa los mSeg. acumulados a uSeg.
	_pulsewidthin = _pulsewidthin + _conta  'Totaliza el tiempo en uSeg.
End Function                                      
'*******************************************************************************************