domingo, 18 de noviembre de 2018

Uso de "SBI" y "CBI"

SBI(Set Bit in I/O Register)
Coloca el nivel alto(setea) a un bit de un registro de entrada/salida.

CBI(Clear Bit in I/O Register)
Coloca el nivel bajo(limpia) a un bit de un registro de entrada/salida.

Ejemplo

------------------------------------------------------------------------------------------------------------------------------------------------------
El objetivo de este ejemplo es leer el estado de un bit mediante un switch conectado por el pin PB0 y un led en el pin PB7 que reflejará el estado del PB0.
-----------------------------------------------------------------------------------------------------------------------------------------------------

Código
SBIS=1,SBI portb,7

SBIS=0,CBI portb,7
Diagrama de Flujo
Implementación

sábado, 17 de noviembre de 2018

Uso de la instrucción "SBIC"

SBIC(Skip if Bit in I/O register Cleared)
Esta instrucción permite monitorear el estado de un bit, salta a la siguiente instrucción del código si en el bit del registro es detectado el estado bajo("0").
Esta instrucción trabaja con registros I/O.

Instrucción SBIC
I/O R ≤ 31, 0 ≤ b ≤ 7
Ejemplo:
un switch es conectado a pinb2. Escribir un programa que chequee el estado del switch y ejecute lo siguiente:
  • Si pinb,2=1 enviar la letra "00000000" al puerto D.
  • Si pinb,2=0 enviar la letra "11111111" al puerto D.
Código
Pinb,2=0
Pinb,2=1

En este programa el bucle led_encendido esta en lazo cerrado siempre cuando(pinb2=0) es decir después que se ejecute la instrucción sbic pinb,2 va a ver un salto de linea a la siguiente instrucción de código y de esta manera se omite(rjmp) la bifurcación para salir del bucle y además se carga el valor de 255 y luego se escribe en el puerto D. 
Cuando hay bifurcación(rjmp) se carga el valor de 0 y se escribe en el puerto D



Diagrama de flujo

Implementación

miércoles, 14 de noviembre de 2018

Uso de la instrucción "SBIS"

                                                SBIS(Skip if Bit in I/O register Set)
Esta instrucción permite monitorear el estado de un bit, salta a la siguiente instrucción del código si en el bit del registro es detectado el estado alto("1").
Esta instrucción trabaja con registros I/O.
Instrucción SBIS
I/O R ≤ 31, 0 ≤ b ≤ 7
Código.
En este programa el bucle inicio esta en lazo cerrado siempre cuando(pinb2=1) es decir después que se ejecute  la instrucción sbis pinb,2 va a ver un salto de linea a  la siguiente instrucción de código y de esta manera se omite(rjmp) la bifurcación para salir del bucle y además se carga el valor de 255 y luego se escribe en el puerto D. 
Cuando hay bifurcación(rjmp)  se carga el valor de 0 y se escribe en el puerto D.

pinb2=0. 
pinb2=1


Diagrama de flujo.
Implementación.

domingo, 14 de octubre de 2018

Stack o Pila - SP(Stack Pointer) ¿?

Qué es un Stack?
--------------------------------------------------------------------------------------------------------------------------
Un "Stack" es bloque consecutivo de datos almacenados por el programador. Este bloque de memoria puede ser utilizado tanto por el control interno del microcontrolador como por el programador para almacenar datos temporalmente. La pila funciona con un mecanismo tipo LIFO, lo último que se almacena en la pila es lo primero que se recupera de la pila.


Estructura de una Stack-LIFO(Proceso de PUSH y POP)
Esta pila tiene un apuntador conocido como Stack Pointer o SP, el funcionamiento de la pila en el microcontrolador AVR es muy sencillo, la posicion inicial es la dirección superior es decir que si la pila tuviera 100 espacios la primera posicion sería la 100, cuando se almacena un registro en la pila entonces el apuntador disminuye en 1 de manera que el siguiente dato se almacene en la siguiente posicion es decir para nuestro ejemplo sería en la posición 99 así sucesivamente, cuando se saca un dato el SP aumenta para poder sacar el dato siguiente.

La capacidad de la pila cambiará de acuerdo con la referencia del microcontrolador que se esté utilizando, pero en general los microcontroladores AVR necesitan 16 bits para direccionamiento de la Pila, debido a que el microcontrolador AVR es de 8 bits entonces se hace necesario utilizar dos registros para el SP, estos son el SPH y el SPL (high and low) y se refieren a los bits mas significativos y menos significativos respectivamente.



