UN CÓDIGO POSIBLE PARA EL EJERCICIO PRÁCTICO #include <p24FJ128GA010.h> // #include <config.h> char i; int tiempos[10]; //Array de elementos tipo int (16 bits) int captura, ms, temp_prev; int main (void) { //CONFIGURAMOS EL ESCALADO DEL OSCILADOR PRINCIPAL _COSC = 0b111; //Oscilador interno con postscaler _RCDIV = 0b111; //Escalamos al máximo: 1:128; // CONFIGURAR PUERTOS PORTA = 0; TRISA = 0xff00; // Todos los pines como salida (LEDs) _TRISD8 = 1; // Pin 8 del puerto D (IC1) en modo entrada //HABILITACIÓN Y CONFIGURACIÓN DEL TIMER ASOCIADO AL MÓDULO IC T2CON = 0x8020; // Habilitado, fac. escala 1:64, reloj interno // Así dejamos el reloj del contador a 976.56 Hz (casi 1KHz) TMR2 = 0; // Ponemos el temporizador a cero //CONFIGURACIÓN Y ACTIVACION DEL MÓDULO DE CAPTURA CANAL 1 IC1CON = 0x0000; // Reseteamos el modulo de captura IC1CON = 0x0084; // Interrupción en cada captura (cada cuatro flancos ascendentes) //DESACTIVAR FLAG DE INTERRUPCIÓN DEL IC1 (por si acaso) _IC1IF = 0; // HABILITAR INTERRUPCION MÓDULO DE CAPTURA _IC1IE = 1; //BUCLE PRINCIPAL (bucle infinito) i=0; temp_prev=0; while (1); } //**********************ISR**************************** // Rutina de servicio de interrupción /********************************************************/ void __attribute__((interrupt,no_auto_psv)) _IC1Interrupt(void) { PORTA ^= 0xFF; //Invertimos los LEDs captura = IC1BUF; //Leemos el valor del timer2 en la FIFO del módulo IC ms = (captura-temp_prev)/0.976; //Afinamos el valor de conteo a 1ms (freq. reloj es 976 Hz) //Aquí he supuesto que no se llega al límite del timer //Otra opción sería poner el timer a cero tras cada interrupción: // TMR2 = 0; //ms=captura/0.976 //y evitaríamos tener que calcular la diferencia entre capturas temp_prev = captura; tiempos[i] = ms; //Guardamos el valor capturado en el array if (i==9) //Si hemos llegado al final, empezamos de nuevo i=0; else i++; //SI no, apuntamos el siguiente elemento IC1CON = 0x0000; //Reseteamos el modulo de captura IC1CON = 0x0084; //Reactivamos el modulo de captura IFS0bits.IC1IF = 0; //Desactivamos el flag de interrupción } ESQUEMA DEL CIRCUITO DESCRITO MEDIANTE VHDL library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity modulua is Port ( w : in STD_LOGIC_VECTOR (7 downto 0); clk, rst : in STD_LOGIC; salida : out STD_LOGIC); end modulua; architecture dos_segmentos of modulua is signal r_reg, r_next: unsigned(7 downto 0); signal buf_reg, buf_next: std_logic; begin process (clk, rst) begin if (rst='1') then r_reg <= (others => '0'); buf_reg <= '0'; elsif (clk'event and clk='1') then r_reg <= r_next; buf_reg <= buf_next; end if; end process; r_next <= r_reg + 1; buf_next <= '1' when ((r_reg < unsigned(w)) or (w="00000000")) else '0'; salida <= buf_reg; end dos_segmentos; Este circuito consta de un contador, un comparador, y un buffer de salida. Mediante la entrada w se puede controlar el tiempo que la salida está a ‘1’ con una resolución de 1/256 (contador de 8 bits). Es decir, este es un circuito para generar señales PWM (se ha omitido la entrada de reset a los registros).