Programación de microcontroladores avr en C. Programación de microcontroladores AVR en C. Entonces, ¿qué es un microcontrolador?

Decidí escribir un breve artículo introductorio para aquellos que comenzaron a programar microcontroladores por primera vez y nunca antes estaban familiarizados con el lenguaje C. No entraremos en detalles, hablaremos un poco de todo para tener una idea general de cómo trabajar con CodeVisionAVR.

Más información detallada se puede ver en inglés en el Manual de usuario de CodeVision, y también recomiendo el sitio http://somecode.ru con lecciones en video sobre C para microcontroladores y el libro “Cómo programar en C” de Deitel, este es el único buen libro. con el que yo mismo comencé.

Para empezar, no importa qué acciones hagamos, en última instancia, todo se reduce al firmware del microcontrolador. El proceso de firmware en sí ocurre de la siguiente manera: usando un determinado programa, se selecciona un archivo de firmware, se seleccionan los parámetros, se presiona un botón y se actualiza directamente el firmware, que, en esencia, es una copia. Al igual que copias música o documentos desde una computadora a una unidad flash, la física del proceso es la misma.

El firmware en sí tiene una extensión .hex y es un conjunto de instrucciones, en forma de unos y ceros, comprensibles para el microcontrolador. ¿De dónde puedo obtener el firmware? Puede descargarlo de sitios web de electrónica o escribirlo usted mismo. Puede escribirlo en programas especiales llamados entorno de desarrollo. Los más conocidos para mí son AVR Studio, IAR, CodeVision, WinAVR... Es imposible decir cuál de estos entornos es mejor o peor, para cada uno lo suyo. Podemos decir que estos programas se diferencian principalmente en comodidad, lenguaje de programación y precio. Dentro de este sitio, sólo se considera CodeVision.

Hemos resuelto el entorno, ahora veamos el proceso de escritura del firmware. En CodeVision, primero necesitas crear un proyecto. Se puede crear usando el asistente de código o vacío. En cualquier caso, es necesario seleccionar el tipo de microcontrolador utilizado e indicar su frecuencia. Al utilizar el asistente, se le pedirá que seleccione la configuración inicial y genere el código fuente con la configuración. A continuación, aparecerá una ventana en la que podrás editar este código. Aunque puedes escribir tu código fuente en el Bloc de notas y luego adjuntarlo al proyecto en la configuración.

Un archivo de código fuente es un conjunto de comandos en un lenguaje de programación, la tarea de CodeVision es traducir estos comandos a código binario, su tarea es escribir este código fuente. CodeVision entiende el lenguaje C, los archivos de código fuente tienen la extensión “.c”. Pero CodeVision tiene algunas construcciones que no se usan en C, razón por la cual a muchos programadores no les gusta, y el lenguaje usado se llama C-like. Sin embargo, esto no le impide escribir proyectos serios. Muchos ejemplos, un generador de código y un gran conjunto de bibliotecas le dan a CodeVision una gran ventaja. Lo único negativo es que es de pago, aunque hay versiones gratuitas con restricción de código.

El código fuente debe contener un encabezado con el tipo de microcontrolador utilizado y la función principal. Por ejemplo, se utiliza ATtiny13

#incluir vacío principal(vacío) ( );

#incluir vacío principal(vacío) ( );

Antes de la función principal, puede conectar las bibliotecas necesarias, declarar variables, constantes y configuraciones globales. Una biblioteca es un archivo independiente, normalmente con una extensión “.h”, que ya contiene código preescrito. En algunos proyectos podemos necesitar este código, pero en otros no lo necesitamos. Por ejemplo, en un proyecto utilizamos pantallas LCD, pero en otro no. Puede conectar la biblioteca para trabajar con la pantalla LCD “alcd.h” de esta manera:

#incluir #incluir vacío principal(vacío) ( );

#incluir #incluir vacío principal(vacío) ( );

Las variables son áreas de la memoria en las que se pueden colocar ciertos valores. Por ejemplo, si suma dos números, deberá guardar el resultado en algún lugar para usarlo en el futuro. Primero necesitas declarar la variable, es decir asigne memoria para ello, por ejemplo:
int i=0;
aquellos. declaramos la variable i y colocamos el valor 0 en ella, int es el tipo de variable, o más simplemente, significa el tamaño de la memoria asignada. Cada tipo de variable solo puede almacenar un cierto rango de valores. Por ejemplo, int se puede escribir como números desde -32768 hasta 32767. Si necesita usar números con una parte fraccionaria, entonces la variable debe declararse como flotante, para caracteres, use el tipo char.

