Resolución

Anuncio
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).
Descargar