Ayuda con pic16f84 en asm

Quería ver si me podías ayuda con el programa para el control de 2 motores paso a paso unipolares. El programa tiene que estar en asm, para poder programar el pic16f84. Se supone que tengo que construir un brazo robot, un motor es para la base y el otro es para abrir y cerrar una pinza.

1 respuesta

Respuesta
1
Claro que si, realmente programar un pic es sencillo y tal vez donde más problema hay es al momento de configurar configurarlo, configurar puertos para que sean entrada o salida, tipo de oscilador, etc. por lo pronto le hecho una ojeada a los apuntes del pic, Por lo pronto ve pensando que puertos y que pines vas a usar para el control del pic, cuales y que código se usara para el motor, que pines serán y que vas a usar para controlar el brazo (botones, pc->código que usaras).
Y específicamente en que parte quieres que te ayude, si solamente el programa o todo el circuito. Por lo pronto dime que tanto sabes del Pic y así avanzamos más rapido.
Lo que se de pics no es mucho, he empezado hace un mes más o menos, con un proyecto de un motor paso a paso, use de driver el uln 2803 y en el protoboard puse las botoneras una iba conectada a ra0 que hacia que girara a la derecha, otra a ra1 hacia que girara a la izquierda y la otra al masterclear, configure el puerto a como entrada y el b como salida, pero la cosa esta en que tiene que utilizar ahora interrupciones, y no se muy bien como ponerlas dentro de un programa, por eso quería tu ayuda con el programa para poder entender mejor ademas que no se como se hace para poder controlar dos motores pap unipolares, aquí te dejo el programa de mi primer proyecto, a ver si me puedes agregar algo para poder lograr concluir este proyecto del brazo, ya que me interesa mucho (espero haberme explicado bien)
LIST P=16F84
STATUS EQU 03h ; REGISTRO ESTADO
PORTA EQU 05h ; PUERTO A
PORTB EQU 06h ; PUERTO B
Trisa equ 85h ; registro configuración puerto a
trisb equ 86h ; registro configuración puerto b
tiemp1 equ 0ch ; registros de propósito general
TIEMP2 EQU 1Ch
TIEMP3 EQU 2Ch
ORG 00h ; INDICA AL COMPILADOR DONDE COMIENZA EL PROGRAMA
GOTO INICIO ; VA A SUBRUTINA INICIO
Inicio
BSF STATUS, 5
MOVLW B'11111' ; CARGA '11111' EN EL REGISTRO DE TRABAJO 'W'
MOVWF TRISA ; CARGA 'W' EN EL PUERTO A
MOVLW B'00000000' ; CARGA '00000000' EN EL REGISTRO DE TRABAJO 'W'
MOVWF TRISB ; CARGA 'W' EN EL PUERTO B
BCF STATUS, 5 ; VUELVE A 0
GOTO GIRO ; VA A SUBRUTINA GIRO
Giro
BTFSC PORTA, 0 ; EN ESTE PUERTO DA EL GIRO A LA IZQUIERDA
GOTO GIRO1
GOTO IZQUIERDA
giro1
btfsc porta, 1 ; en este puerto da el giro a la derecha
goto giro
goto derecha
derecha
movlw b'00001100' ; primer paso.
MOVWF PORTB
CALL TIEMPO ; TEMPORIZACIÓN ANTES DE PASAR AL SIGIENTE PASO
MOVLW B'00000110' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00000011' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00001001' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELE A GIRO PARA MIRAR EL ESTADO DEL BIT
Izquierda
MOVLW B'00001001' ; PRIMER PASO
MOVWF PORTB
CALL TIEMPO ; TEMPORIZACIÓN ANTES DE PASAR AL SIGUIENTE PASO
MOVLW B'00000011' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00000110' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00001100' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELVE A GIRO PARA MIRAR EL ESTADO DEL BIT
Tiempo
MOVLW D'10' ; CARGA CON UN LITERAL TIEMP1
MOVWF TIEMP1
tiempo2
MOVLW D'100'
MOVWF TIEMP2
tiempo3
MOVLW D'100'
MOVWF TIEMP3
tiempo4
decfsz tiemp3, 1 ; decrementa tiemp3 y si es 0 salta
goto tiempo4 ; volver a tiempo4
decfsz tiemp2, 1 ; decrementa tiemp2 y si es 0 salta
goto tiempo3 ; volver a tiempo3
decfsz tiemp1, 1 ; decrementa tiemp1 y si es 0 salta
goto tiempo2 ; volver a tiempo2
return ; retorna de donde fue llamada
end ; fin
gracias por responderme, y darte el tiempo de explicarme
Para empezar ya tienes bastante avanzado tu programita, y empezaremos con lo que es controlar 2 motores:
Aprovechando que tienes 4 bits disponibles en el puert B, ahí es donde conectaras el otro driver, obviamente en tu programa anexaras otras rutinas para mover hacia la dcha o la izda el otro motor, y claro otros 2 botones (2 para 1 motor y otros 2 para el otro), y pues lo que vas a modificar en tu programa sera al momento de cargar los códigos en el registro w para posteriormente pasarlos al puerto b, algo como lo siguiente:
*PARA EL MOTOR QUE SE CONTROLA CON B0,B1,B2 Y B3*
DERECHA
// MOVLW B'00001100' ;quitar
MOVF PORTB,0;MUEVE PORTB A W
ANDLW B'11110000';PARA BORRAR PARTE BAJA DE W
IORLW B'00001100';PARA AGREGAR PRIMER CODIGO DE GIRO
MOVWF PORTB
CALL TIEMPO ; TEMPORIZACIÓN ANTES DE PASAR AL SIGIENTE PASO
//MOVLW B'00000110' ;QUITAR
MOVF PORTB,0;MUEVE PORTB A W
ANDLW B'11110000';PARA BORRAR PARTE BAJA DE W
IORLW B'00000110';PARA AGREGAR SEGUNDO CODIGO DE GIRO
MOVWF PORTB
CALL TIEMPO
ETC...
Las operaciones andlw y iorlw son una and y una or (correspondientemente) que te servirán para en el caso de la andlw para borrar ciertos bits de w ( w .and. que -> w), y la iorlw te servirá para poner el código que quieras, hay que tener cuidado y control de que parte del puerto estas controlando.
Sobre el manejo de interrupciones, hace tiempo que no las manejo, pero lo que recuerdo es que primero que nada debes de elegir cuales interrupciones vas a querer utilizar seleccionando con el registro intcon (0bh), y pues estas trabajan así:
Cuando es llamada una interrupción, el pic hace ciertas operaciones (guarda en que instrucción va) y se translada a ejecutar el código que pones en el interrupt vector, osea la parte del programa que esta en la dirección 0004h (por eso es tan importante la instrucción "org").
Entonces tu iniciaras tu programa así (después de las declaraciones):
ORG 00H
GOTO INICIO
ORG 04H
CALL SUB_CORRESPOD._A_LA_INT.
org 0ah
Inicio
* EL RESTO DEL PROGRAMA *
Si tienes varias interrupciones, pues después de org 04h tendrás que checar cual interrupción se activo (revisando el registro de interrupciones) y de ahí un call a la subrutina correspondiente.
Finalmente con retfie regresas de la interrupción.
Espero esto te ayude.
Disculpa por la tardanza en la contestación, solo que estoy atareado con la elaboración de los programas y cálculos para utilidades ;)
Estoy a tus ordenes
Disculpa, tu ayuda me sirvió pero ahora me vengo a enterar de que tiene que el programa tiene que tener estas especificaciones:
El control de los motores stepper se debe efectuar por medio de botones (4 botones). Las subrutinas de tiempo asociadas a los motores stepper se deben realizar por medio del TMR0. No se aceptarán subrutinas de decremento de registros.
Es importante que se incluya en el diseño del programa el concepto de interrupciones.
Estas especificaciones fueron dadas por un profesor.
Espero que me puedas ayudar como lo has hecho hasta ahora y si no puedes, por tiempo o algo más no importa igual estoy agradecido.
Ok, ahora si me libre de pendientes y vamos a echarle ganas a tu proyecto.
Permite tantito, ahora si le voy a entrar duro con esto, ¿por lo pronto que tanto haz avanzado?, para esta altura solo te debe faltar la parte correspondiente al TMR0. No se si haz intentado lo del vector de interrupción.
* Dime que avances tienes mientras te consigo toda la información para el manejo del TMRO mediante interrupciones.
Estamos en contacto!
Hola que bueno que me has respondido, el programa que tengo tiene los movimientos y se supone que interrupciones pero no estoy segurode esto haci que te dejo el programa lo vez le cambias lo que haya que cambiar para que me funcione, ya que esto es para el 4 de junio
list p=16f84
status equ 03h ; registro estado
Porta equ 05h ; puerto a
PORTB EQU 06h ; PUERTO B
OPTION_REG EQU 81h ; REGISTRO DE INTERRUPCION
INTCON EQU 0bh
TMR0 EQU 01h ; REGISTRO DE TIMER
Trisa equ 85h ; registro configuración puerto a
trisb equ 86h ; registro configuración puerto b
ORG 00h ; INDICA AL COMPILADOR DONDE COMIENZA EL PROGRAMA
GOTO INICIO ; VA A SUBRUTINA INICIO
ORG 04h
GOTO CONTROL
Inicio
BSF STATUS, 5
MOVLW B'11111' ; CARGA '11111' EN EL REGISTRO DE TRABAJO 'W'
MOVWF TRISA ; CARGA 'W' EN EL PUERTO A
MOVLW B'00000000' ; CARGA '00000000' EN EL REGISTRO DE TRABAJO 'W'
MOVWF TRISB ; CARGA 'W' EN EL PUERTO B
MOVLW B'00000111' ; CARGA '00000111' EN EL REGISTRO DE TRABAJO 'W'
MOVWF OPTION_REG ; CONFIGURAMOS TMR0 COMO CONTADOR DESCENDENTE
BCF STATUS, 5 ; VUELVE A 0
CLRF PORTA
CLRF PORTB
Control
MOVLW D'60' ; W=60
MOVWF TMR0 ; TMR0=60
GIRO
BTFSC PORTA,0 ; EN ESTE PUERTO DA EL GIRO A LA IZQUIERDA
GOTO GIRO1
GOTO IZQUIERDA
GIRO1
BTFSC PORTA,1 ; EN ESTE PUERTO DA EL GIRO A LA DERECHA
GOTO GIRO2
GOTO DERECHA
GIRO2
BTFSC PORTA,2 ; EN ESTE PUERTO ABRE
GOTO GIRO3
GOTO ABRE
GIRO3
BTFSC PORTA,3 ; EN ESTE PUERTO CIERRA
GOTO GIRO
GOTO CIERRA
DERECHA
MOVLW B'00001100' ; PRIMER PASO.
MOVWF PORTB
CALL TIEMPO ; TEMPORIZACIÓN ANTES DE PASAR AL SIGIENTE PASO
MOVLW B'00000110' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00000011' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00001001' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELE A GIRO PARA MIRAR EL ESTADO DEL BIT
Izquierda
MOVLW B'00001001' ; PRIMER PASO
MOVWF PORTB
CALL TIEMPO ; TEMPORIZACIÓN ANTES DE PASAR AL SIGUIENTE PASO
MOVLW B'00000011' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00000110' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00001100' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELVE A GIRO PARA MIRAR EL ESTADO DEL BIT
Cierra
MOVLW B'11000000' ; PRIMER PASO.
MOVWF PORTB
CALL TIEMPO ; TEMPORIZACIÓN ANTES DE PASAR AL SIGIENTE PASO
MOVLW B'01100000' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00110000' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'10010000' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELE A GIRO PARA MIRAR EL ESTADO DEL BIT
Abre
MOVLW B'10010000' ; PRIMER PASO
MOVWF PORTB
CALL TIEMPO ; TEMPORIZACIÓN ANTES DE PASAR AL SIGUIENTE PASO
MOVLW B'00110000' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'01100000' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'11000000' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELVE A GIRO PARA MIRAR EL ESTADO DEL BIT
Tiempo
decfsz tmr0, 1 ; controla y decrementa
goto tiempo ; control de intentar
retfie ; vuelve tras interrupción
end
tengo el dilema en las interrupciones así que ayudame por favor
Aquí te mando unas modificaciones al programa, NO LAS HE PROBADO NI DEPURADO, te pueden dar idea del uso de interrupciones, aclaro que para tu programa no tiene sentido usar interrupciones pero si usar el TMR0 en operación libre (solo se incrementa cuando pasa de FF a 00 activa una bandera y si lo deseas una interrupción), dejo un pequeño apartado por si deseas agregar algo cuando la interrupción se active.
Espero te sirva y no tengas problemas con las correcciones al código (mínimas).
Cualquier cosa solo escribe y de inmediato te contesto.
Suerte con tu proyecto.
LIST P=16F84
Status equ 03h ; registro estado
Porta equ 05h ; puerto a
PORTB EQU 06h ; PUERTO B
OPTION_REG EQU 81h ; REGISTRO DE INTERRUPCION
INTCON EQU 0bh ; REGISTRO CONTROL DE INTERRUPCIONES
TMR0 EQU 01h ; REGISTRO DE TIMER
Trisa equ 85h ; registro configuración puerto a
trisb equ 86h ; registro configuración puerto b
gie equ 07h ; bit activación de interrupciones
toif equ 02h ; bit bandera desbordamiento de tmr0
ORG 00h ; INDICA AL COMPILADOR DONDE COMIENZA EL PROGRAMA
GOTO INICIO ; VA A SUBRUTINA INICIO
org 04h ; subrutinas de interrupciones
; Algo que se quiera hacer en la interrupción, en este caso no la utilizo
retfie ; vuelve tras interrupción
Inicio
MOVLW B'00100000'
Movwf intcon ; preparo intcon para habilitar solo interrupción de tmr0
; SOLO FALTA ACTIVAR BIT 7 "GIE"
BSF STATUS, 5 ; ACTIVO BANCO 1
MOVLW B'11111' ; CARGA '11111' EN EL REGISTRO DE TRABAJO 'W'
MOVWF TRISA ; CARGA 'W' EN EL PUERTO A
MOVLW B'00000000' ; CARGA '00000000' EN EL REGISTRO DE TRABAJO 'W'
MOVWF TRISB ; CARGA 'W' EN EL PUERTO B
MOVLW B'00000111' ; CARGA '00000111' EN EL REGISTRO DE TRABAJO 'W'
MOVWF OPTION_REG ; CONFIGURAMOS TMR0 COMO CONTADOR DESCENDENTE
; OSCILADOR INTERNO, PRESCALER 1:256
BCF STATUS, 5 ; VUELVE A BANCO 0
CLRF PORTA
CLRF PORTB
Giro
BTFSC PORTA,0 ; BIT 0 - GIRO A LA IZQUIERDA
GOTO GIRO1
GOTO IZQUIERDA
GIRO1
BTFSC PORTA,1 ; BIT 1 - GIRO A LA DERECHA
GOTO GIRO2
GOTO DERECHA
GIRO2
BTFSC PORTA,2 ; BIT 2 - ABRE
GOTO GIRO3
GOTO ABRE
GIRO3
BTFSC PORTA,3 ; BIT 3 - CIERRA
GOTO GIRO
GOTO CIERRA
Derecha
MOVLW B'00001100' ; PRIMER PASO.
MOVWF PORTB
CALL TIEMPO
MOVLW B'00000110' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00000011' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00001001' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELE A GIRO PARA MIRAR EL ESTADO DEL BIT
Izquierda
MOVLW B'00001001' ; PRIMER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00000011' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00000110' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00001100' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELVE A GIRO PARA MIRAR EL ESTADO DEL BIT
Cierra
MOVLW B'11000000' ; PRIMER PASO.
MOVWF PORTB
CALL TIEMPO ; TEMPORIZACIÓN ANTES DE PASAR AL SIGIENTE PASO
MOVLW B'01100000' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00110000' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'10010000' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELE A GIRO PARA MIRAR EL ESTADO DEL BIT
Abre
MOVLW B'10010000' ; PRIMER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'00110000' ; SEGUNDO PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'01100000' ; TERCER PASO
MOVWF PORTB
CALL TIEMPO
MOVLW B'11000000' ; CUARTO PASO
MOVWF PORTB
CALL TIEMPO
GOTO GIRO ; SE VUELVE A GIRO PARA MIRAR EL ESTADO DEL BIT
Tiempo
MOVLW 00h
Movwf tmr0 ; pone en 0 el tmr0, si tarda mucho cambiar el prescaler
bcf intcon, toif ; pongo en 0 la bandera de desbordamiento del tmr0
bsf intcon, gie ; activo interrupciones (solo la del tmr0 esta activa)
BTFSS INTCONT,TOIF ; ESPERO HASTA QUE TMR0 CUENTE HASTA 255 Y ENCIENDA TOIF
BCF INTCON,GIE ; DESACTIVO INTERRUPCIONES
RETURN
END
Hola de nuevo te escribo para decirte unas cosas, sabes probé tu programa en mi circuito con unos leds correctamente conectados todo y no funciono la secuecia, se supone que se tienen que encender 2 leds a la vez después de presionar la botonera y con el programa que hiciste estaban dos leds prendidos y cuando presionaba en la botonera habían 4 leds prendidos, yo creo que es un problema con el tiempo y otra consulta es acerca de la parte de inicio de programa que esta a continuación
ORG 00h ; INDICA AL COMPILADOR DONDE COMIENZA EL PROGRAMA
GOTO INICIO ; VA A SUBRUTINA INICIO
ORG 04h ; SUBRUTINAS DE INTERRUPCIONES
; ALGO QUE SE QUIERA HACER EN LA INTERRUPCION, EN ESTE CASO NO LA UTILIZO
RETFIE ; VUELVE TRAS INTERRUPCION
AQUI DESPUES DE ORG 04H SE SUPONE QUE DEBERIA IR UN GOTO A UNA SUBRUTINA DE INTERRUPCION O EN ESTE PROGRAMA NO ES NECESARIO Y SOLO LE PONGO RETFIE DESPUES DEL VECTOR
Espero tu respuesta
De antemano gracias
Ok, ahora si, ya compile y revise el programa, te recomiendo que antes de probar el programa directamente el circuito uses un simulador es un software que te permite correr el programa y ver lo que esta pasando con los registros internos así como las salidas en el microprocesador.
Por lo pronto ya probé el programa, parece que funciona bien, tal vez necesite algunas correcciones pero son mínimas, para probar la interrepcion (que funciono perfectamente) use un contador en la dirección 0Dh este se incrementa cada vez que ocurre una interrupción.
Y pues te pido alguna dirección de correo a donde mandarte el programa y de paso te mando el SIM84 (simulador para el pic) que te va a ser muy útil en tus futuros trabajos.
hola mándamelo a [email protected]
Gracias
Te mande el programita y el software del simulador.
Suerte en tu proyecto!

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas