Hola.
Sí se pueden conectar dos periféricos a un mismo pin, no se si mediante el MCC se puede hacer esto, yo lo hice manualmente:
También me di cuenta que no debía hacer la deshabilitación de los periféricos en la función cambiarProceso, esta sólo debe inicializar la tarea de muestro y el del cálculo del RMS
void cambiarProceso(void)
{
APPSAMPLING_Initialize(); // Reinicio la tarea de muestreo
APPRMS_Initialize(); // Reinicio la tarea que calcula el valor RMS
}
En cambio, en el primer estado de la tarea de muestro (APPSAMPLING), debo en función de la bandera medirFrecuencia, deshabilitar un periférico y habilitar el otro.
case APPSAMPLING_ESTADO_INICIAL:
{
if (apppulsadorData.medirFrecuencia)
{
/** Deshabilito todo lo relacionado con el cálculo del valor RMS**/
EVIC_ExternalInterruptDisable(EXTERNAL_INT_2); //detengo la interrupción por interrupción externa
EVIC_SourceStatusClear(INT_SOURCE_EXTERNAL_2); //limpio la bandera por interrupción externa
TMR4_Stop(); //detengo al temporizador 4
TMR4_InterruptDisable(); //deshabilito la interrupción del temporizador 4
EVIC_SourceStatusClear(INT_SOURCE_TIMER_4); //limpio la bandera por interrupción de tmr4
ADC_Disable(); //deshabilito al módulo ADC
EVIC_SourceStatusClear(INT_SOURCE_ADC); //limpio la bandera por interrupción del ADC
/*************************************************/
ICAP1_Enable();
TMR2_Start();
ICAP1_CallbackRegister(ManejarInterrupcionModuloCaptura, (uintptr_t)NULL);
appsamplingData.captura = 0x0000;
}
else
{
/** Deshabilito todo lo relacionado con el cálculo del periodo de la señal**/
ICAP1_Disable(); //Deshabilito el módulo de captura
TMR2_Stop();
EVIC_SourceStatusClear(INT_SOURCE_INPUT_CAPTURE_1); // limpio bandera del módulo de captura.
/*************************************************/
TMR4_Stop();
TMR4_CallbackRegister(ManejarInterrupcionTMR4, (uintptr_t) NULL);// registro función de interrupción por TMR4
ADC_CallbackRegister(ManejarInterrupcionADC, (uintptr_t)NULL); // registro función de interrupción por ADC
EVIC_ExternalInterruptCallbackRegister(EXTERNAL_INT_2, &ManejarInterrupcionExterna, (uintptr_t)NULL); //Registro la función que se llama por la interrupción externa
EVIC_ExternalInterruptEnable(EXTERNAL_INT_2); // Habilito la interrupción externa 2
TMR4_InterruptEnable();
ADC_Enable();
}
appsamplingData.state = APPSAMPLING_ESTADO_REPOSO;
break;
}
El error que mencioné antes que cuando presionaba el pulsante para regresar a medir la frecuencia, era debido a que TMR4 y el ADC eran deshabilitados, y eran necesario volver a activarlos. (
Línea 32 y 32 del código de arriba)
El código inicial que usé para visualizar la frecuencia fue así:
void ManejarInterrupcionModuloCaptura(uintptr_t context)
{
appsamplingData.captura = ICAP1_CaptureBufferRead() - appsamplingData.captura;
rmsDisplay(750000.000/((float)(diferencia)));
}
}
Pero en el display salía cualquier cosa, menos un valor cercano, sólo la primera vez que sucedía la interrupción del comparador, se obtiene un valor que corresponde a 60Hz.
Luego de darle vueltas a lo que estaba pensando y analizando el código de ejemplo de Microchip que mide tiempo con el comparador que es este:
while ( true )
{
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
while(!ICAP1_CaptureStatusGet());
capturedValue[captureIndex++] = ICAP1_CaptureBufferRead();
if ( captureIndex > 1){
printf("Pulse Width Count = %d\r\n",(capturedValue
[1] - capturedValue
[0])); captureIndex = 0;
}
}
Me di cuenta que deben tomarse dos muestras, y realizar la diferencia entre las dos para obtener el valor medido, así que cambié la variable captura a un arreglo de 2 palabras con su índice.
Y realicé un código similar al ejemplo de Microchip:
void ManejarInterrupcionModuloCaptura(uintptr_t context)
{
appsamplingData.captura[appsamplingData.indiceCaptura++] = ICAP1_CaptureBufferRead();
if (appsamplingData.indiceCaptura > 0x01)
{
uint32_t diferencia = appsamplingData.captura[0x01] - appsamplingData.captura[0x00];
if (diferencia)
{
rmsDisplay(750000.000/((float)(diferencia)));
}
appsamplingData.indiceCaptura = 0x00;
}
}
Nótese que hay un if (diferencia), ya que a veces, cuando presiono el pulsador para cambiar a medir frecuencia, el microcontrolador, reinicia. Pensaba que podía estar realizándose un división para cero, pero sigue pasando, es algo que debo revisar.
Y este es el resultado, obviamente, el cambio de la información el el display es mucho más rápido, me imagino que se debe a que al medir la frecuencia, no demora al CPU ya que no hace cálculos como en el caso del RMS.
El cambio en el display es muy rápido, es algo que debo corregir, pero se puede ver al poner pausa que el valor medido es de 60 Hz:
Pero también se visualizar un valor igual a cero, y a pesar que está controlado que si la diferencia tiene ese valor, no se muestre en el display, es algo que debo investigarloTambién aparece la alarma de "bajo voltaje", ya que dicho proceso toma el valor de 60 como voltaje y esa es la razón.
Debería también crear otros límites cuando se está midiendo la frecuencia. Según busqué, el error es de 5Hz, es decir la frecuencia no debe ser mayor a 60.5Hz o menor a 59.5 Hz.