bit, _Bit 0 o 1 carácter de -128 a 127 carácter sin signo de 0 a 255 int de -32768 a 32767 int sin signo de 0 a 65535 int largo de -2147483648 a 2147483647 int largo sin signo de 0 a 4294967295 flotante de ±1,17 5e- 38 a ±3.402e38

Dentro de la función principal, el programa principal ya se está ejecutando. Después de ejecutar la función, el programa se detendrá, por lo que hacen un bucle while infinito, que repite el mismo programa constantemente.

void main(void) (mientras (1) ( ); );

void main(void) (mientras (1) ( ); );

Puede escribir un comentario en cualquier parte del código fuente; no afectará de ninguna manera el funcionamiento del programa, pero ayudará a tomar notas sobre el código escrito. Puede comentar una línea con dos barras //después de lo cual el compilador ignorará toda la línea o varias líneas /**/, por ejemplo:

/*Operaciones matemáticas básicas:*/ intyo= 0 ; //declaramos la variable i y le asignamos el valor 0//Suma: i = 2 + 2 ; //Resta: i = 2 - 2 ; //después de ejecutar esta expresión, la variable i será igual a 0//Multiplicación: i = 2 * 2 ; //después de ejecutar esta expresión, la variable i será igual a 4//División: i = 2 / 2 ; //después de ejecutar esta expresión, la variable i será igual a 1

/*Operaciones matemáticas básicas:*/ int i=0; //declaramos la variable i y le asignamos el valor 0 //Suma: i = 2+2; //después de ejecutar esta expresión, la variable i será igual a 4 //Resta: i = 2-2; //después de ejecutar esta expresión, la variable i será igual a 0 //Multiplicación: i = 2*2; //después de ejecutar esta expresión, la variable i será igual a 4 //División: i = 2/2; //después de ejecutar esta expresión, la variable i será igual a 1

A menudo, un programa necesita pasar de un fragmento de código a otro, dependiendo de las condiciones; para ello, existen operaciones condicionales if(), por ejemplo:

if(i>3) //si i es mayor que 3, entonces asígnale el valor 0 ( i=0; ) /*si i es menor que 3, entonces ve al código que sigue al cuerpo de la condición, es decir después de corchetes ()*/

Además, si se puede usar junto con else; de ​​lo contrario

si yo<3) //если i меньше 3, то присвоить i значение 0 { i=0; } else { i=5; //иначе, т.е. если i больше 3, присвоить значение 5 }

También hay un operador de comparación “==”, que no debe confundirse con la asignación “=". La operación inversa no es igual a "!=", digamos

if(i==3)//si i es 3, asigna a i el valor 0 (i=0; ) if(i!=5) //si i no es 5, asigna a i el valor 0 (i=0; )

Pasemos a cosas más complejas: las funciones. Supongamos que tiene un determinado fragmento de código que se repite varias veces. Además, este código es bastante grande. Es inconveniente escribirlo cada vez. Por ejemplo, en un programa que de alguna manera cambia la variable i, al presionar los botones 0 y 3 del puerto D, se ejecuta el mismo código que, dependiendo del valor de la variable i, enciende las patas del puerto B.

