//Práctica 3
//Definimos los pines
const int senyal_entrada = 18; // GPIO pin interrupcion para la entrada de señal
//Valores de la frecuencia y periodo de la función que queremos crear
float t_medida=1; //Empezamos con 1 segundo (tiempo de visualizacion de la señal)
//Variables globales de las interrupciones
//HAY QUE PONERLOS COMO VOLATILES!!
volatile float nflancos=0; //Cuenta el número de flancos
volatile int subida=0;//VA A REGISTRAR SI PULSAMOS EL BOTON DE AUMENTAR 1 SEGUNDO
volatile int bajada=0;//VA A REGISTRAR SI PULSAMOS EL BOTON DE DISMINUIR 1 SEGUNDO
volatile int cuenta1=0; //Regista cuando pasa el tiempo de conteo de la frecuencia
//Variales para los timers (timer cada segundo y timer2 cada mitad de periodo)
hw_timer_t * timer = NULL; //puntero a la estructura
#define temp1 1
#define temp2 2
#define temp0 0
#define fprescaler 80e6 //Definido por el microprocesador
#define prescaler 290 //200 + 10 *9 (puesto 9)
volatile float valor_cuenta=fprescaler/prescaler; //valor para obtener 1 segundo
volatile float nuevo_valor=valor_cuenta; //inicialmente
//PARA EVITAR LOS REBOTES
int cts=0;//tiempo de subida
int ctb=0;//tiempo de bajada
////////////////////////////////////////////////////////////////////
//ISR Cuenta el número de flancos
void IRAM_ATTR ISR_senyal(){
nflancos++;
}
// ISR Registra cuando pasa el tiempo de conteo de la frecuencia
void IRAM_ATTR finTimer() {
cuenta1=1;
}
//ISR Aumenta el tiempo de medida 1 segundo
void IRAM_ATTR ISR_sube(){
if(millis()>cts+300)
subida =1;
cts=millis();
}
//ISR Disminuye el tiempo de medida 1 segundo
void IRAM_ATTR ISR_baja(){
if(millis()>ctb+300)
bajada =1;
ctb=millis();
}
///////////////////////////////////////////////////////////////////
void setup(){
Serial.begin(115200);
Serial.printf("\n\n Práctica 3: Interrupciones y timers\n");
Serial.print("Para cambiar la frecuencia introduzca el valor deseado en cualquier momento\n");
attachInterrupt(digitalPinToInterrupt(18), ISR_senyal, FALLING);//configuro el pin como entrada de interrupción
//en el pin 18 cuando se detecte un flanco descendente, se ejecuta la funcion ISR_senyal(cuenta el número de flancos)
attachInterrupt(digitalPinToInterrupt(32), ISR_sube, FALLING);//configuro el pin como entrada de interrupción
//en el pin 23 cuando se detecte un flanco descendente, se ejecuta la funcion ISR_sube(aumenta 1 segundo el tiempo de visualización)
attachInterrupt(digitalPinToInterrupt(33), ISR_baja, FALLING);//configuro el pin como entrada de interrupción
//en el pin 18 cuando se detecte un flanco descendente, se ejecuta la funcion ISR_baja(disminuye 1 segundo el tiempo de visualización)
/*Configuramos 2 timers
- timer -> Para definir el tiempo de toma de la frecuencia
- timer2 -> Define el tiempo de la frecuencia de la señal */
//Inicializamos los timers, contando en el flanco ascendente de la señal de reloj
timer = timerBegin(temp0, prescaler, true);
//Indicamos la función de interrupción que se activa al pasar el tiempo deseado
timerAttachInterrupt(timer, &finTimer, true);
// 80 MHz / prescaler 290 => valor cuenta = 2,75862e5 tics / sec
timerAlarmWrite(timer, valor_cuenta, true); //Alarma que se activa cada x segundo
//Activamos las alarmas
timerAlarmEnable(timer);
}
//////////////////////////////////////////////////////////////////////
void loop()
{
//Para aumentar 1 segundo el tiempo de la visualización de la frecuencia
if(subida ==1 && nuevo_valor < valor_cuenta*9)
{
timerAlarmDisable(timer); //Se desactiva el timer
nuevo_valor += valor_cuenta ; //se suma 1 segundo a lo de antes
t_medida = nuevo_valor/valor_cuenta;
timerAlarmWrite(timer, nuevo_valor, true); // se ejecuta a lo de antes + 1
timerWrite(timer, 0); //El valor del timer se pone a 0
timerAlarmEnable(timer); //Se vuelve a activar
subida=0;
}
//Para disminuir 1 segundo el tiempo de la visualización de la frecuencia
if(bajada == 1 && nuevo_valor > valor_cuenta) //De forma análoga a la función anterior
{
timerAlarmDisable(timer);
nuevo_valor -= valor_cuenta ; //se resta 1 segundo a lo de antes
t_medida = nuevo_valor/valor_cuenta;
timerAlarmWrite(timer, nuevo_valor, true); // se ejecuta a lo de antes + 1
timerWrite(timer, 0);
timerAlarmEnable(timer);
bajada=0;
}
if(cuenta1==1){//si se ha ejecutado la rutina de interrupcion del timer (temp0)
cuenta1=0;
float valor_frec=nflancos/t_medida;
Serial.printf("Frec:%4.2f hz - nflancos: %.0f en %.0f s \n ", valor_frec, nflancos, t_medida );
nflancos=0;
}
}