Los héroes eléctricos me ayudan con el diseño del frecuencímetro digital. ¡Muchas gracias!
Se espera lograr una medición de frecuencia precisa en el rango de 10Hz-1,1g.
Diagrama del circuito experimental (plano preliminar)
1) Circuito de conteo y visualización:
2) Circuito de preamplificador y divisor de frecuencia:
Concepto de diseño
La medición de la frecuencia en realidad consiste en contar las señales dentro de 1, y el valor calculado es la frecuencia de la señal. Generalmente existen dos métodos para diseñar un frecuencímetro con un microcontrolador: 1) Usar el contador del microcontrolador para contar los pulsos de entrada o medir el período de la señal 2) Usar un contador externo al microcontrolador para contar la señal de pulso; y el valor de conteo es leído por el microcontrolador.
Dado que la frecuencia del reloj de entrada del contador del microcontrolador suele ser solo una fracción o incluso unas pocas décimas de la frecuencia del reloj del sistema, el uso directo del contador del microcontrolador para medir la frecuencia de la señal está muy restringido.
Este experimento utiliza un contador binario de cuatro bits 74LS393 de Atmega8 y un contador T1 para formar un contador de 24 bits. El valor de recuento máximo es 16777215. Si la señal de entrada se mide después de dividirla por el divisor de frecuencia MB501, bajo una base de tiempo fija de 1S, la frecuencia de medición más alta es 1073,45438+0760 MHz.
Para obtener una señal de puerta de medición precisa de 1 segundo, utilizamos la función de reloj asíncrono en tiempo real de Atmega8 y utilizamos un oscilador de cristal de 32,768 Khz para generar una señal de sincronización de 1 segundo desde TC2.
Principio de medición:
El microcontrolador abre la puerta de medición, es decir, PB1 emite un nivel alto y el temporizador TC2 se inicia al mismo tiempo. El 74LS393 comienza a contar los pulsos de entrada. Cuando el 74LS393 cuenta hasta 256, el contador T1 del Atmega8 también cuenta 1 vez. Cuando 1 alcanza el tiempo fijo, el microcontrolador genera una interrupción, PB1 genera un nivel bajo para cerrar la puerta de medición, y luego Atmega8 lee los valores de conteo de 74LS393 y T1, y luego los envía a la pantalla LCD para su visualización.
Progreso experimental
2004-09-27
Según la idea de diseño, se obtuvieron algunos resultados experimentales, como se muestra en la siguiente figura. La siguiente figura muestra los resultados de salida de la medición del oscilador de cristal activo 8M.
Dado que el tiempo de prueba de la puerta 1S no es fácil de probar en condiciones de aficionados, el reloj en tiempo real se muestra en la pantalla LCD al mismo tiempo en el programa experimental para juzgar la precisión del tiempo de prueba de la puerta 1S. . En el experimento, utilicé la hora exacta del satélite GPS que se muestra en el teléfono móvil CDMA para comparar. La unidad de tiempo más pequeña que se muestra en el teléfono móvil son los minutos. Durante la medición, una vez que salta el valor de los minutos del teléfono móvil, el segundo valor mostrado en la pantalla LCD se registrará inmediatamente. En este caso, después de que el frecuencímetro haya estado funcionando durante un período de tiempo, los segundos mostrados en la pantalla LCD se registrarán varias veces, de modo que se pueda juzgar con precisión si el reloj asíncrono del frecuencímetro es exacto. Durante el experimento, dejé que el medidor de frecuencia alcanzara aproximadamente 10 decimales y el reloj 1S medido seguía siendo muy preciso.
#incluye
#incluye
#incluye lcd.h
#incluye 6x8.h
# Contiene chino h
/* -
LCD_init: inicialización de 3310LCD
Fecha de redacción: 10 de agosto de 2004
Última actualización Fecha: 10 de agosto de 2004
- */
void LCD_init(void)
{
Puerto & amp= ~ LCD_RST; //Genera un pulso bajo para restablecer la pantalla LCD.
delay_1us();
PORTB | = LCD_RST;
PORT&=~LCD_CE // Apagar la pantalla LCD.
retraso _ 1us();
PORTB | = LCD _ CE //Habilitar LCD
retraso _ 1us(); LCD_write_byte(0x21, 0); //Utilice comandos extendidos para configurar el modo LCD.
LCD_write_byte(0xc8, 0); //Establece el voltaje de polarización
LCD_write_byte(0x06, 0); //Corrección de temperatura
LCD_write_byte(0x13, 0); ); // 1:48
LCD_write_byte(0x20, 0); //Usa comandos básicos
LCD_clear() //Borrar la pantalla
LCD_write_byte (0x0c, 0); //Establece el modo de visualización en visualización normal.
port&=~LCD_CE//Apaga la pantalla LCD.
//LCD _ clear();
}
/* -
LCD_clear: Función de borrado de la pantalla LCD.
Fecha de redacción: 10 de agosto de 2004
Última actualización: 10 de agosto de 2004
- */
void LCD_clear (nulo)
{
Ent sin signo I;
LCD_write_byte(0x0c, 0);
LCD_write_byte(0x80, 0);
for(I = 0;i<504;i++)
LCD_write_byte(0, 1);
}
/* -
LCD_set_XY: Establece la función de coordenadas LCD.
Parámetros de entrada: x: 0-83
Y: 0-5
Fecha de redacción: 10 de agosto de 2004
Última actualización: 10 de agosto de 2004
- */
void LCD_set_XY (carácter sin firmar X, carácter sin firmar Y)
{ p>
LCD_write_byte(0x40|Y,0); //Columna
LCD_write_byte(0x80|X,0); //Fila
}
/* -
LCD_write_char: muestra caracteres en inglés.
Parámetros de entrada: c: caracteres mostrados;
Fecha de escritura: 10 de agosto de 2004
Fecha de última actualización: 10 de agosto de 2004
- */
void LCD_write_char(carácter sin firmar c)
{
Línea de carácter sin firmar;
//c- = 32;
//for(línea = 0; línea & lt6;línea++)
//LCD _ escritura _ byte(fuente 6x 8[c] [línea], 1 );
for(línea = 0; línea & lt7;línea++)
LCD _ escritura _ byte(fuente 7x 13[c][línea], 1 );
for(línea = 7; línea & lt14;línea++)
LCD _ escritura _ byte(fuente 7x 13[c][línea], 1);
}
/* -
LCD_write_char: función de visualización de cadena en inglés
Parámetros de entrada: *s: puntero de cadena en inglés;
x, y : muestra la posición de la cadena.
Fecha de redacción: 10 de agosto de 2004
Última actualización: 10 de agosto de 2004
- */
void LCD_write_String( carácter sin firmar ;
mientras (*s)
{
LCD_set_XY(X+i*7, Y);
for( línea = 0; línea & lt7; línea++)
LCD _ escribir _ byte(fuente 7x 13[* s-0x 30][línea], 1);
LCD_set_XY(X +i *7, Y+1);
for(línea = 7; línea & lt14;línea++)
LCD _ escritura _ byte(fuente 7x 13[* s-0x 30] [línea], 1);
s++;
i++; /* -
LCD_write_chi: muestra caracteres chinos en la pantalla LCD.
Parámetros de entrada: x, y: muestra las coordenadas x, y iniciales de los caracteres chinos
Ch_with: el ancho de la red de caracteres chinos
Num: muestra el número de caracteres chinos;
Línea: el número de línea inicial en la matriz de puntos de caracteres chinos.
Línea: Muestra el espacio entre líneas de caracteres chinos.
Fecha de redacción: 11 de agosto de 2004
Última actualización: 12 de agosto de 2004.
- */
void LCD_write_chi(carácter sin firmar X, carácter sin firmar Y,
carácter sin firmar ch_with, número de carácter sin firmar,
Línea de carácter sin signo, línea de carácter sin signo)
{
Carácter sin signo I, n;
LCD_set_XY(X, Y); /p>
for(I = 0; i{
for(n = 0; n{
If (n==ch_with) / /Escribe la parte inferior de el carácter chino
{
if (i==0) LCD_set_XY(X, Y+1
Otros
LCD_set_XY); ((X+(ch_with+row)*i),Y+1);
}
LCD _ escritura _ byte(China _ char[línea+I ][n], 1);
}
i++;
LCD_set_XY((X+(ch_with+row)*i),
; p>
}
}
/* -
LCD_write_chi: movimiento de caracteres chinos
Parámetros de entrada: x, y: muestra las coordenadas x, y iniciales de los caracteres chinos
t: velocidad de movimiento
Fecha de redacción: 13 de agosto de 2004
Fecha de la última actualización: 8, 2004 Mes-13.
- */
void LCD_move_chi(carácter sin firmar X, carácter sin firmar Y, carácter sin firmar T)
{
Carácter sin firmar I , n, j = 0;
Búfer de caracteres sin firmar _ h[84]= { 0 }
Búfer de caracteres sin firmar _ l[84]= { 0 };
for(I = 0;i<156;i++)
{
buffer _ h[83]= China _ char[I/ 12][j]; p>
buffer _ l[83]= China _ char[I/12][j+12];
j++;
if(j = = 12)j = 0;
for(n = 0;n & lt83;n++)
{
búfer _ h[n ]= buffer_h[n+1] .
Buffer_l[n]=buffer_l[n+1];
}
LCD_set_XY(X, Y);
para( n = 0; n & lt83;n++)
{
LCD_write_byte(buffer_h[n], 1);
}
LCD_set_XY(X, Y+1);
for(n = 0; n & lt83;n++)
{
LCD_write_byte (buffer_l[n], 1);
}
retraso _ NMS(T);
}
}
/* -
LCD_draw_map: función de dibujo de mapa de bits
Parámetros de entrada: x, y: coordenadas x, y iniciales para el dibujo de mapa de bits;
*map: datos de red de mapa de bits;
Pix_x: Píxeles de mapa de bits (largo)
Pix_y: Píxeles de mapa de bits (ancho)
Fecha de redacción: 13 de agosto de 2004
Fecha de última actualización: agosto de 2004-13.
- */
void LCD_draw_map(carácter X sin firmar, carácter Y sin firmar, mapa de caracteres sin firmar *map
Carácter sin firmar Pix_x, carácter sin firmar Pix_y)< /p >
{
Sin firmar int i, n;
Línea de caracteres sin firmar
if(Pix _ y % 8 = = 0 )fila = Pix _ y/8; //Calcula el número de filas ocupadas por el mapa de bits.
Otros
fila = Pix _ y/8+1;
for(n = 0; n{
LCD_set_XY(X , Y);
for(I = 0;i{
LCD_write_byte(map[i+n*Pix_x], 1);
} p>
y++; //Nueva línea
}
}
/* -
LCD_write_byte: utiliza la interfaz SPI para escribir datos Escribir en LCD
Parámetros de entrada: datos: datos escritos
Comando: escribir datos/selección de comando
Fecha de escritura: 10 de agosto de 2004
Última actualización: 13 de agosto de 2004.
- */
void LCD_write_byte (datos de caracteres sin firmar, comando de caracteres sin firmar)
{
Puerto & amp= ~ LCD_CE/ /Habilitar LCD
if(command == 0)
port & amp= ~ LCD_DC //Enviar comando
Otro
PORTB | = LCD_DC; //Transferir datos
SPDR = datos; //Transferir datos al registro SPI
Y ((SPSR & amp; 0x 80) = = 0); /Esperar a que se complete la transmisión de datos
PORTB | = LCD_CE//Apagar la pantalla LCD.
}