lunes, 21 de noviembre de 2011

HCS08 - Motorola Freescale - Convertidor AD enviado por Comunicación Serial

COMUNICACIÓN SERIAL Y CONVERTIDOR ANALÓGICO DIGITAL CON HCS08

Material:
* Micro HCS08 (MC9S08SE4CRL 0M82P).
* Open Source BDM (o con lo que programes el micro-controlador).
* Conector DB-9 (Tipo entrada [vulgarmente conocido como Hembra]).
* PC o Laptop (con el IDE para programar el micro-controlador.
* Un cable de comunicación serial (para comunicar a la Computadora con el puerto serial del micro-controlador).
* Un Circuito Integrado MAX232N o MAX233.
* Un potencio-metro de Precisión.
* Y los dispositivos que necesites para el integrado que decidas usar.

Objetivo
El objetivo de esta práctica es tomar el valor analógico de ADP1, procesarlo y mandar su resultado vía comunicación serial con la computadora.
En la entrada analógica se colocará un potenciómetro en forma de divisor de voltaje para que por medio de hacer un cambio en el voltaje el resultado del mismo se refleje en la computadora.

MAX233
Este circuito integrado permite la comunicación serial entre un microcontrolador y la computadora, esto debido a que el estándar de los voltajes lógicos que maneja la computadora es de BAJO: -12V y ALTO: 12V, en tanto que un microcontrolador maneja BAJO: 0V y ALTO: 5V.
Este circuito integrado adapta los voltajes de los pulsos de información que se intercambian durante la comunicación.


DB9
Este conector es el estándar usado para la comunicación serial.
El conector DB9 (originalmente DE-9) es un conector analógico de 9 clavijas de la familia de conectores D-Subminiature (D-Sub o Sub-D).
El conector DB9 se utiliza principalmente para conexiones en serie, ya que permite una transmisión asíncrona de datos según lo establecido en la norma RS-232 (RS-232C).


Se debe tener en cuenta que existen adaptadores DB9-DB25 (Serial-Paralelo) para convertir fácilmente un enchufe DB9 en uno DB25 y viceversa.
Clavijas
Número de clavija
Nombre
1
CD: Detector de transmisión
2
RXD: Recibir datos
3
TXD: Transmitir datos
4
DTR: Terminal de datos lista
5
GND: Señal de tierra
6
DSR: Ajuste de datos listo
7
RTS: Permiso para transmitir
8
CTS: Listo para enviar
9
RI: Indicador de llamada

Protección

Código
Podemos mandar el valor del convertidor en dos formatos, decimal y hexadecimal.

Decimal
;*******************************************************************
;* This stationery serves as the framework for a user application. *
;* For a more comprehensive program that demonstrates the more     *
;* advanced functionality of this processor, please see the        *
;* demonstration applications, located in the examples             *
;* subdirectory of the "Freescale CodeWarrior for HC08" program    *
;* directory.                                                      *
;*******************************************************************

; Include derivative-specific definitions
            INCLUDE 'derivative.inc'
;
; export symbols
;
            XDEF _Startup
            ABSENTRY _Startup

;
; variable/data section
;
            ORG    RAMStart         ; Insert your data definition here
ExampleVar: DS.B   1
conversion  equ     $85
unidades    equ     $82
decenas     equ     $81
centenas    equ     $80
tope        equ     $83
cuentaux    equ     $84
unidadesA   equ     $88
decenasA    equ     $87
centenasA   equ     $86

;
; code section
;
            ORG    ROMStart

_Startup:
            LDHX   #RAMEnd+1        ; initialize the stack pointer
            TXS
            CLI                     ; enable interrupts


            ; Insert your code here
            
;PROGRAMA que usa el convertidor analogico digital del micro
;usando la entrada por PTA1, ADP1
;obtenemos una lectura y la mandamos por puerto serial ajustando
;los valores para que se despliegue en decimal
;VREFH va a VCC
;VREFL va a GND
;creado por: Hazael Fernando Mojica García
;Matrícula: 1500724


;cabecera del programa o tambien podriamos decir, la programacion de puertos
;*********************               
cabecera:            
                
            ;Configuracion del ADC
            ;*************************************
           ;Configuracion del ADC
            LDA #$90          ;Cargamos $90=10010000
            STA ADCCFG        ;Colocamos en ADCCFG=bajo poder, clock /1,largo tiempo muestreo, resolucion 8 bits, 
            
            LDA #$00
            STA ADCSC2        
                                                                   
            LDA     #$21        ;$21=00100001, COCO y AIEN desactivados, Activada conversion continua, Canal 1 seleccionado
            STA     ADCSC1
            ;*************************************
            

            ;declaramos la comunicacion serial
            ;*************************************           
            LDA    #$0
            STA    SCIBDH
            LDA    #$1F
            STA    SCIBDL
            LDA    #$0
            STA    SCIC1
            LDA    #$0C
            STA    SCIC2
            ;*************************************
            
            ;acomodamos el codigo ascci en una secuencia de memorias
            ;*************************************
            MOV   #$30,$90        ;codigo ascci del $0 es $30 
            MOV   #$31,$91        ;codigo ascci del $1 es $31 
            MOV   #$32,$92
            MOV   #$33,$93
            MOV   #$34,$94
            MOV   #$35,$95
            MOV   #$36,$96
            MOV   #$37,$97
            MOV   #$38,$98
            MOV   #$39,$99
            MOV   #$41,$9A       ;codigo ascci del $A es $41 
            MOV   #$42,$9B
            MOV   #$43,$9C
            MOV   #$44,$9D
            MOV   #$45,$9E
            MOV   #$46,$9F  
            ;*************************************
            
            MOV   #$A,$8A       ;New Line
            MOV   #$D,$89       ;carriage return
            
;*******************************************************************
;Termina la cabecera            

;Inicia el main
;*******************************************************************
;*******************************************************************
main:
            feed_watchdog
            BSR   hacer_conversion
            LDA   conversion
            STA   tope
            BSR   separa
            BSR   ajusta
            BSR   manda_serial
            ;BSR   retardo

            BRA   main
;*******************************************************************
;*******************************************************************

;SUBRUTINA MANDA_SERIAL
;Esta subrutina se encarga de mandar por serial el contenido de las 3 memorias
;centenas, decenas y unidades en ese orden
;**********************************************************************
manda_serial:
            LDHX  #$86      ;apunto a la mem $80
            
lleno:
            feed_watchdog
            LDA   SCIS1       ;cargo el Status register
            AND   #$80   
            BEQ   lleno       ;Si ya se envio el dato anterior TDRE=0, mando otro

            LDA   ,X          ;cargo el contenido de la memoria apuntada actual
            STA   SCID        ;la coloco para enviar
            INCX              ;incremento el puntero
            CPHX  #$8A        ;si estoy apuntando a la 8B (palabra finalizada)
            BNE   lleno       ;si no, mando el siguiente caracter
            
            RTS 
;**********************************************************************
;Termina subrutina de Manda_serial



;SUBRUTINA DE CONVERSION
;******************************************
hacer_conversion:
            feed_watchdog
            LDA     ADCSC1          ;Se carga el contenido de ADCSC1 para verificar COCO
            CMP     #$A1            ;Comparamos con $A1=%10100001 si igual Z=1,(COCO activado, AIEN desactivado, Conversion continua activada, Canal 1), 
            BNE     hacer_conversion;si COCO no esta activado (Z=0), regresa (Branch) a main, con COCO debe ser: 
                        
            LDA     ADCRL               ;cargamos la conversion
            STA     conversion           ;la colocamos en nuestra variable            
            RTS
            
 ;TERMINA SUBRUTINA DE CONVERSION
;******************************************

;SUBRUTINA SEPARA (UNIDADES, DECENAS Y CENTENAS)
;SUBRUTINA QUE SEPARA EL NUMERO EN DOS MEMORIAS, UNA CON UNIDADES (unidades) Y OTRA CON DECENAS (decenas) Y OTRA CON CENTENAS (centenas)
;se tomara la memoria: tope, como el numero el cual se desea separar
;se usa una variable auxiliar llamada cuentaux que llevara la cuenta actual
;****************************
separa:           
                CLR   cuentaux
                CLR   unidades
                CLR   decenas
                CLR   centenas

checa_aux:
                LDA   cuentaux                        
                CMP   tope                          ;comparamos la cuenta actual, si ya llegamos a tope
                BEQ   sale_separa                   ;salimos de la subrutina, si no, incrementamos de nuevo
                BRA   incrementa_cuenta

incrementa_cuenta:
                feed_watchdog
                INC   unidades                      ;si las unidades completa una decena
                INC   cuentaux
                LDA   unidades                      ;regresamos a cero unidades y decenas +1
                CMP   #$A
                BEQ   una_decena_mas
                BRA   checa_aux                     ;si no hay incrementos de decenas nos vamos directo a checar el auxiliar
                                
una_decena_mas:
                MOV   #$00,unidades
                INC   decenas
                LDA   decenas                       ;si hay una decena mas, incremento en uno las centenas
                CMP   #$A                           ; y regreso a cero las decenas
                BEQ   una_centena_mas
                BRA   checa_aux
                
una_centena_mas:
                MOV   #$00,decenas
                INC   centenas
                BRA   checa_aux                
                                
sale_separa:    
                RTS                                
                
;**************************************
;TERMINA SUBRUTINA SEPARA


;SUBRUTINAS DE AJUSTE
;ajusta, es decir convierte el contenido de las memorias unidades, decenas y centenas
;a su valor hexadecimal ascii
;*********************************************

;.---------------------------Subrutinas de ajuste
ajusta:            
ajusta_unidades:
                LDHX    #$90                    ;apuntamos a la memoria $80, que es donde empiezan los valores de ajuste
                MOV     #$90,tope               ;colocamos $80 en la memoria que servira de tope
                LDA     unidades
                ADD     tope                    ;cargamos las unidades y las sumamos a tope obteniendo asi ($80+unidades) la direccion del numero para ajustar
                STA     tope                
ciclo_unidades:                             
                feed_watchdog                   ;recorremos desde la memoria $80 hasta que llegemos a la memoria tope($80+unidades)
                CPX     tope  
                BEQ     salir_unidades
                INCX
                BRA     ciclo_unidades               
salir_unidades:                                
                LDA   ,X
                STA   unidadesA                 ;el valor de la memoria tope la guardamos en unidadesA el cual sera el valor ajustado de la unidad
                
                
ajusta_decenas:
                LDHX    #$90                    ;misma explicacion que para unidades pero con decenas
                MOV     #$90,tope
                LDA     decenas
                ADD     tope
                STA     tope                
ciclo_decenas:
                feed_watchdog
                CPX     tope  
                BEQ     salir_decenas
                INCX
                BRA     ciclo_decenas               
salir_decenas:                                
                LDA   ,X
                STA   decenasA        


ajusta_centenas:
                LDHX    #$90                    ;misma explicacion que para unidades pero con decenas
                MOV     #$90,tope
                LDA     centenas
                ADD     tope
                STA     tope                
ciclo_centenas:
                feed_watchdog
                CPX     tope  
                BEQ     salir_centenas
                INCX
                BRA     ciclo_centenas               
salir_centenas:                                
                LDA   ,X
                STA   centenasA

                RTS
;*************************************************
;TERMINAN LAS SUBRUTINAS DE AJUSTE


;**************************************************************
;* spurious - Spurious Interrupt Service Routine.             *
;*             (unwanted interrupt)                           *
;**************************************************************
spurious:                           ; placed here so that security value
            NOP                     ; does not change all the time.
            RTI

;**************************************************************
;*                 Interrupt Vectors                          *
;**************************************************************
            ORG   $FFFA

            DC.W  spurious          ;
            DC.W  spurious          ; SWI
            DC.W  _Startup          ; Reset

Haxadecimal
;
;
; variable/data section
;
            ORG    RAMStart         ; Insert your data definition here
ExampleVar: DS.B   1
conversion  equ     $85
unidades    equ     $82
decenas     equ     $81
tope        equ     $83
cuentaux    equ     $84
unidadesA   equ     $88
decenasA    equ     $87

;
; code seconversion  equ     $85


;
            ORG    ROMStart

_Startup:
            LDHX   #RAMEnd+1        ; initialize the stack pointer
            TXS
            CLI                     ; enable interrupts

            ; Insert your code here

;PROGRAMA que usa el convertidor analogico digital del micro
;usando la entrada por PTA1, ADP1
;obtenemos una lectura y la mandamos por puerto serial ajustando
;los valores para que se despliegue en hexadecimal
;VREFH va a VCC
;VREFL va a GND
;creado por: Hazael Fernando Mojica García
;Matrícula: 1500724

;cabecera del programa o tambien podriamos decir, la programacion de puertos
;*********************               
cabecera:            
                
            ;Configuracion del ADC
            ;*************************************
           ;Configuracion del ADC
            LDA #$90          ;Cargamos $90=10010000
            STA ADCCFG        ;Colocamos en ADCCFG=bajo poder, clock /1,largo tiempo muestreo, resolucion 8 bits, 
            
            LDA #$00
            STA ADCSC2        
                                                                   
            LDA     #$21        ;$21=00100001, COCO y AIEN desactivados, Activada conversion continua, Canal 1 seleccionado
            STA     ADCSC1
            ;*************************************
            

            ;declaramos la comunicacion serial
            ;*************************************           
            LDA    #$0
            STA    SCIBDH
            LDA    #$1F
            STA    SCIBDL
            LDA    #$0
            STA    SCIC1
            LDA    #$0C
            STA    SCIC2
            ;*************************************
            
            ;acomodamos el codigo ascci en una secuencia de memorias
            ;*************************************
            MOV   #$30,$90        ;codigo ascci del $0 es $30 
            MOV   #$31,$91        ;codigo ascci del $1 es $31 
            MOV   #$32,$92
            MOV   #$33,$93
            MOV   #$34,$94
            MOV   #$35,$95
            MOV   #$36,$96
            MOV   #$37,$97
            MOV   #$38,$98
            MOV   #$39,$99
            MOV   #$41,$9A       ;codigo ascci del $A es $41 
            MOV   #$42,$9B
            MOV   #$43,$9C
            MOV   #$44,$9D
            MOV   #$45,$9E
            MOV   #$46,$9F  
            ;*************************************
            
            MOV   #$A,$8A       ;New Line
            MOV   #$D,$89       ;carriage return
            
;*******************************************************************
;Termina la cabecera            

;Inicia el main
;*******************************************************************
;*******************************************************************
main:
            feed_watchdog
            BSR   hacer_conversion
            LDA   conversion
            STA   tope
            BSR   separa
            BSR   ajusta
            BSR   manda_serial

            BRA   main
;*******************************************************************
;*******************************************************************

;SUBRUTINA MANDA_SERIAL
;Esta subrutina se encarga de mandar por serial el contenido de las 3 memorias
;centenas, decenas y unidades en ese orden
;**********************************************************************
manda_serial:
            LDHX  #$87      ;apunto a la mem $80
            
lleno:
            feed_watchdog
            LDA   SCIS1       ;cargo el Status register
            AND   #$80   
            BEQ   lleno       ;Si ya se envio el dato anterior TDRE=0, mando otro

            LDA   ,X          ;cargo el contenido de la memoria apuntada actual
            STA   SCID        ;la coloco para enviar
            INCX              ;incremento el puntero
            CPHX  #$8A        ;si estoy apuntando a la 8B (palabra finalizada)
            BNE   lleno       ;si no, mando el siguiente caracter
            
            RTS 
;**********************************************************************
;Termina subrutina de Manda_serial



;SUBRUTINA DE CONVERSION
;******************************************
hacer_conversion:
            feed_watchdog
            LDA     ADCSC1          ;Se carga el contenido de ADCSC1 para verificar COCO
            CMP     #$A1            ;Comparamos con $A1=%10100001 si igual Z=1,(COCO activado, AIEN desactivado, Conversion continua activada, Canal 1), 
            BNE     hacer_conversion;si COCO no esta activado (Z=0), regresa (Branch) a main, con COCO debe ser: 
                        
            LDA     ADCRL               ;cargamos la conversion
            STA     conversion           ;la colocamos en nuestra variable            
            RTS
            
 ;TERMINA SUBRUTINA DE CONVERSION
;******************************************

;SUBRUTINA SEPARA (UNIDADES, DECENAS)
;SUBRUTINA QUE SEPARA EL NUMERO EN DOS MEMORIAS, UNA CON UNIDADES (unidades) Y OTRA CON DECENAS (decenas)
;se tomara la memoria: tope, como el numero el cual se desea separar
;se usa una variable auxiliar llamada cuentaux que llevara la cuenta actual
;NOTA: se usa el termino UNIDADES para referirnos al primer digito del numero hexadecimal
;y el termino DECENAS para referirnos al segundo digito, ya que separa el numero por notacion desarrollada base 16
;no es que estemos trabajanod en decimal, solo es una forma de expresarlo
;****************************
separa:           
                CLR   cuentaux
                CLR   unidades
                CLR   decenas

checa_aux:
                LDA   cuentaux                        
                CMP   tope                          ;comparamos la cuenta actual, si ya llegamos a tope
                BEQ   sale_separa                   ;salimos de la subrutina, si no, incrementamos de nuevo
                BRA   incrementa_cuenta

incrementa_cuenta:
                feed_watchdog
                INC   unidades                      ;si las unidades completa una decena
                INC   cuentaux
                LDA   unidades                      ;regresamos a cero unidades y decenas +1
                CMP   #$10
                BEQ   una_decena_mas
                BRA   checa_aux                     ;si no hay incrementos de decenas nos vamos directo a checar el auxiliar
                                
una_decena_mas:
                MOV   #$00,unidades
                INC   decenas
                BRA   checa_aux
                                
                                
sale_separa:    
                RTS                                
                
;**************************************
;TERMINA SUBRUTINA SEPARA


;SUBRUTINAS DE AJUSTE
;ajusta, es decir convierte el contenido de las memorias unidades, decenas y centenas
;a su valor hexadecimal ascii
;*********************************************

;.---------------------------Subrutinas de ajuste
ajusta:            
ajusta_unidades:
                LDHX    #$90                    ;apuntamos a la memoria $80, que es donde empiezan los valores de ajuste
                MOV     #$90,tope               ;colocamos $80 en la memoria que servira de tope
                LDA     unidades
                ADD     tope                    ;cargamos las unidades y las sumamos a tope obteniendo asi ($80+unidades) la direccion del numero para ajustar
                STA     tope                
ciclo_unidades:                             
                feed_watchdog                   ;recorremos desde la memoria $80 hasta que llegemos a la memoria tope($80+unidades)
                CPX     tope  
                BEQ     salir_unidades
                INCX
                BRA     ciclo_unidades               
salir_unidades:                                
                LDA   ,X
                STA   unidadesA                 ;el valor de la memoria tope la guardamos en unidadesA el cual sera el valor ajustado de la unidad
                
                
ajusta_decenas:
                LDHX    #$90                    ;misma explicacion que para unidades pero con decenas
                MOV     #$90,tope
                LDA     decenas
                ADD     tope
                STA     tope                
ciclo_decenas:
                feed_watchdog
                CPX     tope  
                BEQ     salir_decenas
                INCX
                BRA     ciclo_decenas               
salir_decenas:                                
                LDA   ,X
                STA   decenasA                       

                RTS
;*************************************************
;TERMINAN LAS SUBRUTINAS DE AJUSTE

En la siguiente imagen se muestran las conexiones de los dispositivos usados:

En la siguiente imagen se observan los dos archivos que contienen ambos códigos en el programa (CodeWarrior IDE):


En la siguiente imagen se observa el debug del programa en decimal, el cual corre sin ningun mensaje de error o advertencia:


En la imagen de abajo el debug del código en Hexadecimal, sin errores o advertencias y corriendo:



Por cosas del destino parece ser que hay veces que no funciona la conexión serial
y puede deberse a la conexión del MAX233, recomiendo mejor usar el siguiente circuito:



Debido a la hoja de datos del MAX233


Powered by iGus

No hay comentarios:

Publicar un comentario