Una pila es un búfer (LIFO), que contiene una cantidad de elementos de datos generalmente implementados como un bloque de n bytes consecutivos.
La dirección del último elemento de datos que se colocará en la pila se señala mediante el puntero de pila (sp)

Aplicación de pilas:
- Almacenamiento temporal de variables.
- Almacenamiento temporal de direcciones de programas
- Comunicación con subrutinas.

La CPU necesita esta área de almacenamiento porque solo hay un número limitado de registros

Qué es un SP?
--------------------------------------------------------------------------------------------------------------------------
En un micro AVR, SP es un registro independiente para propositos de STACK.
SP es un registro especial donde se necesita para operaciones en STACK.
SP es de 16 bits de ancho y se implementa como dos registros que son SPH y SPL.
El registro SPH presenta el byte alto de SP mientras que el registro SPL presenta el byte inferior.
Tanto SPH como SPL tienen 8 bits de ancho.
El SP debe ser lo suficientemente ancho para dirigirse a toda la RAM.
En los AVR con más de 256 bytes de memoria, SP se compone de dos registros de 8 bits (SPL y SPH)
En AVR con menos de 256 bytes de memoria, SP está hecho de sólo registro SPL.

Registro SP

Operaciones en STACK(PUSH-POP)
--------------------------------------------------------------------------------------------------------------------------

>>>PUSH
      Es una intrucción para llenar de datos temporales en la memoria SRAM.
      1-->Se escribe en Stack el dato(en la parte de arriba) , memory[stack]<~~DR(registro de datos)
      2-->disminuye  SP, SP<~~SP-1

Estado inicial
 LDI R16,0x33
 Push R16

Después de Push R16



LDI R17,0x25
Push R17


Después de Push R17
LDI R18,0x20
Push R18
Después de Push R18



-Recordemos que la memoria en $DF es mayor que $DC($DF>$DC).
-En AVR, la pila(STACK) crece de una ubicación de memoria superior a una ubicación de memoria inferior.
-Así, es común inicializar el SP a la ubicación de memoria más alta.
-El puntero de Pila apunta al área de pila de la SRAM de datos donde se localizan la pila de interrupción y de subrutina. Este espacio de la pila en la SRAM de datos debe ser definido por el programa antes de que se ejecute cualquier llamada a subrutina o se habiliten interrupciones. El puntero de pila debe estar a set para apuntar por encima de $60.

>>>POP
         Es una intrucción para sacar  datos temporales de la memoria SRAM

         1-->Incrementa SP, SP<~~SP+1
         2-->Lee la posicición de stack(parte de arriba ) y copia al destino,                                           
                DR(registro de datos) <~~Memoria(Stack).

Para recuperar un byte de datos de la pila usamos la instrucción POP.

POP R18
Después de POP R18


POP R17
Después de POP R17

POP R16
Después de POP R16


Ejemplo de STACK?
--------------------------------------------------------------------------------------------------------------------------
1)
Este ejemplo muestra el STACK y SP(Stack Pointer) y el registro usado despues de la ejecución de cada instrución.

.INCLUDE "M32DEF.INC"
                   .ORG       0
                   LDI          R16,HIGH(RAMEND)
                   OUT         SPH,R16
                   LDI          R16,LOW(RAMEND)
                   OUT         PL,R16
                   LDI           R31,0
                   LDI           R20,0x21
                   LDI           R22,0x66
                   PUSH        R20
                   PUSH        R22
                   LDI           R20,0
                   LDI           R22,0
                   POP           R22
                   POP           R31 

Funcionamiento de STACK y STACK POINTER(SP)
2) 


(LLENADO DE STACK)

PUSH AX ; Coloca Ax en STACK
PUSH BX ; Coloca Bx en STACK
PUSH CX ; Coloca Cx en STACK
PUSH DX ; Coloca Dx en STACK
PUSH SI ; Coloca SI en STACK
PUSH DI ; Coloca DI en STACK
--------
--------; Código que modifica AX,BX,CX,DX,SI,DI
--------

(RECUPERACIÓN DE LOS VALORES DE STACK)

POP DI ; restaura el valor original de DI
POP SI ; restaura el valor original de SI
POP DX ; restaura el valor original de DX
POP CX ; restaura el valor original de CX
POP BX ; restaura el valor original de BX
POP AX ; restaura el valor original de AX

