Académique Documents
Professionnel Documents
Culture Documents
Conocido
con el bus SPI.
Publicado en 9 de enero de 2017por Narod Stream Publicado en SPI , Programación AVR - 2 comentarios ↓
Lección 24
Conocer el bus SPI
Hoy estamos empezando a familiarizarnos con el bus SPI (Interfaz Periférica
Serial) .
Este neumático es muy utilizado en electrónica. Es muy conveniente, ya que es
síncrono y dúplex completo, por lo tanto, se utiliza en muchos esquemas para la
comunicación entre varios dispositivos digitales: sensores, controladores, controladores
y otros dispositivos.
Otro factor importante en la necesidad de nuestra relación con ella es que este bus es
un hardware organizado en controladores AVR .
Además, ya sea que lo queramos o no, nos hemos estado comunicando con la
interfaz SPI hace mucho tiempo, tan pronto como comenzamos a actualizar nuestro
controlador por primera vez, ya que se muestra a través de esta interfaz.
Por lo tanto, quiero familiarizarme con este neumático más cerca.
Vamos a abrir la documentación técnica para el controlador Atmega8, abrir la página
donde se muestra el pinout de este controlador y ver que de 16 a 19 patas y hay
terminales de bus SPI
Ahora un poco más sobre estos hallazgos.
SS (chip select) es el pie de selección del dispositivo. Si el dispositivo esclavo en
este tramo se establece en un nivel bajo, entonces este dispositivo responderá e
intercambiará información en el bus SPI, si es alto, no lo hará.
MOSI (entrada esclava de salida maestra) es el pin de la salida del dispositivo
maestro y la entrada del dispositivo esclavo.
MISO (salida del esclavo de la entrada maestra) : por el contrario, la salida del
esclavo, la entrada del maestro.
SCK - sincronizar la pierna. Todos los dispositivos que participan en el intercambio
de información en este bus se suministran con pulsos de sincronización con una cierta
frecuencia.
Estudiaremos todo esto en las siguientes clases con más detalle cuando usaremos
ciertos dispositivos en nuestros proyectos.
Bueno, parece que descubrimos los circuitos de transmisión de datos en el bus SPI.
Ahora averigüemos cómo administrar este proceso en el nivel de los registros de
hardware del controlador AVR.
Estos registros que vemos en el diagrama de flujo de arriba en la página.
Atmega8 tiene los siguientes registros para el servicio de bus SPI.
SPDR (Registro de datos SPI) es un registro de datos, en el diagrama de bloques es un BUFFER
DE DATOS. En este registro agregaremos un byte para su posterior transferencia al dispositivo
esclavo y, a partir de él, leeremos el byte de información que proviene del dispositivo
esclavo. Tampoco es necesario que nuestro controlador sea un maestro. Posteriormente, armaremos
un circuito de dos controladores, uno de los cuales será el esclavo. Entonces, ¿qué es exactamente en
este registro un byte para el envío y la recepción.
SPCR (registro de control SPI) - registro de control
Aquí hay una relación tan interesante. A veces vemos en las características técnicas de
un dispositivo que, por ejemplo, puede funcionar en modo SPI 0: 0 y SPI 1: 1, esto es
exactamente lo que concierne al ajuste de estos bits.
SPR1, SPR0 (SPI Clock Rate Select) son los bits responsables del valor del divisor
de frecuencia de sincronización, trabajan en conjunto con el bit SPI2X , ubicado en el
registro de estado. También es administrador, ya que ocho bits en el registro de control
no fueron suficientes para todos los ajustes, y hay muchos de los libres en el registro de
estado.
SPI2X (Bit de velocidad SPI doble) es un bit que duplica la velocidad, trabajando en
conjunto con los bits SPR1 y SPR0 del registro de control.
Veamos la dependencia de la frecuencia en los datos de tres bits.
Lección 25
SPI. Conecte el registro de
desplazamiento 74HC595
Hoy continuaremos trabajando con el bus SPI , que aprendimos en la lección
anterior . Más bien, lo continuaremos: para estudiar este bus, solo la lección ahora será
práctica. Tomaremos un determinado dispositivo e intentaremos controlar este
dispositivo.
Y como dispositivo, tomamos el chip 74HC595 más simple , que está controlado por
la interfaz SPI y es un registro de desplazamiento. A juzgar por la documentación técnica
de este registro, el desarrollador es Philips.
Preste atención a algunas de las características técnicas de este registro de
desplazamiento.
La frecuencia de reloj límite no debe exceder de 100 MHz, por lo que con nuestra
frecuencia de reloj de 8 o 16 MHz del controlador, es poco probable que excedamos esta
frecuencia.
Voltaje de alimentación del chip - de 2 a 6 V.
Este chip existe en dos tipos de casos: el DIP habitual, así como DHVQFN16.
Usaremos la primera opción, así que veremos el pinout para esta opción.
Q0-Q7 - ocho salidas paralelas para uso general. Estas salidas son necesarias para que
podamos utilizar de alguna manera los datos entrantes en SPI: conectar una línea de LED,
segmentos de un indicador, un decodificador, etc.
VCC - tensión de alimentación.
GND es un cable común.
Q7 ' - salida de datos en serie. El mismo miso .
DS - Entrada de datos en serie o MOSI .
MR es un reinicio maestro. Se estudiará durante el uso.
SH_CP - en nuestro caso será chip select.
ST_CP es la parte de control del registro de almacenamiento, en nuestro caso será la parte de
sincronización, a la que enviaremos pulsos de reloj.
OE - salida de activación. Con un valor negativo, la salida serial está activada, con un
valor positivo, está deshabilitada.
#ifndef MAIN_H_
#define MAIN_H_
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#endif /* MAIN_H_ */
#include "main.h"
int main(void)
{
unsigned int i=0;
DDRB |= ((1<<PORTB2)|(1<<PORTB3)|(1<<PORTB5)); //ножки SPI на выход
PORTB &= ~((1<<PORTB2)|(1<<PORTB3)|(1<<PORTB5)); //низкий уровень
while(1)
{
}
}
SPDR = 0b00000000;
while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
Por lo tanto, en este código, formamos un nivel lógico bajo en todas las etapas de la
salida paralela del chip, y los LED tendrán que apagarse si de repente nos iluminamos al
inicio.
Esperemos dos segundos y repetimos lo mismo otra vez, pero con todas las unidades
lógicas en el registro de datos, por lo tanto, todos los LED conectados a la salida paralela
del chip deberían estar encendidos. Luego espera otros dos segundos
int main(void)
{
unsigned int i=0;
while(1)
{
for (i=0;i<256;i++)
{
SPDR = i;
while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
//сгенерируем отрицательный фронт для записи в STORAGE REGISTER
PORTB |= (1<<PORTB2); //высокий уровень
PORTB &= ~(1<<PORTB2); //низкий уровень
_delay_ms(50);
}
i=0;
}
Recoja el código, ejecute el controlador y vea el resultado de nuestro trabajo en el
código.
Lección 26
SPI. Conecte el indicador LED
Seguimos trabajando con el bus SPI . En la última lección, aprendimos cómo trabajar
con el registro de desplazamiento 74HC595 .
Hoy, también continuaremos trabajando con este registro, pero hoy intentaremos
conectar un indicador LED de siete dígitos de un solo segmento.
Creo que se verá más interesante que las luces encendidas en la tira de LED.
Conectamos el ánodo común del indicador al bus de alimentación y los segmentos al
registro a través de las resistencias limitadoras de corriente de esta manera
Las entradas de control del registro permanecieron sin nombre conectadas de la misma
manera que en la lección anterior.
Mi indicador, que conecté, es un pinout
En la práctica, se ve algo como esto.
El proyecto se creó con el nombre SPI_LED , el código se tomó completamente de la
última lección para evitar la configuración inicial y la configuración de inicialización.
Si ahora convertimos nuestro proyecto en un proteus, entonces el código anterior
funcionará para nosotros, solo los segmentos que brillaron en la última lección, por el
contrario, no se iluminarán, por lo que los LED están conectados en el orden inverso y no
al bus común, sino a bus de potencia
Hasta el bucle sin fin, el código en la función main () será así
Es decir, dejaremos aquí enviando todos los ceros al registro y dejaremos el retraso
500. Es decir, tendremos que iluminar todos los segmentos involucrados del indicador,
ya que tiene un ánodo común y su estado activo es bajo.
while (1)
{
// 1
SPDR = 0b11111001 ;
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
// generar un borde negativo para escribir en el REGISTRO DE ALMACENAMIENTO
PORTB | = (1 << PORTB2 ); // nivel alto
PORTB & = ~ (1 << PORTB2 ); // nivel bajo
_delay_ms ( 500 );
Luego podemos copiar el código varias veces y corregir en él los valores ingresados
en el registro SPDR .
Aquí está el código completo del bucle infinito (código debajo del spoiler, presione
" + ")
mientras ()
Lección 27
SPI. LED - indicación dinámica
Continuar trabajando con el bus SPI. También trabajaremos con el mismo microcircuito del registro
de desplazamiento 74HC595 , estamos trabajando con este microcircuito por tercera vez. Este
microcircuito nos atrajo por el hecho de que cuesta solo unos centavos, así como por el hecho de que
no es muy difícil de configurar y que se conecta al controlador a través del bus SPI. Todos estos
factores nos permitieron elegir este registro en particular para las lecciones iniciales del autobús SPI.
En la última lección, conectamos un indicador LED de siete segmentos a este chip y aprendimos cómo
controlarlo.
Hoy conectaremos un indicador de cuatro dígitos y también trataremos de controlarlo.
En consecuencia, para este propósito no tendremos suficiente un registro, y tomaremos otro.
También nos brinda una oportunidad única de trabajar con la interfaz SPI conectando dos dispositivos
esclavos al mismo tiempo. E intentaremos conectarlos usando el anillo (o método en cascada).
Aquí está nuestro diagrama en el proteus (haga clic en la imagen para una imagen más grande)
Aquí vemos que un chip es responsable de los cátodos paralelos de cada descarga, y
el segundo es para los ánodos. Solíamos conectar los ánodos, como en los circuitos
paralelos convencionales, los transistores clave en modo inverso, también conectados
desde las patas del puerto a los chips de la base de datos del transistor a través de
resistencias limitadoras de corriente, por lo tanto, para que tengamos un nivel positivo
activo en el ánodo de cada indicador, entonces desde el puerto en el transistor para hacer
el nivel lógico bajo opuesto. Todo, en general, como de costumbre, solo el control de este
esquema se realiza no desde el controlador, sino desde dos registros de desplazamiento.
Ahora el lado izquierdo del diagrama. Las patas de sincronización y las patas de
selección también están conectadas en paralelo, así como el comando de cambio
de SS . Pero desde las patas del controlador MOSI, la señal va a la entrada digital del chip
responsable de los ánodos, y ya desde la salida digital de este chip a la entrada digital del
chip responsable de los cocodes. En consecuencia, aquí nuestro anillo se rompe, ya que
no conectaremos la entrada del controlador MISO desde la salida digital del chip superior
como innecesaria para dicho monitoreo.
Es decir, lo primero que enviaremos bytes para los cátodos, y luego sin demora, bytes
para los ánodos. Por lo tanto, el byte para los cátodos se pone en un círculo en el chip
deseado, y el byte para los cátodos entra en su chip. Luego generaremos un pulso para
alimentar los bytes a los registros del almacenamiento de microcircuitos, y esperaremos
un poco. Y en este momento, nuestros indicadores recibirán las señales necesarias por sí
mismos.
En general, algo como esto.
También veamos todo esto de verdad, con un controlador real, registros e indicadores.
SPI_init ();
timer_ini ();
sei ();
SPDR = 0b00000000;
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
SPDR = 0b00000000;
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
// generar un borde negativo para escribir en el REGISTRO DE
ALMACENAMIENTO
PORTB | = (1 << PORTB2 ); // nivel alto
PORTB & = ~ (1 << PORTB2 ); // nivel bajo
_delay_ms (500);
mientras (1)
Desde un bucle infinito, borra todo por completo. Luego escribiremos en él nuestro
código indicador estándar para el indicador.
mientras (1)
{
para ( i = 0; i <10,000; i ++)
{
ledprint ( i );
_delay_ms (500);
}
}
// ———————————————
void ledprint ( número int sin firma );
Ahora eliminamos todas las macros de led.c, ya que no las necesitamos, y también
eliminamos la variable para el modo
#include "led.h"
// ———————————————
# define MODETIMEVIEW 100
# define MODETEMPERVIEW 101
# define MODEDATEVIEW 102
# define MODEDAYVIEW 103
# define MODEYEARVIEW 104
// ———————————————
#define MODENONEEDIT 0
# define MODEHOUREDIT 1
# define MODEMINEDIT 2
# define MODEDATEEDIT 3
# define MODEMONTHEDIT 4
#define MODEYEAREDIT 5
# define MODEDAYEDIT 6
# define MODEALARMHOUREDIT 7
# define MODEALARMMINEDIT 8
// ———————————————
unsigned char R1 = 0, R2 = 0, R3 = 0, R4 = 0;
un unsigned char CLOCKMODE ;
// ———————————————
extern un unsigned char clockeditmode ;
// ———————————————
// ———————————————
void segchar ( unsigned char seg )
{
interruptor ( seg )
{
caso 1: SPDR = 0b11111001; declaración de la rotura ;
caso 2: SPDR = 0b10100100; declaración de la rotura ;
caso 3: SPDR = 0b10110000; declaración de la rotura ;
caso 4: SPDR = 0b10011001; declaración de la rotura ;
caso 5: SPDR = 0b10010010; declaración de la rotura ;
caso 6: SPDR = 0b10000010; declaración de la rotura ;
caso 7: SPDR = 0b11111000; declaración de la rotura ;
caso 8: SPDR = 0b10000000; declaración de la rotura ;
caso 9: SPDR = 0b10010000; declaración de la rotura ;
caso 0: SPDR = 0b11000000; declaración de la rotura ;
caso 10: SPDR = 0b10111111; declaración de la rotura ; // firmar -
caso 11: SPDR = 0b11111111; declaración de la rotura ; // espacio
vacío
caso 12: SPDR = 0b11000110; declaración de la rotura ; // letra C
para lecturas de temperatura
}
}
// ———————————————
// ———————————————
ISR ( TIMER1_COMPA_vect )
{
si ( n_count == 0)
{
}
si ( n_count == 1)
{
}
si ( n_count == 2)
{
}
si ( n_count == 3)
{
}
n_count ++;
if ( n_count > 3) n_count = 0;
}
// ———————————————
si ( n_count == 0)
{
segchar ( R1 );
segchar ( R1 );
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
Vemos que tendremos el ánodo más bajo activo, que es lo que necesitamos.
Bueno, al final del cuerpo de esta condición, formaremos un pulso para transferir bytes
a registros más bajos.
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
// generar una ventaja negativa para escribir en el REGISTRO DE
ALMACENAMIENTO
PORTB | = (1 << PORTB2 ); // nivel alto
PORTB & = ~ (1 << PORTB2 ); // nivel bajo
}
si ( n_count == 1)
{
segchar ( R2 );
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
SPDR = 0b00001101;
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
// generar una ventaja negativa para escribir en el REGISTRO DE
ALMACENAMIENTO
PORTB | = (1 << PORTB2 ); // nivel alto
PORTB & = ~ (1 << PORTB2 ); // nivel bajo
}
si ( n_count == 2)
{
segchar ( R3 );
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
SPDR = 0b00001011;
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
// generar un borde negativo para escribir en el REGISTRO DE
ALMACENAMIENTO
PORTB | = (1 << PORTB2 ); // nivel alto
PORTB & = ~ (1 << PORTB2 ); // nivel bajo
}
si ( n_count == 3)
{
segchar ( R4 );
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
SPDR = 0b00000111;
while (! ( SPSR & (1 << SPIF ))); // espera hasta que se transmitan los
datos
// generar un borde negativo para escribir en el REGISTRO DE
ALMACENAMIENTO
PORTB | = (1 << PORTB2 ); // nivel alto
PORTB & = ~ (1 << PORTB2 ); // nivel bajo
}
// ———————————————
void ledprint ( unsigned int número , unsigned char cm )
{
modo de reloj = cm ;
R1 = número % 10;
R2 = número % 100/10 ;
R3 = número % 1000/100;
R4 = número / 1000;
}
// ———————————————
_delay_ms ( 10 );
Aquí es donde nuestras clases de SPI no terminan. La próxima vez que intentará
conectarse en este módulo de bus con pantalla, que ya se utiliza un controlador especial
para trabajar con el indicador, así como una pantalla de ocho dígitos. Allí ya puedes
controlar el brillo del indicador y hacer algunas cosas interesantes.
AVR Lección 28. SPI. Driver
led max7219
Publicado en 11 de enero de 2017por Narod Stream Publicado en SPI , Programación AVR - 3 comentarios ↓
Lección 28
Aquí vemos al final del registro de 16 bits, los 8 bits bajos de los cuales son datos, y
los siguientes 4 bits, la dirección de los registros. También vemos varios registros para
diversos propósitos, un controlador de segmentos y un controlador de descargas. También
vemos un modulador de ancho de pulso que controla la intensidad del brillo y está
controlado por un registro especial. También hay un registro interesante, SCAN-LIMIT,
que controla el número de bits involucrados.
Un dato interesante es también un decodificador de segmento, que puede generar el
brillo de ciertos segmentos en una descarga, dependiendo del valor entrante. Antes,
recuerdo, se llamaba decodificador. Este decodificador también se puede apagar, y se
puede encender para algunos dígitos, y se puede apagar para algunos. Surge la pregunta:
¿por qué desactivas la descodificación? La respuesta aquí es multifacética. Primero, para
mostrar algunos caracteres intrincados especiales que no están en la lista de códigos. Y lo
más importante es que cuando usamos un decodificador de caracteres podemos controlar
el indicador solo con un cátodo común, ya no podemos controlar el indicador con un
ánodo común y, si desactivamos la decodificación, podemos pensar en algo para controlar
los ánodos comunes. Bueno, no vamos a hacer esto, vamos a utilizar el decodificador.
Además, en la documentación técnica, todos los registros se consideran en detalle,
ahora no lo consideraremos, pero lo haremos solo cuando sea necesario al escribir el
código.
Bueno, entonces no lo dudaremos, sino que procederemos directamente al proyecto. El
proyecto se creó con el nombre LED7219 , el código es todo del proyecto de la lección
anterior . La única diferencia es que no conectaremos la biblioteca de los archivos led.c
y led.h, ya que tenemos un controlador y lo haremos a nivel de hardware con estas cosas
descritas en estas bibliotecas.
Por lo tanto, eliminaremos la inicialización del temporizador y las interrupciones de la
función main ()
timer_ini ();
sei ();
Luego habrá otra función que escribiremos a continuación. Esta función transferirá los
bytes no solo al bus, sino a un registro específico del chip. A juzgar por la figura con el
esquema estructural y al mirar en el registro de datos, vemos exactamente dónde y qué
colocar allí. Los parámetros de entrada son la dirección del registro y los bytes de datos.
Aquí es una característica tan simple. Primero omitimos el tramo CS para seleccionar
nuestro microcircuito, luego transmitimos un byte con la dirección del registro, y luego
un byte de datos, y al final, elevamos el CS.
Veamos el esquema en el proyecto. El esquema también tomó el esquema del
conocimiento anterior y, en consecuencia, se volvió a trabajar para obtener un nuevo
microchip. El punto es. No tengo un chip separado, pero hay un módulo en el que ya está
instalado un indicador de ocho dígitos, por lo que conectaremos el mismo indicador en el
proteus (haga clic en la imagen para obtener una imagen más grande)
Vemos que la salida del controlador MISO va a la entrada DIN, y también le traemos
sincronización y selección. Bueno, conectamos el indicador con los bits y segmentos
correspondientes a las salidas paralelas correspondientes del controlador. En general, el
esquema resultó ser más fácil que el nabo.
Y aquí tenemos todo en el módulo.
También aquí vemos que en lugar de un indicador de ocho dígitos, se instalan dos
indicadores de cuatro dígitos en el módulo, lo que, de hecho, no es muy difícil, ya que los
escuadrones están todos a la misma distancia entre sí, por así decirlo, sin espacios.
Volvamos a nuestro proyecto.
Como no tenemos prisa, activemos el prescaler para sincronizar el bus SPI en la
función SPI_init ()
Retraso de licencia.
Veamos primero la tabla de direcciones de registro en la hoja de datos.
SPI_init ();
Send_7219 (0x09, 0xFF); // habilitar el modo de decodificación
Aquí el esquema es simple. El valor de este registro, que pasamos, es igual al número
de bits acumulados, reducido en 1.
#include "main.h"
char dg = 8;
Ahora hagamos el brillo del resplandor. Para ello disponemos de un registro separado
con la dirección 0x0A.
Ya que tenemos el MAX7219, entonces para nosotros la primera columna. Aquí creo
que todo es simple. Para empezar, vamos a configurar la intensidad media del indicador.
Después de todos estos ajustes, es conveniente eliminar toda la basura que se recopila
en el búfer de datos. Para hacer esto, escribimos la función de limpieza de la pantalla,
nuevamente sobre la función main ()
Bueno, finalmente, ahora intentemos mostrar algo en la pantalla, por ejemplo, algún
carácter, y lo mejor de todo, en todos los ocho dígitos, los caracteres de los dígitos
Clear_7219 ();
Send_7219 (0x01, 1);
Send_7219 (0x02, 2);
Send_7219 (0x03, 3);
Send_7219 (0x04, 4);
Send_7219 ( 0x05,5 );
Send_7219 (0x06, 6);
Send_7219 (0x07, 7);
Send_7219 (0x08, 8);
Veamos el resultado
Sí, es diferente, se volvió más oscuro.
Ahora escribamos una función para generar algún valor numérico, para enviar
números, no en bits, sino en números enteros, como en proyectos anteriores.
Vuelva a crear dicha función por encima de la función main ().
Aquí hay una función, aparentemente sin pretensiones, que no se puede decir sobre su
cuerpo, que le escribiremos a continuación. En la entrada habrá una cantidad no
optimizable, y luego no es suficiente, se perderá.
Comencemos con un signo variable, de repente, queremos generar un valor negativo
Pantalla clara
n * = -1;
}
Clear_7219 ();
Luego está la condición de igualdad a cero, entonces solo enviaremos el cero al orden
inferior y saldremos de la función.
Clear_7219 ();
si ( n == 0) {
Send_7219 (0x01, 0); // escribe 0 al primer dígito
instrucción de retorno ;
}
Luego agrega otra variable al contador.
instrucción de retorno ;
}
char i = 0;
El siguiente es el ciclo en el que llenamos los dígitos con números de nuestro valor.
char i = 0;
hacer {
Send_7219 (++ i , n % 10);
n / = 10;
} tiempo ( n );
Aquí, también, todo es simple con nosotros, reducimos nuestro valor 10 veces con
cada dígito y extraemos el último dígito mediante el módulo 10, y lo enviamos al dígito
actual.
Bueno, al final del cuerpo de la función, muestre el símbolo menos en el siguiente
dígito.
} tiempo ( n );
si ( ng ) {
Send_7219 ( i +1, 0xA); // carácter -
}
}
Bueno, vamos a comprobar esta función. Después de mostrar nuestros caracteres del
1 al 8 en la función principal (), agregue un pequeño retraso y luego muestre algún valor
Genial
Bueno, ahora, para que se vea cada vez más animado, escribamos un contador,
especialmente porque ya tenemos una variable. Agregue el código al bucle sin fin, antes
de que también insertemos el retraso
Número_7219 (-2016);
_delay_ms (1000);
mientras (1)
{
NumberFull_7219 ( i );
i ++;
_delay_ms (200);
}
Bueno, estamos con usted y nos familiarizamos con el nuevo dispositivo, por lo que
una vez más practicamos con el bus SPI .
Solo que de nuevo no terminamos con el bus SPI . En la siguiente
lección,intentaremos conectar un ADC externo a través de este bus .
Lección 29
Aquí vemos que este chip ADC es de 8 pines, existe en el paquete DIP, así como en
otros paquetes diversos. Por ejemplo, tuve este microcircuito en mis manos en el estuche
SOIC, por lo que tuve que usar un adaptador económico y sin pretensiones, que veremos
un poco más tarde, y hacer algo como un DIP para enchufarlo a la placa de pruebas, es
decir, resultó algo así como una pequeña heces
Ahora las piernas
Vref es un contacto para referencia de voltaje. Es decir, daremos, por ejemplo, cinco
voltios aquí, y este será nuestro voltaje máximo.
En + es nuestra entrada analógica. Sobre ella medimos nuestra tensión.
En- es la entrada para ajustar el ADC. Es decir, si hay algún error, entonces estamos
enviando un voltaje de corrección de -100 milivoltios a +100 milivoltios.
Vss - cable común.
CS / SHDN - pie para seleccionar y desactivar el chip.
Dout - datos digitales de la pierna medido voltaje.
CLK - sincronización o pie de reloj.
Vdd - potencia de la pierna de 2,7 voltios a 5,5 voltios.
Y así es como la tensión en sí, o más bien, por el contrario, se calcula a partir del valor
de información medido y de voltaje de referencia, que obtenemos del bus.
El primer modo (haga clic en la imagen para una imagen más grande)
El segundo modo (haga clic en la imagen para una imagen más grande)
Aquí también vemos exactamente cómo se transmiten los bits útiles de información.
Bueno, podemos decir, nos reunimos un poco con el microcircuito.
Ahora el proyecto.
Tomé el proyecto según una gloriosa tradición de la ocupación anterior, y lo nombré
por nuestro microcircuito ADC3201 .
Eliminé todo lo innecesario del archivo principal, dejando solo las
funciones SPI_init , SPI_SendByte y main .
Además, se eliminó la biblioteca led y se conectó la biblioteca para la pantalla de
caracteres lcd.
Por lo tanto, el archivo main.h ahora adquirió este formulario.
#ifndef MAIN_H_
# define MAIN_H_
#define F_CPU 8000000UL
#include <avr / io.h>
#include <avr / interrupt.h>
#include <util / delay.h>
#include <stdio.h>
#include <stdlib.h>
// —————————————
#include " lcd.h "
#endif / * MAIN_H_ * /
La biblioteca LCD, que consta de archivos lcd.h y lcd.c, se tomó de un borrador de una
de las lecciones anteriores .
La función principal () después de la limpieza tomó la siguiente forma
#include "main.h"
void port_ini ( void )
{
PORTD = 0x00;
DDRD = 0xFF;
}
mientras (1)
{
setpos (0,0);
_delay_ms (500);
}
Bueno, ahora, antes de escribir otro código, necesitamos familiarizarnos con el circuito
para conectar un ADC externo al controlador. Para ello, vamos a verlo en el proteus (haz
click en la imagen para ampliar)
Como podemos ver, la función no ha cambiado mucho. Justo después del final de la
recepción y transmisión, leemos el registro de datos y lo devolvemos. Pero como no
transferimos nada de acuerdo con el esquema del controlador, pero debido a la tecnología
del dispositivo SPI, el dispositivo esclavo todavía nos dará un byte, no va a ninguna parte.
Ahora necesitamos usar de alguna manera la función anterior y aún solicitar algo. Para
ello, escribimos a continuación otra función. Esta función recibirá bytes, los procesará y
nos devolverá el valor borrado de los bits innecesarios.
En esta función, declararemos dos variables para dos bytes, luego bajaremos el bus de
selección de chip, ya que el nivel activo es bajo, por lo que obligaremos al chip a
comenzar a enviar bytes
unsigned int Read_3201 ( void )
{
sin firma int b1 , b2 ;
PORTB & = ~ (1 << PORTB2 ); // nivel bajo
Bueno, ahora agregaremos otra función a continuación, que convertirá nuestro valor
bruto de dos bytes en un resultado de punto flotante, que ya llevará el voltaje medido
Primero agregamos una variable local para almacenar temporalmente nuestro valor de
punto flotante.
setpos (0,0);
dt = Convert_3201 ( Read_3201 ());
float dt = 0;
char str [10];
Bueno, ahora llamaremos la función sprinf en un bucle infinito, que convertirá nuestro
valor de punto flotante en una cadena
Los paréntesis no se requieren aquí, pero con ellos de alguna manera más silenciosos.
Compruebe el resultado mediante la recopilación del código y la actualización del
controlador. Todavía no tenemos la misma lectura, por lo tanto. Habiendo jugado con el
valor multiplicado, aún puede lograr un resultado preciso. Quizás el hecho es que el
voltaje es inestable en todas las patas debido a la resistencia de los cables.
En general, si aplica una tensión de referencia precisa y estable, puede lograr
resultados muy precisos con esta resolución.
Pero ese no es el punto. El hecho es que hoy, una vez más, jugamos con el bus SPI y
pudimos lograr resultados al usarlo para recibir datos.
Y en la siguiente lección , conectaremos la pantalla a otro controlador para luego
conectarlo en el bus SPI a nuestra tarjeta de depuración con el controlador ATmega8