Únete gratis a la revolución de los 32 bits.

Gana un microcontrolador de 32 bits mandando un video donde muestres como te deshaces de un microcontrolador de 8 bits.

La fuente de poder.

Acondiciona la fuente de poder de tu vieja pc para usarla con tus proyectos.

Gamepads de SNES en Windows y Linux.

Adapta tu viejo gamepad de SNES para conectarlo al puerto paralelo (DB25) de la computadora, probado en WinXP y PupppyLinux.

martes, 1 de enero de 2013

PWM Variable con ATMega16


Generar una señal PWM configurable en frecuencia y ciclo útil es de lo más básico, es por eso que en esta entrada mostramos como hacerlo con un microcontrolador ATMega16 en esamblador.

Señal PWM generada (Línea amarilla).

Para lograr esta señal, vamos a hacer un contador ascendente/descendete y vamos a compararlo con una señal de referencia. Para fines ilustrativos, en el circuito se han puesto convertidores DAC del contador (línea azul) y la referencia (línea morada) cuya salidas son conectadas al osciloscopio virtual, sin embargo, esto no es necesario porque todo el proceso se realiza dentro del microcontrolador y podría solo salir la señal PWM deseada por el pin 4 (PB3).

Esquemático del circuito.

Para configurar la señal en tiempo de ejecución, usamos la terminal virtual de ISIS, la cual se comunica de manera serial con el microcontrolador, los comandos usados son:
W: Incrementa la señal de referencia.
S: Disminuye la señal de referencia.
E: Disminuye a frecuencia de operación.
D: Aumenta la frecuencia de operación.

Configurando la señal PWM.


Código en ASM:

.include "m16def.inc"
.device ATmega16

.def temp = R16
.def fre  = R17
.def ref  = R18
.def dato = R19

.cseg
.org 0x000

reset:
ldi temp,0x04;ubica apuntador de la pila
out sph,temp
ldi temp,0x5f
out spl,temp

ldi temp,0xff
out DDRB,temp
out DDRA,temp
out DDRC,temp

ldi temp,  0x71
out TCCR0, temp
ldi temp,  0x00
out TCNT0, temp

ldi temp, 128
out OCR0, temp

rcall conf_usart;configurar la usart
ldi zh, high(2*duty)
ldi zl, low(2*duty)

ldi fre, 1
ldi ref, 5

main:
in temp, TCNT0
out PORTA, temp
in temp, OCR0
out PORTC, temp
sbis ucsra,rxc
rjmp main

rcall recibe
rjmp main

recibe:
in dato,udr
rcall transmite
cpi dato, $57 // W
brne baja_ref
inc ref
mov temp, ref
rcall transmite_temp
cpi ref, 10
brne baja_ref
ldi ref, 1
baja_ref:
cpi dato, $53 // S
brne sube_frec
dec ref
cpi ref, 0
brne sube_frec
ldi ref, 9
sube_frec:
cpi dato, $45 // E
brne baja_frec
inc fre
cpi fre, 6
brne baja_frec
ldi fre, 1
baja_frec:
cpi dato, $44 // D
brne final
dec fre
cpi fre, 0
brne final
ldi fre, 5
final:
ldi zh, high(2*duty)
mov zl, ref
lpm temp, z
out OCR0, temp
ldi zh, high(2*frec)
mov zl, fre
lpm temp, z
out TCCR0, temp
ret

transmite:
sbis ucsra, udre
rjmp transmite
out udr,dato
ret

transmite_temp:
sbis ucsra, udre
rjmp transmite
out udr, temp
ret

conf_usart:
clr r16;valor de recarga para una velocidad de 9600 bps
out ubrrh,r16
ldi r16,12
out ubrrl,r16

ldi r16,0x02;
out ucsra,r16

ldi r16,0x18;habilita receptor y trasmisor
out ucsrb,r16;sin interrupciones

ldi r16,0x86; 1 bit de paro,sin paridad y datos de 8 bits
out ucsrc,r16
ret

.org 0x200
duty: .db 00, 00, 32, 64, 96, 128, 160, 192, 224, 255
.org 0x300
frec: .db $71, $71, $72, $73, $74, $75


Descarga código y simulación aquí.

Comunicación serial PIC a PIC

La comunicación RS232 se ha vuelto obsoleta en cuanto a computadoras se refiere, pero en el mundo de la electrónica sigue siendo un protocolo muy popular.

Es por eso que dedicamos este post a un ejemplo de comunicación serial entre 2 PIC16F877a (un emisor y un receptor), para ello los programas se han escrito en C con el compilador CCS y simulado en ISIS de PROTEUS.

Al puerto B del microcontrolador emisor se le han conectado entradas lógicas, los cuales se muestran en el puerto B del receptor. Ambos microcontroladores tienen un cristal de 20MHz y usan su módulo serial por hardware.


Esquemático y simulación.

Código emisor:
#include "16f877a.h"
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

int main( void ){
int dato;
while(1){
   dato=input_b(); //Recibimos un entero de 8 bits (Puerto B).
   putc(dato); //Mandamos el dato por el puerto serial.
   delay_ms(1000); //Hacemos un retardo
}
return 0;
}


Código receptor:
#include "16f877a.h"
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8)

int main( void ){
int dato;
while(1){
   if(kbhit()){ //Revisamo si hemos recibido algo por el puerto serial.
      dato=getc(); //Recibimos un dato de 8 bits
      output_b(dato);//Mostramos el dato en el puerto B
   }
}
return 0;
}


Esta es la configuración típica utilizada, estos mismos programas se pueden usar si en lugar de un cable se utiliza un módulo Bluetooth serial,ya que el protocolo es transparente para el micro.

Durante la simulación es muy conveniente que el micro nos mande mensajes, así como en un programa de PC normal con la ayuda de la función printf(), para este caso se puede conectar la terminal virtual de ISIS a la línea TX del micro que nos va a mandar la información y, con un simple printf() el programa va a mandar esa cadena por el puerto serial.

Descargar códigos y simulación aquí.