vacío principal (vacío) (si (PIND.0== 0) //comprueba si el botón en PD0 está presionado(si (i== 0) //si i==0 habilita PB0( PORTB.0= 1 ; ) si (i== 5 ) // si i==5 habilita PB1(PORTB.1= 1; ) ) … si (PIND.3== 0 ) // haz lo mismo al marcar el botón PD3( si (i== 0 ) ( PORTB.0= 1 ; ) si (i== 5 ) ( PORTB.1= 1 ; ) ) )

void main(void) ( if(PIND.0==0) //comprobar si el botón en PD0 está presionado ( if(i==0) //si i==0 enciende PB0 ( PORTB.0=1; ) if( i==5) // si i==5 enciende PB1 ( PORTB.1=1; ) ) ... if(PIND.3==0) // haz lo mismo al verificar el botón PD3 ( si(i==0 ) ( PORTB.0=1; ) si(i==5) ( PORTB.1=1; ) ) )

En general, el código no es muy grande, pero podría ser muchas veces más grande, por lo que sería mucho más conveniente crear tu propia función.
Por ejemplo:

void i_check() ( si (i== 0 ) ( PORTB.0= 1 ; ) si (i== 5 ) ( PORTB.1= 1 ; ) )

void i_check() ( si(i==0) ( PORTB.0=1; ) si(i==5) ( PORTB.1=1; ) )

void significa que la función no devuelve nada, más sobre esto a continuación i_check() - este es el nombre de nuestra función, puedes llamarla como quieras, yo la llamé exactamente así - marca i. Ahora podemos reescribir nuestro código:

void i_check() ( if(i==0) ( PORTB.0=1; ) if(i==5) ( PORTB.1=1; ) ) void main(void) ( if(PIND.0==0 ) //comprobar si el botón en PD0 está presionado ( i_check(); ) ... if(PIND.3==0) ( i_check(); ) )

Cuando el código llega a la línea i_check(); luego saltará dentro de la función y ejecutará el código dentro. De acuerdo, el código es más compacto y claro, es decir. Las funciones ayudan a reemplazar el mismo código, solo una línea. Tenga en cuenta que la función se declara fuera del código principal, es decir. antes de la función principal. Puedes decir por qué necesito esto, pero mientras estudias las lecciones a menudo encontrarás funciones, por ejemplo, borrar la pantalla LCD lcd_clear() - la función no acepta ningún parámetro y no devuelve nada, pero borra el pantalla. A veces, esta función se utiliza casi cada dos líneas, por lo que el ahorro de código es obvio.

Parece mucho más interesante usar una función cuando toma valores, por ejemplo, hay una variable c y hay una función suma que toma dos valores de tipo int. Cuando el programa principal ejecute esta función, los argumentos ya estarán entre paréntesis, por lo que "a" será igual a dos y "b" será igual a 1. La función se ejecutará y "c" será igual a 3 .

intc= 0 ; suma vacía(int a, int b) ( c= a+ b; ) principal vacía(void ) ( suma(2, 1 ); )

intc=0; suma vacía(int a, int b) ( c=a+b; ) principal vacía(void) ( suma(2,1); )

Una de las funciones similares más comunes es mover el cursor en la pantalla LCD lcd_gotoxy(0,0); que, por cierto, también toma argumentos: coordenadas xey.

Otra opción para usar una función, cuando devuelva un valor ahora ya no será nulo, mejoremos el ejemplo anterior de una función para sumar dos números:

intc= 0 ; int suma(int a, int b) ( return a+ b; ) void main(void) ( с= suma(2, 1) ; )

intc=0; int suma(int a, int b) ( return a+b; ) void main(void) ( с=sum(2,1); )

El resultado será el mismo que la última vez c=3, pero fíjate que asignamos a la variable “c” el valor de una función que ya no es nula, sino que devuelve la suma de dos números de tipo int. De esta manera no estamos atados a una variable “c” específica, lo que agrega flexibilidad en el uso de funciones. Un ejemplo simple de tal función es leer datos ADC, la función devuelve el valor medido result=read_adc();. Terminemos con las funciones.

Ahora pasemos a las matrices. Una matriz son variables relacionadas. Por ejemplo, tienes una tabla de senos con varios puntos, no crearás variables int sinus1=0; int sinus2=1; etc. Para esto se utiliza una matriz. Por ejemplo, puedes crear una matriz de tres elementos como este:
int sinus=(0,1,5);
El número total de elementos de la matriz se indica entre corchetes. Puedes asignar el valor del tercer elemento a la variable “c” así:
с=seno;
Tenga en cuenta que la numeración de los elementos de la matriz comienza desde cero, es decir "c" será igual a cinco. ¡¡¡Esta matriz no tiene un elemento sinusal !!!
Puede asignar un valor a un elemento individual como este:
seno=10;

Quizás ya hayas notado que CodeVision no tiene variables de cadena. Aquellos. no puedes crear una cadena variable hola=”hola”; Para hacer esto, tendrás que crear una serie de personajes individuales.

lcd_putchar(hola); lcd_putchar(hola); lcd_putchar(hola);

etc.
Resulta bastante engorroso, aquí las bicicletas vienen al rescate.
Por ejemplo, bucle while

mientras(PINB.0!=0) ( )

Hasta que presione el botón, no haga nada: ejecute un bucle vacío.

Otra opción es el bucle for.

ent yo; para (yo= 0 ; yo< 6 ; i++ ) { lcd_putchar(hello[ i] ) ; }

ent yo; para(i=0;yo<6;i++) { lcd_putchar(hello[i]); }

El significado es exactamente el mismo que el de while, solo se agregan la condición inicial i=0 y la condición que se ejecuta en cada ciclo i++. El código dentro del bucle está lo más simplificado posible.

Una vez que haya escrito su programa, se compila el código fuente y, si no hay errores, recibirá el codiciado firmware en la carpeta del proyecto. Ahora puedes flashear el microcontrolador y disfrutar del funcionamiento del dispositivo.

No debería intentar utilizar inmediatamente bucles, matrices y funciones en su firmware. Tu tarea principal es hacer que el firmware funcione, así que hazlo como te resulte más fácil y no prestes atención al tamaño del código. Llegará el momento en el que no sólo querrás escribir código que funcione, sino también escribirlo de forma hermosa y compacta. Entonces será posible adentrarse en las selvas del lenguaje C. Para aquellos que quieran dominarlo todo, les recomiendo una vez más el libro “Cómo programar en C”, hay muchos ejemplos y tareas. Instale Visual Studio, cree una aplicación de consola win32 y practique allí a su gusto.

Lección 0.

Entonces, hoy abrimos una serie de lecciones sobre programación de microcontroladores de la familia AVR.

Hoy se discutirán las siguientes preguntas:

  1. ¿Qué es un microcontrolador?
  2. ¿Dónde se utilizan los microcontroladores?

Introducción.

Los microcontroladores están en todas partes. En teléfonos, lavadoras, “hogares inteligentes”, máquinas herramienta en fábricas y también en muchos otros dispositivos técnicos. Su uso generalizado permite sustituir circuitos analógicos complejos por circuitos digitales más comprimidos.

Entonces, ¿qué es un microcontrolador?

Microcontrolador (Unidad de microcontrolador, MCU) - un microcircuito diseñado para controlar dispositivos electrónicos. Se puede imaginar como una simple computadora capaz de interactuar con dispositivos externos, por ejemplo, abrir y cerrar transistores, recibir datos de sensores de temperatura, mostrar datos en pantallas LCD, etc. Además, el microcontrolador puede realizar diversos procesamientos de datos de entrada, al igual que su computadora personal.

Es decir, los microcontroladores nos ofrecen posibilidades casi ilimitadas para controlar cualquier dispositivo, gracias a la presencia de puertos I/0 (puertos de entrada/salida), así como la posibilidad de programarlos.

¿Dónde se utilizan los microcontroladores?

  1. Electrodomésticos (Lavadoras, hornos microondas, etc.).
  2. Tecnología móvil (Robots, sistemas robóticos, equipos de comunicaciones, etc.).
  3. Equipos industriales (sistemas de control de máquinas).
  4. Tecnología informática (Placas base, sistemas de control de dispositivos periféricos).
  5. Equipos de entretenimiento (Juguetes infantiles, adornos).
  6. Transporte (Sistemas de control de motores de automóviles, sistemas de seguridad)

Esta no es una lista completa de aplicaciones para microcontroladores. A menudo, resulta muy rentable sustituir un conjunto de chips de control por un microcontrolador, debido a la simplificación de la producción y al reducido consumo de energía.

Empezando con AVR

AVR- una familia de microcontroladores de Atmel que tienen un rendimiento suficiente para la mayoría de los dispositivos de aficionados. También son muy utilizados en la industria.

El diagrama esquemático del programador de puerto LPT se muestra en la figura. Como conductor de autobús, utilice el microcircuito 74AC 244 o 74HC244 (K1564AP5), 74LS244 (K555AP5) o 74ALS244 (K1533AP5).

El LED VD1 indica el modo de grabación del microcontrolador,

LED VD2 - lectura,

LED VD3 - presencia de alimentación al circuito.

El circuito toma el voltaje requerido para el suministro de energía del conector ISP, es decir desde el dispositivo programable. Este circuito es un circuito programador STK200/300 rediseñado (se agregaron LED para facilitar la operación), por lo que es compatible con todos los programas de programación de PC que funcionan con el circuito STK200/300. Para trabajar con este programador, utilice el programa. CVAVR

El programador se puede fabricar sobre una placa de circuito impreso y colocarlo en la carcasa del conector LPT, como se muestra en las figuras:




Para trabajar con el programador es conveniente utilizar una extensión del puerto LPT, que es fácil de hacer usted mismo (por ejemplo, a partir de un cable Centronix para impresora), lo principal es no ahorrar conductores de tierra (18- 25 patas conectoras) o comprar. El cable entre el programador y el chip programable no debe exceder los 20-30 cm.

Las operaciones bit a bit se basan en las operaciones lógicas que cubrimos anteriormente. Desempeñan un papel clave en la programación de AVR y otros tipos de microcontroladores. Casi ningún programa puede prescindir del uso de operaciones bit a bit. Antes de esto, los evitamos deliberadamente para facilitar el proceso de aprendizaje de la programación MK.

En todos los artículos anteriores, programamos solo puertos de E/S y no utilizamos componentes integrados adicionales, por ejemplo, temporizadores, convertidores analógico-digital, interrupciones y otros dispositivos internos sin los cuales el MK pierde toda su potencia.

Antes de pasar a dominar los dispositivos integrados del MK, debe aprender a controlar o verificar bits individuales de los registros del AVR MK. Anteriormente, realizamos una verificación o configuramos los dígitos de todo el registro a la vez. Averigüemos cuál es la diferencia y luego sigamos adelante.

Operaciones bit a bit

La mayoría de las veces, al programar microcontroladores AVR, lo usamos, ya que es más visual en comparación y es más comprensible para los programadores MK novatos. Por ejemplo, necesitamos configurar solo el tercer bit del puerto D. Para hacer esto, como ya sabemos, podemos usar el siguiente código binario:

PORTD = 0b00001000;

Sin embargo, con este comando ponemos el tercer dígito a uno y ponemos a cero todos los demás (0, 1, 2, 4, 5, 6 y 7). Ahora imaginemos una situación en la que los bits 6 y 7 se usan como entradas ADC y en este momento se recibe una señal de algún dispositivo en los pines MK correspondientes, y usamos el comando anterior para restablecer estas señales. Como resultado, el microcontrolador no los ve y cree que las señales no llegaron. Por lo tanto, en lugar de dicho comando, deberíamos usar otro que establezca solo el tercer bit en uno, sin afectar los bits restantes. Para ello se suele utilizar la siguiente operación bit a bit:

PUERTO |= (1<<3);

Discutiremos su sintaxis en detalle a continuación. Y ahora otro ejemplo. Digamos que necesitamos verificar el estado del tercer dígito del registro PIND, verificando así el estado del botón. Si este bit se pone a cero, entonces sabemos que se presiona el botón y luego se ejecuta el código de comando, que corresponde al estado del botón presionado. Anteriormente habríamos utilizado la siguiente notación:

si (PIND == 0b00000000)

(cualquier código)

Sin embargo, con su ayuda comprobamos no sólo el tercer bit, sino todos los bits del registro PIND a la vez. Por lo tanto, incluso si se presiona el botón y se restablece el bit deseado, pero en este momento se recibe una señal en algún otro pin del puerto D, el valor correspondiente se establecerá en uno y la condición entre paréntesis será falsa. Como resultado, el código dentro de las llaves no se ejecutará incluso cuando se presione el botón. Por lo tanto, para comprobar el estado de un tercer bit individual del registro PIND, se debe utilizar una operación bit a bit:

si (~PIND & (1<<3))

(cualquier código)

Para trabajar con bits individuales del microcontrolador, el lenguaje de programación C tiene herramientas que se pueden utilizar para cambiar o verificar el estado de uno o más bits individuales a la vez.

Configurar un solo bit

Para configurar un solo bit, como el puerto D, se utiliza una operación OR bit a bit. Esto es lo que usamos al principio del artículo.

PORTD = 0b00011100; // valor inicial

PUERTO = PUERTO | (1<<0); применяем побитовую ИЛИ

PUERTO |= (1<<0); // сокращенная форма записи

PORTD == 0b00011101; // resultado

Este comando establece el bit cero y deja el resto sin cambios.

Por ejemplo, instalemos otro sexto bit del puerto D.

PORTD = 0b00011100; // estado inicial del puerto

PUERTO |= (1<<6); //

PORTD == 0b01011100; // resultado

Para escribir de uno a varios bits separados a la vez, por ejemplo, los puertos cero, sexto y séptimo B Se aplica la siguiente notación.

PUERTOB = 0b00011100; // valor inicial

PUERTO |= (1<<0) | (1<<6) | (1<<7); //

PUERTOB == 0b1011101; // resultado

Restablecer (poner a cero) bits individuales

Para restablecer un solo bit, se utilizan a la vez tres comandos discutidos anteriormente: .

Restablezcamos el tercer bit del registro PORTC y dejemos el resto sin cambios.

PORTC = 0b00011100;

PUERTO &= ~(1<<3);

PORTC == 0b00010100;

Realicemos acciones similares para el segundo y cuarto dígito:

PORTC = 0b00111110;

PUERTO &= ~((1<<2) | (1<<4));

PORTC == 0b00101010;

conmutación de bits

Además de configurar y restablecer, también se utiliza un comando útil que cambia un solo bit al estado opuesto: uno a cero y viceversa. Esta operación lógica se utiliza ampliamente para crear diversos efectos de iluminación, por ejemplo, una guirnalda de Año Nuevo. Veamos el ejemplo de PORTA.

PORTA = 0b00011111;

PORTA ^= (1<<2);

PORTA == 0b00011011;

Cambiemos el estado de los bits cero, segundo y sexto:

PORTA = 0b00011111;

PORTA ^= (1<<0) | (1<<2) | (1<<6);

PORTA == 0b01011010;

Comprobación del estado de un bit individual. Permítame recordarle que la verificación (en lugar de escribir) un puerto de E/S se realiza leyendo los datos del registro PIN.

La mayoría de las veces, las pruebas se realizan mediante una de dos declaraciones de bucle: if y while. Ya conocemos estos operadores anteriormente.

Comprobación del bit para detectar la presencia de un cero lógico (reinicio) con si

si (0==(PIND & (1<<3)))

Si se borra el tercer bit del puerto D, se ejecuta Code1. De lo contrario, se ejecuta Code2.

Se realizan acciones similares con esta forma de grabación:

si (~PIND & (1<<3))

Comprobación del bit para detectar la presencia de una unidad lógica (configuración) con si

si (0 != (PIND & (1<<3)))

si (PIND & (1<<3))

Los dos bucles anteriores funcionan de manera similar, pero, debido a la flexibilidad del lenguaje de programación C, pueden tener una forma diferente de notación. El operador != significa no igual. Si el tercer bit del puerto PD I/O está establecido (uno), entonces se ejecuta Code1; si no, se ejecuta Code2.

Esperando que se reinicie el bit mientras

mientras (PIND & (1<<5))

Code1 se ejecutará siempre que esté establecido el quinto bit del registro PIND. Cuando lo reinicie, Code2 comenzará a ejecutarse.

Esperando que se establezca el bit mientras

Aquí, la sintaxis de C le permite escribir código de dos de las formas más comunes. En la práctica se utilizan ambos tipos de grabación.

Los microcontroladores (en adelante MK) han entrado firmemente en nuestras vidas, en Internet se pueden encontrar muchos circuitos interesantes que se ejecutan en MK. Lo que no se puede montar en un MK: indicadores varios, voltímetros, electrodomésticos (dispositivos de protección, dispositivos de conmutación, termómetros...), detectores de metales, juguetes varios, robots, etc. La lista podría llevar mucho tiempo. Vi el primer circuito de un microcontrolador hace 5 o 6 años en una revista de radio y casi de inmediato pasé la página, pensando: "Todavía no podré ensamblarlo". De hecho, en ese momento los MK eran un dispositivo muy complejo e incomprendido para mí; no tenía idea de cómo funcionaban, cómo flashearlos y qué hacer con ellos en caso de firmware incorrecto. Pero hace aproximadamente un año, monté mi primer circuito en un MK; era un circuito de voltímetro digital basado en indicadores de 7 segmentos y un microcontrolador ATmega8. Dio la casualidad de que compré un microcontrolador por accidente, cuando estaba parado en el departamento de componentes de radio, el tipo frente a mí estaba comprando un MK, y yo también decidí comprarlo e intentar ensamblar algo. En mis artículos te hablaré de microcontroladores AVR, te enseñaré cómo trabajar con ellos, veremos programas para firmware, haremos un programador simple y confiable, veremos el proceso de firmware y, lo más importante, los problemas que pueden surgir no sólo para principiantes.

Parámetros básicos de algunos microcontroladores de la familia AVR:

Microcontrolador

Memoria flash

memoria RAM

memoria EEPROM

Puertos de E/S

poder U

Parámetros adicionales del AVR mega MK:

Temperatura de funcionamiento: -55…+125*С
Temperatura de almacenamiento: -65…+150*С
Voltaje en el pin RESET relativo a GND: máx. 13 V
Tensión de alimentación máxima: 6,0 V
Corriente máxima de línea de E/S: 40 mA
Corriente máxima de alimentación VCC y GND: 200 mA

Distribución de pines del modelo ATmega 8X

Distribución de pines para los modelos ATmega48x, 88x, 168x

Disposición de pines para modelos ATmega8515x

Disposición de pines para modelos ATmega8535x

Disposición de pines para modelos ATmega16, 32x

Disposición de pines para modelos ATtiny2313

Al final del artículo se adjunta un archivo con hojas de datos para algunos microcontroladores.

Puntas de FUSIBLE de instalación MK AVR

Recuerde, un fusible programado es 0, uno no programado es 1. Debe tener cuidado al configurar los fusibles, un fusible mal programado puede bloquear el microcontrolador. Si no está seguro de qué fusible necesita programar, es mejor flashear el MK sin fusibles por primera vez.

Los microcontroladores más populares entre los radioaficionados son ATmega8, seguido de ATmega48, 16, 32, ATtiny2313 y otros. Los microcontroladores se venden en paquetes TQFP y DIP; para principiantes, recomiendo comprar en DIP. Si compras TQFP, será más problemático flashearlos; tendrás que comprar o soldar la placa porque sus piernas están ubicadas muy cerca una de la otra. Le aconsejo que instale microcontroladores en paquetes DIP en enchufes especiales, es conveniente y práctico, no es necesario desoldar el MK si desea actualizarlo o usarlo para otro diseño.

Casi todos los MK modernos tienen la capacidad de programar un ISP en circuito, es decir. Si su microcontrolador está soldado a la placa, entonces para cambiar el firmware no tendremos que desoldarlo de la placa.

Se utilizan 6 pines para la programación:
REINICIAR- Iniciar sesión MK
VCC- Fuente de alimentación Plus, 3-5V, depende de MK
Tierra- Cable común, menos potencia.
MOSI- Entrada MK (señal de información en MK)
MISO- Salida MK (señal de información de MK)
SCK- Entrada MK (señal de reloj en MK)

A veces también usan los pines XTAL 1 y XTAL2; se adjunta cuarzo a estos pines si el MK está alimentado por un oscilador externo; en ATmega 64 y 128, los pines MOSI y MISO no se usan para la programación ISP; en cambio, los pines MOSI son conectado al pin PE0 y MISO al pin PE1. Al conectar el microcontrolador al programador, los cables de conexión deben ser lo más cortos posible y el cable que va desde el programador al puerto LPT tampoco debe ser demasiado largo.

El marcado del microcontrolador puede contener letras extrañas con números, por ejemplo Atmega 8L 16PU, 8 16AU, 8A PU, etc. La letra L significa que el MK funciona a un voltaje más bajo que el MK sin la letra L, generalmente 2,7V. Los números después del guión o espacio 16PU u 8AU indican la frecuencia interna del generador que se encuentra en el MK. Si los fusibles están configurados para funcionar con un cuarzo externo, el cuarzo debe configurarse a una frecuencia que no exceda el máximo según la hoja de datos, esto es 20 MHz para ATmega48/88/168 y 16 MHz para otros atmegas.


Arriba