RAMEND?
--------------------------------------------------------------------------------------------------------------------------
RAMEND es una etiqueta que representa la dirección de la última ubicación de memoria en SRAM. Para usar esta etiqueta, debe asegurarse de incluir el archivo de encabezado de definición para el microcontrolador específico.
Las funciones low () y high () son utilizadas por el ensamblador para devolver el byte bajo y el byte alto respectivamente de una palabra de 16 bits. Recuerde que estamos tratando con un microcontrolador de 8 bits que solo puede manejar solo 8 bits a la vez. RAMEND es una palabra de 16 bits y por eso usamos las funciones para dividirla.

.include "M32DEF.Inc"
             LDI R16,low(RAMEND)
             OUT SPL,R16
             LDI R16,high(RAMEND)
             OUT SPH,R16

 Conclusión
--------------------------------------------------------------------------------------------------------------------------
                  

  • El puntero de pila es decrementado en 1 cuando los datos se introducen en la pila con la instrucción PUSH y es decrementado en 2 cuando una dirección se introduce en la pila con llamadas a subrutinas e interrupciones. El puntero de pila es incrementado en 1 cuando el dato se saca de la pila con la instrucción POP y es incrementado en 2 cuando una dirección se saca de la pila con retorno de subrutina RET o retorno de interrupción RETI.
  • El rango que abarcará nuestra Pila /Stack y Stack Pointer  depende del microcontrolador por ejemplo:



miércoles, 10 de octubre de 2018

Conceptos a tener en cuenta

                                                                 Registro DDRX
Registro que se usa para configurar si un pin o puerto X se configura como salida o como entrada.





En general un registro DDR de cualquier puerto , esta dividido en 8 bits, como se muestra el la figura siguiente:
Muchas veces se va a trabajar con los bits de cada registro para ello hay que tener en cuenta como se trabajan en lenguaje C. Aquí un un tutorial ==>>  Trabajo con Bits

-número binario de 8 bits ---> 0b00000000--->>> 0b bit7..........bit0
Ejemplos:
poner a 1 el Bit 0==>0b00000001=(1<<0)
poner a 1 el Bit 1==>0b00000010=(1<<1)
poner a 1 el Bit 2==>0b00000100=(1<<2)
poner a 1 el Bit 3==>0b00001000=(1<<3)
poner a 1 el Bit 4==>0b00010000=(1<<4)
poner a 1 el Bit 5==>0b00100000=(1<<5)
poner a 1 el Bit 6==>0b01000000=(1<<6)
poner a 1 el Bit 7==>0b10000000=(1<<7)

                                                                     Salidas Digital 
DDRX = DDRX|(1<<7)<==>DDRX = DDRX|(0b01000000)<==>DDRX|=(0b01000000)<==> DDRX|=(DDRX7)

---------------------------------------------------------------------------------------------------------------------
Explicación:
DDRX | (0b10000000) ==> Se realiza la operación OR entre el número binario y el registro DDRX, así se logrará que el Bit7 del resultado  se mantenga en 1 lógico en este caso.
y el resto de los Bits serán igual a los de DDRX, en conlusión:
si es que se quiere guardar en el mismo registro DDRX, entonces la situación final sería de la siguiente manera:
DDRX=DDRX|(0b10000000)
se pondrá a 1 si antes estaba en 0 y si ya estaba a 1 se mantendrá a 1, los otros Bits mantendrán sus valores ya que los otros Bits son 0.
---------------------------------------------------------------------------------------------------------------------

Si se desea que los pines 2,4 y 6 se pongan a 1 se puede hacer uno por uno como en el ejemplo anterior, o los 3 en una sola linea de código, veamos:

DDRX=DDRX|((1<<2)|(1<<4)|(1<<6))<==>DDRX=DDRX|((1<<DDRX2)|(1<<DDR4)|(1<<DDR6));

                                                                   Entrada Digital
Configurar el Bit 5 como salida digital:
DDRX&=~(1<<5)<==>DDRX=DDRX&~(0b00100000);
---------------------------------------------------------------------------------------------------------------------
Explicación:
recordemos que & es un operador AND y ~ es un operador negación.
(1<<5) = 0b00100000
~(1<<5) =0b11011111
DDRX&(0b11011111)==> se realiza la operación AND, el bit5 se mantiene en 0 lógico(entrada digital) y el resto como 1 lógico (salida digital).
guardamos el resultado como el nuevo valor del registro DDRX
DDRX=(0b11011111)==> El registro quedó con el Bit5, como único puerto de entrada digital.
--------------------------------------------------------------------------------------------------------------------- 
Se niega el número binario con lo que el bit0 se pone a 0 y todos sus demás bits se ponen a 1, luego se realiza la operación AND con el registro DDRB, con lo que se logra que el bit0 del registro DDRB mediante la operación AND se ponga a 0.

