Autor Tema: programa entrada analogica salida a pc por usart  (Leído 2545 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado aamoros79

  • PIC10
  • *
  • Mensajes: 46
programa entrada analogica salida a pc por usart
« en: 21 de Marzo de 2006, 03:52:00 »
hola a todos.
aun soy novatilla en este tema asi que pido ayuda.
tengo una entrada analogica y los datos que vienen por ella los quiero almacenar en un ordenador.
he pensado entrada AN0 y salida por puerto serie, el programa es el siguiente(si hay algo mal por favor indicarme que es)(no es  todo el programa todavia me queda configurar el puerto serie)

   Title  "primer programa"
;queremos que teniendo una entrada analogica
;los datos que entren por esta salgan por el puerto serie y vayan al pc


      list p=16f877       ; processor type
      include "p16f876.inc"
;------------
;definiciones
;------------


TRISB      equ 0x86      ; direccion TrisB RAM
PORTB      equ 0x06      ; direccion PortB RAM

ADCON0      equ 0x1F      ; direccion ADCON0 RAM
ADCON1      equ 0x9F      ; direccion ADCON1 RAM
GO      equ 0x04      ; GO = bit 2 de ADCON0 (¿tengo que definirlo?)
PIR1      equ 0x0C      ; direccion PIR1 RAM
PIE1      equ 0x8C      ; direccion PIE1 RAM
ADIF      equ 0x04      ; ADIF = bit 6 de PIR1 (¿tengo que definirlo?)
ADIE      equ 0x04      ; ADIE = bit 6 de PIE1 (¿tengo que definirlo?)
INTCON      equ 0x0B      ; direccion INTCON RAM (banco0)
PEIE      equ 0x04      ; PEIE = bit 6 de INTCON (¿tengo que definirlo?)
GIE      equ 0x04      ; GIE = bit 7 de INTCON (¿tengo que definirlo?)


; -------------
; PROGRAM START
; -------------

Start      clrf   PORTB      ; LIMPIA TODOS LOS BITS DE PORTB
      clrf   TRISB      ; PORTB como Outputs
      call   IniciaAD    ; configura modulo A/D
               ; & permite Interrupciones   
      bsf   ADCON0,GO   ; comienza primera conversion A/D

Main      GoTo   Main      ; do nothing loop

;---------------------------------------------------------
; IniciaAD - inicializa e instala el hardware a/d.
; Selecion de AN0  como entrada analogica, RC clock.
; Permire interrupciones
;---------------------------------------------------------

IniciaAD   movLW   B"10001110"   ; RA0 analog inputs(EL RESTO RAx SERAN SEÑALES I/O DIGITALES)
      movWF   ADCON1

      movLW   B"11000001"   ; Select RC osc (FOSC/2), AN0 selected
      movWF   ADCON0      ; A/D enabled

      bCF   PIR1,ADIF   ; Limpia A/D interrupt flag
      bSF   PIE1,ADIE   ; Permite A/D interrupt
   
      bSF   INTCON,PEIE   ; Enable peripheral interrupts
      bSF   INTCON,GIE   ; Enable Global interrupts

      RETURN         ; Subroutine Return      

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
RE: programa entrada analogica salida a pc por usart
« Respuesta #1 en: 21 de Marzo de 2006, 05:36:00 »
Hola, antes que nada bienvenida al mundo de los Pics.

Te pasaré a explicar.

Escrito originalmente por aamoros79

Codigo:

   list p=16f877       ; processor type
   include "p16f876.inc"
;------------
;definiciones
;------------

TRISB      equ 0x86      ; direccion TrisB RAM
PORTB      equ 0x06      ; direccion PortB RAM

ADCON0      equ 0x1F      ; direccion ADCON0 RAM
ADCON1      equ 0x9F      ; direccion ADCON1 RAM
GO      equ 0x04      ; GO = bit 2 de ADCON0 (¿tengo que definirlo?)
PIR1      equ 0x0C      ; direccion PIR1 RAM
PIE1      equ 0x8C      ; direccion PIE1 RAM
ADIF      equ 0x04      ; ADIF = bit 6 de PIR1 (¿tengo que definirlo?)
ADIE      equ 0x04      ; ADIE = bit 6 de PIE1 (¿tengo que definirlo?)
INTCON      equ 0x0B      ; direccion INTCON RAM (banco0)
PEIE      equ 0x04      ; PEIE = bit 6 de INTCON (¿tengo que definirlo?)
GIE      equ 0x04      ; GIE = bit 7 de INTCON (¿tengo que definirlo?)






Si usas el include "p16f876.inc" no te hace falta redefinir todos estos registros, y dije TODOS.
Ni siquiera el TRISB o el PORTB ya que estas redefiniendo algo que ya está definido en el .inc




Escrito originalmente por aamoros79

Codigo:

; -------------
; PROGRAM START
; -------------

Start      clrf   PORTB      ; LIMPIA TODOS LOS BITS DE PORTB
      clrf   TRISB      ; PORTB como Outputs
      call   IniciaAD    ; configura modulo A/D
               ; & permite Interrupciones   
      bsf   ADCON0,GO   ; comienza primera conversion A/D

Main      GoTo   Main      ; do nothing loop

;---------------------------------------------------------
; IniciaAD - inicializa e instala el hardware a/d.
; Selecion de AN0  como entrada analogica, RC clock.
; Permire interrupciones
;---------------------------------------------------------

IniciaAD   movLW   B"10001110"   ; RA0 analog inputs(EL RESTO RAx SERAN SEÑALES I/O DIGITALES)
      movWF   ADCON1

      movLW   B"11000001"   ; Select RC osc (FOSC/2), AN0 selected
      movWF   ADCON0      ; A/D enabled

      bCF   PIR1,ADIF   ; Limpia A/D interrupt flag
      bSF   PIE1,ADIE   ; Permite A/D interrupt
   
      bSF   INTCON,PEIE   ; Enable peripheral interrupts
      bSF   INTCON,GIE   ; Enable Global interrupts

      RETURN         ; Subroutine Return      





No estas haciendo caso al tema de las páginas de memoria.

El ADCON0 está en la página 0 y el ADCON1 en la página 1.
El PIR1 está en la página 0 y el PIE1 en la página 1.

Entonces, debes indicarle al pic que redireccione a la página 1.
Cuando se resetea el PIC comienza en la página 0 de memoria de datos también (bits RP0 y RP1 del status en 0).
Esto se haría asi.


Codigo:

; -------------
; PROGRAM START
; -------------

Start      clrf   PORTB      ; LIMPIA TODOS LOS BITS DE PORTB
      clrf   TRISB      ; PORTB como Outputs
      call   IniciaAD    ; configura modulo A/D
               ; & permite Interrupciones   
      bsf   ADCON0,GO   ; comienza primera conversion A/D

Main      GoTo   Main      ; do nothing loop

;---------------------------------------------------------
; IniciaAD - inicializa e instala el hardware a/d.
; Selecion de AN0  como entrada analogica, RC clock.
; Permire interrupciones
;---------------------------------------------------------

IniciaAD
      bsf   STATUS,RP0   ; Pasar a RAM BANK #1
      movlw   B"10001110"   ; RA0 analog inputs(EL RESTO RAx SERAN SEÑALES I/O DIGITALES)
      movwf   ADCON1

      bcf   STATUS,RP0   ; Pasar a RAM BANK #0
      movlw   B"11000001"   ; Select RC osc (FOSC/2), AN0 selected
      movwf   ADCON0      ; A/D enabled

      bcf   PIR1,ADIF   ; Limpia A/D interrupt flag

      bsf   STATUS,RP0   ; Pasar a RAM BANK #1
      bsf   PIE1,ADIE   ; Permite A/D interrupt
      bcf   STATUS,RP0   ; Pasar a RAM BANK #0
   
      bsf   INTCON,PEIE   ; Enable peripheral interrupts
      bsf   INTCON,GIE   ; Enable Global interrupts

      return         ; Subroutine Return      



Con eso solucionaras el problema de la configuración.

Ahora, no es necesario que actives el GIE y PEIE si no utilizarás interrupciones, pero bueno todavía te falta lo de la USART que no se como lo piensas hacer.
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado aamoros79

  • PIC10
  • *
  • Mensajes: 46
RE: programa entrada analogica salida a pc por usart
« Respuesta #2 en: 22 de Marzo de 2006, 01:46:00 »
gracias maunix, me has sido de gran ayuda.
he hecho algunos cambios en el programa, haber que te parece.
y muchas gracias

Title  "primer programa"
;queremos que teniendo una entrada analogica
;los datos que entren por esta salgan por el puerto seriey vayan al pc


      list p=16f877       ; processor type
      include <p16f876.inc>

; ---------------
; PROGRAM START
; ---------------

      org 00h         ; direccion de comienzo = 0000
      goto START
      org 04h         ; direccion de interrupcion
      goto INTERRUPCION


START      clrf   PORTC      ; Limpia todos los bits de PORTC
      clrf   TRISC      ; PORTC como Outputs
      call   INICIAAD    ; configura modulo A/D
               ; & permite Interrupciones   
      call   ESPERA
      bsf   ADCON0,GO   ; comienza primera conversion A/D
LOOP      goto   LOOP


;---------------------------------------------------------
; IniciaAD - inicializa e instala el hardware a/d.
; Selecion de AN0  como entrada analogica, RC clock.
; Permire interrupciones
;---------------------------------------------------------

INICIAAD   bsf   STATUS,RP0   ; Pasar a RAM BANK #1
      movlw   B"00001110"   ; RA0 analog inputs(el resto RAx I/O digitales)
      movwf   ADCON1      ; justificado a la izquierda,
               ; 8 bits mas s ignificativos en ADRESH
      
      bcf   STATUS,RP0   ; Pasar a RAM BANK #0
      movLW   B"01000001"   ; Select RC osc (FOSC/8), AN0 selected
      movWF   ADCON0      ; A/D enabled

      bsf   STATUS,RP0   ; Pasar a RAM BANK #1
      bsf   PIE1,ADIE   ; Permite A/D interrupt
      bcf   STATUS,RP0   ; Pasar a RAM BANK #0

   
      bSF   INTCON,PEIE   ; Enable peripheral interrupts
      bSF   INTCON,GIE   ; Enable Global interrupts
      return
;-------------------------------------------------------
; ESPERA - necesitamos un tiempo de retraso
; para que se pueda asegurar la adquisicion de datos.
;-------------------------------------------------------

ESPERA      btfss    PIR1,ADIF   ; espera a que acabe la conversion
      goto    ESPERA
      clrf    ADCON0      ; para el conversor A/D
      return            
;------------------------------------------------------
; INTERRUPCION - salidas puerto serie?
;------------------------------------------------------

INTERRUPCION   btfss    PIR1,ADIF   ; espera a que acabe la conversion
      retfie         ; retorno de interrupcion
      movf   ADRESH,W   ; cojo los 8 bits mas peso
      movwf   PORTB      ; los muestro PORTB
      bcf    PIR1,ADIF   ; reseteo el flag
      call   ESPERA
      call   ESPERA
      bsf    ADCON0,GO   ; lanzo una nueva conversion
      retfie


END


pd: aunque he puesto end se que tengo que poner algo mas , es solo provisional para que no se me olvide

Desconectado aamoros79

  • PIC10
  • *
  • Mensajes: 46
RE: programa entrada analogica salida a pc por usart
« Respuesta #3 en: 23 de Marzo de 2006, 04:36:00 »
 bueno al final he hecho muchos cambios, creo
poco a pco me voy enterando de como se programa, jeje
 mando el programa final haber si esta bien por fin y es el definitivo

      Title  "primer programa"
;queremos que teniendo una entrada analogica
;los datos que entren por esta salgan por el puerto serie y vayan al pc


      list p=16f877       ; processor type
      include <p16f876.inc>

;-------
; RESET
;-------
      org 00h         ; direccion de comienzo = 0000
               ; cuando se produce un reset o comienza el programa
      goto INICIO      ; va a la primera instruccion del programa

      
; --------------------
; INICIO DE PROGRAMA
; --------------------

INICIO      clrf   PORTC      ; Limpia todos los bits de PORTC
      clrf   PORTB      ; Limpia todos los bits de PORTB
      movlw   b"11111111"
      movwf   TRISA      ; PORTA como entradas

      bsf   STATUS,5   ; (bit RP0 del registro STATUS)5=banco1
      bsf   RCSTA,7      ; Activamos la USART (bit SPEN del
               ; registro RCSTA) 7=habilito puerto serie   
      clrf   TRISB      ; puertab como salida
      movlw   b"10111111"   ; RC7/RX entrada
      movwf   TRISC      ; RC6/TX salida
      
      movlw   b"00100100"   ; Configuramos USART para high speed y
               ; permitimos transmisión
      movwf   TXSTA      ; y activacion de transmision (asincrono)
      
      movlw   d"25"      ; Miramos la tablas del datasheet y
               ; escribimos 25 en SPBRG
      movwf   SPBRG      ; para configurar una velocidad de
               ; transmisión de 9600 BAUDIOS a 4 MHz
      bcf   STATUS,5   ; elegimos BANCO0
      movlw   b"10000000"   
      movwf   RCSTA      ; habilito puerto serie
      bsf   STATUS,5   ; banco1
      bsf   TXSTA,5      ; 5=TXEN habilita la transmision
      bcf   STATUS,5   ; elegimos BANCO0

      call   INICIAAD    ; configura modulo A/D
      call   ENVIAR      ; envia datos por puerto serie
      
      movlw   b"10000000"   ; hago parpadear led q indica que funciona
      xorwf   PORTB,F
      goto    INICIAAD

;---------------------------------------------------------
; IniciaAD - inicializa e instala el hardware a/d.
; Selecion de AN0  como entrada analogica, RC clock.
; Permire interrupciones
;---------------------------------------------------------

INICIAAD   bsf   STATUS,5   ; Pasar a RAM BANCO1
      movlw   B"00001110"   ; RA0 analog inputs(el resto RAx I/O digitales)
      movwf   ADCON1      ; justificado a la izquierda,
               ; 8 bits mas s ignificativos en ADRESH
      
      movLW   B"01000001"   ; Selecciono RC osc (FOSC/8), AN0
      movWF   ADCON0      ; A/D habilitado

      bsf   ADCON0,2   ; 2=GO , la conversion esta en proceso

;-------------------------------------------------------
; ESPERA - necesitamos un tiempo de retraso
; para que se pueda asegurar la adquisicion de datos.
;-------------------------------------------------------

ESPERA      btfsc   ADCON0,2   ; si go=0 la siguiente instruccion es descartada
               ; (ejecuta NOP) saltando a la siguiente
               ; si go=1 ejecuta la siguiente instruccion      
      goto ESPERA
      return

;----------------------------------------------------
; ENVIAR datos por puerto serie
;----------------------------------------------------
   
ENVIAR      movwf   TXREG      ; Movemos lo que queremos transmitir    
               ; (debe estar en el registro W)
      bsf   STATUS,5   ; al registro TXREG y empezamos a transmitir
      bcf   STATUS,6   ; Elegimos BANCO2
FIN_TX      btfss   RCSTA,1      ; Compruebo si el bit TMRT del registro esta
               ; a "1" o a "0".
      goto   FIN_TX      ; Si esta a "0" es que esta lleno TMRT y no
               ; ha terminado de transmitir,
               ; para ello TRMT tiene que estar a 1, hasta
               ; entonces esperamos.
      bcf   STATUS,5   ; Elegimos BANCO0
      return         

END

   ; Al programar el micro tener en cuenta
   ; los fusibles de configuracion
   ; WDT = OFF
   ; OSC = XT
   ; PWRT = ON
 

gracias






Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
RE: programa entrada analogica salida a pc por usart
« Respuesta #4 en: 23 de Marzo de 2006, 06:26:00 »
Escrito originalmente por aamoros79
bueno al final he hecho muchos cambios, creo
poco a pco me voy enterando de como se programa, jeje
 mando el programa final haber si esta bien por fin y es el definitivo



Me alegro que vayas entendiendo como funciona la cuestíon Sonrisa

Escrito originalmente por aamoros79

Codigo:

      Title  "primer programa"
;queremos que teniendo una entrada analogica
;los datos que entren por esta salgan por el puerto serie y vayan al pc


      list p=16f877       ; processor type
      include <p16f876.inc>

;-------
; RESET
;-------
      org 00h         ; direccion de comienzo = 0000
               ; cuando se produce un reset o comienza el programa
      goto INICIO      ; va a la primera instruccion del programa





Fijate que aquí haces la indicación que usaras el PIC16F877 y luego haces un include del 16F876, haz que coincidan Giño  O todo 16F877 o todo 16F876.


Escrito originalmente por aamoros79

Codigo:

   
; --------------------
; INICIO DE PROGRAMA
; --------------------

INICIO      clrf   PORTC      ; Limpia todos los bits de PORTC
      clrf   PORTB      ; Limpia todos los bits de PORTB
      movlw   b"11111111"
      movwf   TRISA      ; PORTA como entradas


      bsf   STATUS,5   ; (bit RP0 del registro STATUS)5=banco1
      bsf   RCSTA,7      ; Activamos la USART (bit SPEN del
               ; registro RCSTA) 7=habilito puerto serie   
      clrf   TRISB      ; puertab como salida
      movlw   b"10111111"   ; RC7/RX entrada
      movwf   TRISC      ; RC6/TX salida





Fijate que el TRISA está en el RamBank1, y tu lo quieres asignar desde el RamBank0.  Mueve esa línea debajo del bsf STATUS,5.  Además porque no usas bsf STATUS,RP0, ya que si usas el include P16F877.inc estos bits ya están definidos ahi! no necesitas recordar si es el bit 5 , el bit 6 o cualquier otro.

El TRISC<7:6> deben estar en 11 para que sean habilitados como pines de usart.  Si bien lo intuitivo es poner al TX como salida, no es este el caso en los pics.  En los pics tenes que ponerlo como 1 para que se configuren como PINES DE USART que son un caso especial de salida ya que en estado de reposo están en 1.

Escrito originalmente por aamoros79

Codigo:

      movlw   b"00100100"   ; Configuramos USART para high speed y
               ; permitimos transmisión
      movwf   TXSTA      ; y activacion de transmision (asincrono)
      
      movlw   d"25"      ; Miramos la tablas del datasheet y
               ; escribimos 25 en SPBRG
      movwf   SPBRG      ; para configurar una velocidad de
               ; transmisión de 9600 BAUDIOS a 4 MHz
      bcf   STATUS,5   ; elegimos BANCO0
      movlw   b"10000000"   
      movwf   RCSTA      ; habilito puerto serie
      bsf   STATUS,5   ; banco1
      bsf   TXSTA,5      ; 5=TXEN habilita la transmision
      bcf   STATUS,5   ; elegimos BANCO0





Si quieres recibir bytes, no te olvides de habilitar el bit CREN en el RCSTA, que es el que te permite la recepcion continua de bytes


Escrito originalmente por aamoros79

Codigo:

      call   INICIAAD    ; configura modulo A/D
      call   ENVIAR      ; envia datos por puerto serie
      
      movlw   b"10000000"   ; hago parpadear led q indica que funciona
      xorwf   PORTB,F
      goto    INICIAAD

;---------------------------------------------------------
; IniciaAD - inicializa e instala el hardware a/d.
; Selecion de AN0  como entrada analogica, RC clock.
; Permire interrupciones
;---------------------------------------------------------

INICIAAD   bsf   STATUS,5   ; Pasar a RAM BANCO1
      movlw   B"00001110"   ; RA0 analog inputs(el resto RAx I/O digitales)
      movwf   ADCON1      ; justificado a la izquierda,
               ; 8 bits mas s ignificativos en ADRESH
      
      movLW   B"01000001"   ; Selecciono RC osc (FOSC/8), AN0
      movWF   ADCON0      ; A/D habilitado

      bsf   ADCON0,2   ; 2=GO , la conversion esta en proceso

;-------------------------------------------------------
; ESPERA - necesitamos un tiempo de retraso
; para que se pueda asegurar la adquisicion de datos.
;-------------------------------------------------------

ESPERA      btfsc   ADCON0,2   ; si go=0 la siguiente instruccion es descartada
               ; (ejecuta NOP) saltando a la siguiente
               ; si go=1 ejecuta la siguiente instruccion      
      goto ESPERA
      return

;----------------------------------------------------
; ENVIAR datos por puerto serie
;----------------------------------------------------
   
ENVIAR      movwf   TXREG      ; Movemos lo que queremos transmitir    
               ; (debe estar en el registro W)
      bsf   STATUS,5   ; al registro TXREG y empezamos a transmitir
      bcf   STATUS,6   ; Elegimos BANCO2
FIN_TX      btfss   RCSTA,1      ; Compruebo si el bit TMRT del registro esta
               ; a "1" o a "0".
      goto   FIN_TX      ; Si esta a "0" es que esta lleno TMRT y no
               ; ha terminado de transmitir,
               ; para ello TRMT tiene que estar a 1, hasta
               ; entonces esperamos.
      bcf   STATUS,5   ; Elegimos BANCO0
      return         

END







Aca veo cosas que no me gustan.  1ro Fijate has vuelto a cometer el error de no cambiar de pagina o mejor dicho no volver a la pagina 0.  El ADCON1 está en el RaMBank1 pero el ADCON0 está en el RamBank0.  Te falta un bcf STATUS,RP0 posterior a la configuración del ADCON1.

Otra cuestión es que no necesitas llamar al ADCON1 cada vez que quieres leer el A/D.  Podrias perfectamente configurar el ADCON1 en las rutinas superiores donde configuras los TRIS y nunca mas volverlo a hacer.

En la parte de la espera de la conversión en ninguno momento lees lo que has convertido!!!
Esto se hace (si usas modo 8 bits) , de una forma asi movf ADRESH,w

Ten cuidado con la rutina de ENVIAR por la usart.  Esta rutina espera que el dato a enviar esté en el WREG.  Tu no le cargas nada y enviará la basura que ahí este incluida.

Saludos
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)