Si es que se requiere en una sola linea hacer que los Bit 2,4 y 6 del puerto B sean configurados como entradas digitales , se puede hacer de la siguiente manera:
DDRB& = ~((1<<2)|(1<<4)|(1<<6));
También puede ser así:

DDRB &=~((1<<DDB2)|(1<<DDB4)|(1<<DDB6));//se usa los nombres de los bits.

Recordemos que el registro DDRX sirve para configurar el puerto X como entrada o como salida.

                                                           Registro PORTX

Su funcionamiento esta ligado al registro anterior(DDR), Tiene dos modos de funcionamiento, mas adelante se verán mas detalladamente:



En general un registro PORT de cualquier puerto, esta dividido en 8 bits, como se muestra el la figura siguiente:
Tiene dos modos de uso según como esta configurado el Registro DDRX.

PRIMER MODO:

Si DDRX está configurado como salida, entonces PORTX funcionará para escribir un valor en el puerto, dicho de otra manera el registro PORTX servirá para poner en alto(1 lógico) ó en bajo(0 lógico) cada bits de ese puerto X.

Ejemplos:

PORTB = 0b10101010; // valor en decimal es de 170, se escribe el valor de 170 en el Puerto B.

PORTB|=(1<<0);//Solo el bit 0 se pone a 1 lógico.
PORTB|=(1<<4);//Solo el bit 4 se pone a 1 lógico.

En ATMEL STUDIO se puede hacer lo siguiente:

PORTB|=(1<<PB0);
PORTB|=(1<<PB4);
PORTB|=((1<<PB0)|(1<<PB4));Si se quiere poner a 1 lógico el bit 0 y bit 4;

PORTB& = ~(1<<0) ;Si es que se quiere poner a cero lógico el bit 0;
PORTB&=~((1<<0)|(1<<4)); Si se quiere poner a cero lógico el bit 0 y el bit 4;//////

SEGUNDO MODO:

Si DDRX está configurado como entrada digital(Bits en 0 lógico), el registro PORTX servirá para activar(1 lógico) o desactivar(0 lógico) las resistencias PULL UP internas al microcontrolador AVR

Ejemplos:

DDRB= 0x00=0b00000000;
PORTB=0b01010100; Activar las resistencias PULL UP de los bits 2,4,6 del puerto B.
PORTB|=(1<<2); activar la resistencia PULL UP del PORTB(bit2).
PORTB|=(1<<2)|(1<<4); activar las resistencias PULL UP del PORTB(bit2 y bit4).
En ATMEL STUDIO se puede hacer lo siguiente:

PORTB|=(1<<PB0);
PORTB|=(1<<PB2)|(1<<PB4)|(1<<PB6); activar las resistencias PULL UP del PORTB(bit2,4 y 6).

                                                          Registro PINX

Independiente si el puerto esta configurado como salida o entrada. el registro PINX leerá el puerto, es decir, con este registro se puede obtener el estado de los valores de los pines del puerto X que esta siendo leído. Una vez obtenida el estado de los valores de los pines se guarda en una variable "Y".




Procedimiento de programación en  C - ATMEL STUDIO 

1=====>> La primera línea de código es la directiva de preprocesador para incluir el archivo de cabecera general de AVR I / O. Esta es una línea importante sin la cual el código podría no ser generado.
                                                  #include <avr/io.h>

2=====>> Algunas directivas para que puedan ser usadas primero necesitan que se definan ciertos parámetros, como por ejemplo:
                                                  #define F_CPU 8000000UL 
/Se refiere a la frecuencia de reloj, en este caso de 8MHz, UL se refiere a Unsignal Lon

3=====>>La siguiente línea para incluir el archivo de cabecera de E / S específico ATmega8. Esto puede ser opcional en algunos IDE, ya que utilizan las propiedades del proyecto para utilizar el archivo de encabezado de E / S adecuado basado en el microcontrolador seleccionado.
# include <avr/iom8.h> for ATmega8
# include <avr/iom32.h>for ATmega32

4=====>>Opcionalmente podemos tener un archivo de biblioteca externa incluyendo lo siguiente. Por ejemplo, para incluir un archivo de biblioteca llamado servo, como escribimos a continuación
#include <util/delay.h>
# include "servo.h"

5=====>>Escribir una función principal con un bucle infinito para hacer que el esqueleto del código C del microcontrolador sea muy básico.

int main(void)
{
while (1)
       {


       }
}

6=====>>Ahora, como ya hemos comentado en la introducción de AVR siempre hay tres registros asociados.
DDRx: registro de dirección de datos, controla la dirección de los pines PORT individualmente.
PORTx: Registro para escribir datos en los pines PORT. Para la operación de salida, el bit respectivo del registro DDRx debe estar en 1.
PINx: Cuando los datos necesitan ser leídos de un pin del PUERTO, entonces necesitamos tener acceso al bit respectivo del registro del PIN. Para que un Pin se configure como entrada, el bit respectivo de la DDRx debe estar en 0.

int main(void)
{
//declaramos puerto C como salida
DDRC = 0xFF;
//Valor inicial del puerto C
PORTC.0 =0xFF;

while (1)
            {
             PORTC = 0b01010101;
            _delay_ms(10);
             PORTC = 0b10101010;
            _delay_ms(10);// no olvidar que cuando se usa retartos se debe de incluir <util/delay.h> pero                primero se debe definir primero la frecuencia en la directiva
            }
}

Lo anterior en la estructura básica para empezar a programar.

NOTAS:

Existen  maneras de reducir el código o hacerlos mas entendible(humanizarlo) realizando definiciones en cabecera(# define), veremos algunos ejemplos:


  • (1)===>Si es que se quiere evitar hacer (1<<PB0); a cada momento podemos definir en cabecera , por ejemplo :

#define _BV(bit) (1 << (bit))  //Convierte un número de bit en un valor de byte.
ahora escribimos solo así 
PORTB|= _BV(PB0); ///PORTB |= _BV(0);

DDRB |= _BV(PB0) | _BV(PB1);
PORTB |= _BV(PB0); 
PORTB &= ~_BV(PB1);

para que se pueda realizar lo anterior se debe primero incluir las librerias de avr 
-->#include <avr/io.h>


  • (2)===>Si es que se quiere evitar  hacer !(PINB & (1<<PB0)), se debe de hacer lo siguiente:

#define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))// Test whether bit bit in IO register sfr is clear. This will return non-zero if the bit is clear, and a 0 if the bit is set.
Comprueba si el bit "bit"(PB0) en el registro PINB está libre. Esto devolverá cero si el bit está limpio, y un 0 si el bit está en establecido.
ahora escribimos solo así
bit_is_clear(PINB,PB0)

  • (3)===>Haremos lo contrario; Si es que se quiere evitar  hacer (PINB & (1<<PB0)), se debe de hacer lo siguiente:

#define bit_is_st(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit))// Test whether bit bit in IO register sfr is set. This will return a 0 if the bit is clear, and non-zero if the bit is set.
Comprueba si el bit "bit"(PB0) en el registro PINB está configurado. Esto devolverá 0 si el bit está limpio, y 1 si el bit está en establecido.

  • (4)====>otra forma de humanizar el código :
#define loop_until_bit_is_clear ( sfr, bit ) do { } while (bit_is_set(sfr, bit))// bit= PB1,etc; sfr=PORTB,etc
Espere hasta que el bit "bit" en el registro entrada/salida sfr esté libre.

  • (5)====>otra forma de humanizar el código :
#define loop_until_bit_is_set ( sfr, bit ) do{}While(bit_is_set(sfr,bit))    
Espere hasta que el bit "bit" en el registro entrada/salida sfr esté establecido.
Para mayor información de las NOTAS se puede revisar este Link.

En resumen

según lo antes visto y reducirlos tiempos de programación se puede expresar lo siguiente:

DDRD|= (1<<DDD0); // DDD0=1= salida
DDRD&=~(1<<DDD1); //DDD1= entrada
PORTD|=(1<<PD1);//
          Si DDD1 está como salida(1 lógico) , entonces PD1=será el valor de un bit en alto.
          Si DDD1 está como entrada(0 lógico), entonces se activará PULL UP para PD1
PORTD &=~(1<<PD0);
         Si DDD0(Registro de configuración de salida / entrada) está como salida(1 lógico),entonces                PD0 será el valor de un bit en bajo(0 lógico).
         Si DDD0 esta como entrada(0 lógico), entonces el registro PORT es para activar o desactivar              las resistencias PULL UPP,en este caso  la resistencia PULL UP de PD0 estará desactivada.

PORTD  ^= (1<<PD0); // Se alterna el valor del led
        
Diagrama de Bloques

Simbología

Se recomienda ver el siguiente VIDEO donde explica muy bien y de manera sencilla la simbología.


domingo, 5 de noviembre de 2017

Programador

En esta serie de ejemplos se realizaran de manera teórica - práctica, se usaran las siguientes herramientas:
  • Circuito Grabador de AVR USBASP---> Link de Descarga, Yo tengo instalado en mi laptop Window8.1 y para poder instalarlo he seguido videos de youtube para que el driver pueda ser reconocido por mi Sistema Operativo.
  • sinaprog 2.1 se va a usar par poder grabar el code al micro y tambien borrarlo si es que se desea y mas cosas.
  • Flowcode V6 para realizar diagrama de Flujos , he usado el programa FlowCode, aquí el Link de descarga.
  • Editor de código--> se usará el Atmel Studio7
Se está usando un Atmega 32A. En argumentos se puso lo siguiente --->avrdude -c usbasp -B 2.0 -p ATMEGA32 -U flash:w:"$(ProjectDir)Debug\$(ItemFileName) .hex":a, tener en cuenta que si se pone ATMEGA32A saldrá error.De lo contrario si es que sale todo bien, saldrá el siguiente mensaje cada vez que le demos click en USBasp avrdude.exe: set SCK frequency to 375000 Hz
avrdude.exe: warning: cannot set sck period. please check for usbasp firmware update.
avrdude.exe: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude.exe: Device signature = 0x1e9502
avrdude.exe: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude.exe: erasing chip
avrdude.exe: set SCK frequency to 375000 Hz
avrdude.exe: warning: cannot set sck period. please check for usbasp firmware update.
avrdude.exe: reading input file "D:\Blog de avr\Codigos\led parpadeante\AssemblerApplication1\AssemblerApplication1\Debug\main .hex"
avrdude.exe: error opening D:\Blog de avr\Codigos\led parpadeante\AssemblerApplication1\AssemblerApplication1\Debug\main .hex: No such file or directory

avrdude.exe: input file D:\Blog de avr\Codigos\led parpadeante\AssemblerApplication1\AssemblerApplication1\Debug\main .hex auto detected as invalid format
avrdude.exe: can't open input file D:\Blog de avr\Codigos\led parpadeante\AssemblerApplication1\AssemblerApplication1\Debug\main .hex: No such file or directory
avrdude.exe: read from file 'D:\Blog de avr\Codigos\led parpadeante\AssemblerApplication1\AssemblerApplication1\Debug\main .hex' failed
avrdude.exe: safemode: Fuses OK
avrdude.exe done. Thank you.
el procedimiento esta detallado en este Blogspot.
  • Para instalar XFeatures - Beta y poder visualizar mejor el código:Se abrirá una ventana con las extensiones y actualizaciones disponibles, como se observa ahy bastantes herramientas que se pueden instalar.
Por ejemplo ahy una herramienta que te permite mejorar la visualización del código y comentarios, llamada XFeatures - Beta:
Antes de Instalar la Aplicación

Después de instalar la aplicación

EJEMPLOS BÁSICOS - LED


                                                          PARPADEO DE UN LED

 * trabajando con bits.c
 *El bit 7 del registro DDRC está  configurado como salida
 *parpadeo del bit 7 del puerto c cada 200 ms.
 * Created: 26/05/2017 11:01:29 a.m.
 * Author : EDWARD
 */

#include <avr/io.h>
#define F_CPU 8000000UL// Frecuencia de clock que se va a usar-8MHz.
#include <util/delay.h>

int main(void)
{
   DDRC|=0b10000000;// DDRC=DDRC| (1<<PC7), PC7=7, Bit PC7 configurado como salida
   PORTC=PORTC&~((1<<PC7)|(1<<PC6)|(1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0));
   //configuración inicial estado 0 lógico de los 8 bits.
    while (1)
    {
PORTC|=(0b10000000);// PORTC|=(1<<7), PORTC=PORTC|(1<<PC7), 1 lógico en bit PC7.
_delay_ms(200);//retardo de 200 ms
PORTC&=~(0b10000000);//PORTC&=~(1<<7),PORTC=PORTC&~(1<<PC7),0 lógico en bit PC7.
_delay_ms(200);//retardo de 200 ms
return(0);
    }
}



Parpadeo de Led