Diferencia entre revisiones de «SCI (Interfaz de Comunicación Serial) - MC9S08QE128»
(→Caracteristicas Generales del SCI) |
|||
(No se muestran 219 ediciones intermedias de 15 usuarios) | |||
Línea 1: | Línea 1: | ||
− | + | [[Categoría: EC2721 - Arquitectura del Computador 1]] | |
+ | [[Categoría: EC3731 - Arquitectura del Computador 2]] | ||
+ | [[Categoría:MC9S08QE128]] | ||
− | + | El módulo del SCI del [[MC9S08QE128]], es una gran herramienta para la recepción / transmisión serial. | |
− | En | + | El Microcontrolador MC9S08QE128, tiene dos puertos seriales, el SCI1 y el SCI2. En el desarrollo del tema se explicará solo el SCI1 ya que es el más usado, si requiere información sobre el SCI2 dirigirse al manual del MC9S08QE128. |
− | + | En esta sección veremos los modos de uso y cómo se deben configurar los registros para la recepción y envío en general. | |
− | + | ||
− | + | ||
− | + | [[Archivo:SCI.jpg|400px|thumb|derecha| Módulos del SCI en el MC9S08QE128.]] | |
− | + | == Características Generales del SCI == | |
− | + | * Formato ''Full-duplex'', estándar sin retorno a cero (NRZ). | |
− | + | * Doble ''buffer'' de transmisión y recepción con habilitadores separados. | |
− | + | * Tasas de baudios programables (13-bits). | |
+ | |||
+ | * Opera por Interrupciones o por encuesta las siguientes actividades: | ||
''- Transmisión registro de datos y registros completos.'' | ''- Transmisión registro de datos y registros completos.'' | ||
Línea 30: | Línea 32: | ||
''- Detección de banderas.'' | ''- Detección de banderas.'' | ||
− | + | * ''Hardware'' de generación y comprobación de paridad. | |
− | + | * Programable a 8-bits o 9-bits de caracteres de longitud. | |
− | + | * Receptor de activación por línea libre o marca de dirección. | |
− | + | * Opcionales: Generación de salto de carácter de 13-bit / Detección de saltos de carácter de 11-bit. | |
− | + | * Transmisor de polaridad de salida seleccionable. | |
+ | |||
+ | Estas características fueron extraídas del Capítulo 14 del [http://www.freescale.com/files/microcontrollers/doc/ref_manual/MC9S08QE128RM.pdf Manual del MC9S08QE128] | ||
== Inicializaciones Generales del SCI == | == Inicializaciones Generales del SCI == | ||
+ | A continuación se presentan algunos ejemplos de cómo configurar el SCI para que transmita y reciba por encuesta e interrupciones | ||
==== '' En Assembler'' ==== | ==== '' En Assembler'' ==== | ||
− | ==== '' En Lenguaje C '' ==== | + | Configuración más utilizada para transmitir y recibir por encuesta. |
− | + | ||
+ | <syntaxhighlight lang="asm"> | ||
+ | |||
+ | LDA #$00 | ||
+ | STA SCI1BDH | ||
+ | LDA #$1A ;/* Pre-escaler ajustado: [SBR12:SBR0] = 4Mhz/(16*9600) =~ 26,04d= 1A (hex)*/ | ||
+ | STA SCI1BDL ;/*Baud Rate = 9600bps para un clock de 4MHZ*/ | ||
+ | LDA #$00 | ||
+ | STA SCI1C1 ;/*Transmisión y recepción normal de 8 bits sin paridad*/ | ||
+ | LDA #$0C | ||
+ | STA SCI1C2 ;/*Habilita transmisor y receptor*/ | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | Configuración más utilizada para transmitir y recibir por interrupción del SCI | ||
+ | |||
+ | <syntaxhighlight lang="asm"> | ||
+ | |||
+ | LDA #$00 | ||
+ | STA SCI1BDH ;/* Tasa alta de transmisión deshabilitada (Baud high disabled)*/ | ||
+ | LDA #$1A ;/* Pre-escaler ajustado: [SBR12:SBR0] = 4Mhz/(16*9600) =~ 26,04d= 1A (hex)*/ | ||
+ | /* Valor requerido para trabajar a 9600bps*/ | ||
+ | STA SCI1BDL ;/*Baud Rate = 9600bps*/ | ||
+ | LDA #$00 | ||
+ | STA SCI1C1 ;/*Transmisión y recepción normal de 8 bits sin paridad*/ | ||
+ | LDA #$2C | ||
+ | STA SCI1C2 ;/*Habilita transmisor y receptor y habilita interrupciones*/ | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | El bus clock de SCI1 y SCI2 está activado luego de cualquier reset, pero puede que sea necesario activar sólo el bus clock del SCI que se está utilizando, lo que se realiza modificando el registro de control de System Clock Gating 1 (SCGC1). | ||
+ | |||
+ | ==== '' En Lenguaje "C" '' ==== | ||
+ | Configuración más utilizada para transmitir y recibir por encuesta | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="c"> | ||
+ | // Inicializaciones para trabajar con SCI | ||
+ | SCI1BDH = 0x00; | ||
+ | SCI1BDL = 0x1A; /*Baud Rate = 9600bps*/ | ||
+ | SCI1C1 = 0x00; /*Transmisión y recepción normal de 8 bits sin paridad*/ | ||
+ | SCI1C2 = 0x0C; /*Habilita transmisor y receptor*/ | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | Configuración más utilizada para transmitir y recibir por interrupción del SCI | ||
+ | |||
+ | <syntaxhighlight lang="c"> | ||
+ | // Inicializaciones para trabajar con SCI | ||
+ | SCI1BDH = 0x00; | ||
+ | SCI1BDL = 0x1A; /*Baud Rate = 9600bps*/ | ||
+ | SCI1C1 = 0x00; /*Transmisión y recepción normal de 8 bits sin paridad*/ | ||
+ | SCI1C2 = 0xAC; /*Habilita transmisor y receptor, habilito recepción y transmisión por interrupciones*/ | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
+ | [https://www.dropbox.com/sh/inkevplco660d9r/7tEkHpF3Vy '''Guía Rápida de los Módulos de Inicialización'''] | ||
+ | |||
+ | === Configuraciones de SCI para trabajar a diferentes velocidades === | ||
+ | El puerto serial puede trabajar a la siguientes velocidades: | ||
+ | |||
+ | [[Archivo:Baudios.jpg|400px|thumb|right|Como determinar a cuantos Baudios va a trabajar el MC9S08QE128. ]] | ||
+ | {| class="wikitable" | ||
+ | |||
+ | ! Velocidad | ||
+ | |||
+ | |- | ||
+ | |||
+ | | 9600 baudios | ||
+ | |||
+ | |- | ||
+ | |||
+ | | 19200 baudios | ||
+ | |||
+ | |- | ||
+ | |||
+ | | 38400 baudios | ||
+ | |||
+ | |- | ||
+ | |||
+ | | 57600 baudios | ||
+ | |||
+ | |- | ||
+ | |||
+ | | 115200 baudios | ||
+ | |||
+ | |} | ||
+ | |||
+ | Para configurar la tasa de baudios (''baud rate'') para la sincronización del módulo SCI se han de configurar los registros [SBR12:SBR0] con el valor del ''prescaler'' deseado, para esto, tomar en cuenta la fórmula | ||
+ | <pre> | ||
+ | [SBR12:SBR0] =(hex) [VelocidadDeReloj/(16*BaudrateDeseado)] | ||
+ | </pre> | ||
+ | |||
+ | ==== '' Assembler '' ==== | ||
+ | Se ha de pasar el valor del ''prescaler'' a los registros '''SCI1BDH''' (parte alta) '''SCI1BDL''' (Parte baja). Se debe escribir primero la parte alta y luego la parte baja. | ||
+ | |||
+ | Ejemplo: | ||
+ | |||
+ | <syntaxhighlight lang="asm"> | ||
+ | LDA #$00 | ||
+ | STA SCI1BDH | ||
+ | LDA #$1A | ||
+ | STA SCI1BDL ;/*Baud Rate = 9600bps para un clock de 4MHZ*/ | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==== '' En Lenguaje "C" '' ==== | ||
+ | Se asigna el valor del prescaler al registro '''SCI1BD''' | ||
+ | Ejemplo: | ||
+ | |||
+ | <syntaxhighlight lang="c"> | ||
+ | SCI1BD=0x1A; | ||
+ | </syntaxhighlight> | ||
== Registros SCI == | == Registros SCI == | ||
− | |||
− | ===''SCIxBDH''=== | + | Los Registros del SCI son de 8-bits. Cada registro tiene características para la configuración del puerto serial dependiendo de cómo se desea trabajar con él. |
+ | |||
+ | ===''SCIxBDH'' y ''SCIxBDL''=== | ||
+ | {| border="0" style="padding: 0.1em; border-collapse: collapse;background:#FFFFFF" cellpadding="3" | ||
+ | |- valign="bottom" style="background:#FFFFFF" | ||
+ | | 7 6 5 4 ¦ 3 2 1 0 | ||
+ | |} | ||
+ | |||
+ | {| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="8" | ||
+ | |- valign="bottom" style="background:#F2F2F2" | ||
+ | !LBKDIE | ||
+ | !RXEDGIE | ||
+ | !////// | ||
+ | !SBR12 | ||
+ | !SBR11 | ||
+ | !SBR10 | ||
+ | ! SBR9 | ||
+ | ! SBR8 | ||
+ | |} | ||
+ | |||
+ | |||
+ | {| border="0" style="padding: 0.1em; border-collapse: collapse;background:#FFFFFF" cellpadding="3" | ||
+ | |- valign="bottom" style="background:#FFFFFF" | ||
+ | | 7 6 5 4 ¦ 3 2 1 0 | ||
+ | |} | ||
+ | |||
+ | {| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="8" | ||
+ | |- valign="bottom" style="background:#F2F2F2" | ||
+ | ! SBR7 | ||
+ | ! SBR6 | ||
+ | ! SBR5 | ||
+ | ! SBR4 | ||
+ | ! SBR3 | ||
+ | ! SBR2 | ||
+ | ! SBR1 | ||
+ | ! SBR0 | ||
+ | |} | ||
− | + | Este par de registros son usados en la inicialización del puerto serial. Ellos controlan la escala de baudios a la cual se transmite y se recibe la información. Generalmente se configuran para 9600 Baudios | |
===''SCIxC1''=== | ===''SCIxC1''=== | ||
+ | {| border="0" style="padding: 0.1em; border-collapse: collapse;background:#FFFFFF" cellpadding="3" | ||
+ | |- valign="bottom" style="background:#FFFFFF" | ||
+ | | 7 6 5 4 ¦ 3 2 1 0 | ||
+ | |} | ||
+ | |||
+ | {| border="4" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="8" | ||
+ | |- valign="bottom" style="background:#F2F2F2" | ||
+ | !LOOPS | ||
+ | !SCISWAI | ||
+ | !RSRC | ||
+ | ! M | ||
+ | !WAKE | ||
+ | ! ILT | ||
+ | ! PE | ||
+ | ! PT | ||
+ | |} | ||
+ | Este registro es usado en la inicialización del puerto serial. Se utiliza para controlar varias características opcionales del sistema SCI. Generalmente se programa para la transmisión y recepción normal de 8 bits sin paridad | ||
===''SCIxC2''=== | ===''SCIxC2''=== | ||
+ | {| border="0" style="padding: 0.1em; border-collapse: collapse;background:#FFFFFF" cellpadding="3" | ||
+ | |- valign="bottom" style="background:#FFFFFF" | ||
+ | | 7 6 5 4 ¦ 3 2 1 0 | ||
+ | |} | ||
+ | |||
+ | {| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="8" | ||
+ | |- valign="bottom" style="background:#F2F2F2" | ||
+ | ! TI E | ||
+ | !TCIE | ||
+ | ! RIE | ||
+ | !ILIE | ||
+ | ! TE | ||
+ | ! RE | ||
+ | ! RWU | ||
+ | ! SBK | ||
+ | |} | ||
+ | Este registro es usado en las inicializaciones para activar las interrupciones de transmisión y recepción. Cuando el bit 7 está en 1, se activa la transmisión y cuando el bit 5 está en 1, se activa la recepción. | ||
===''SCIxS1''=== | ===''SCIxS1''=== | ||
+ | {| border="0" style="padding: 0.1em; border-collapse: collapse;background:#FFFFFF" cellpadding="3" | ||
+ | |- valign="bottom" style="background:#FFFFFF" | ||
+ | | 7 6 5 4 ¦ 3 2 1 0 | ||
+ | |} | ||
+ | {| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="8" | ||
+ | |- valign="bottom" style="background:#F2F2F2" | ||
+ | !TDRE | ||
+ | ! TC | ||
+ | !RDRF | ||
+ | !IDKE | ||
+ | ! OR | ||
+ | ! NF | ||
+ | ! FE | ||
+ | ! PF | ||
+ | |} | ||
+ | Este registro contiene 8 banderas de estatus. El bit 7 contiene la bandera de estatus de transmisión, cuando se transmite dicha bandera se pone en 1. Cuando se recibe la bandera del bit 5 RDRF se pone en 1. Para limpiar las banderas hay que leer el registro SCI1S1 (Ej, Variable=SCI1S1 en C y LDA SCI1S1 en assembler) | ||
− | ===''SCIxS2''=== | + | ===''SCIxS2''=== |
+ | {| border="0" style="padding: 0.1em; border-collapse: collapse;background:#FFFFFF" cellpadding="3" | ||
+ | |- valign="bottom" style="background:#FFFFFF" | ||
+ | | 7 6 5 4 ¦ 3 2 1 0 | ||
+ | |} | ||
+ | {| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="8" | ||
+ | |- valign="bottom" style="background:#F2F2F2" | ||
+ | !LBKDIF | ||
+ | !RXEDGIF | ||
+ | !/////// | ||
+ | !RXINV | ||
+ | !RWUID | ||
+ | !BRK13 | ||
+ | !LBKDE | ||
+ | ! RAF | ||
+ | |} | ||
− | + | Configura las opciones de soporte LIN y supervisa la actividad del receptor. | |
+ | ===''SCIxC3''=== | ||
+ | |||
+ | {| border="0" style="padding: 0.1em; border-collapse: collapse;background:#FFFFFF" cellpadding="2" | ||
+ | |- valign="bottom" style="background:#FFFFFF" | ||
+ | | 7 6 5 4 ¦ 3 2 1 0 | ||
+ | |} | ||
+ | |||
+ | {| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="10" | ||
+ | |- valign="bottom" style="background:#F2F2F2" | ||
+ | ! R8 | ||
+ | ! T8 | ||
+ | ! TXDIR. | ||
+ | ! TXINV. | ||
+ | ! ORIE. | ||
+ | ! NEIE. | ||
+ | ! FEIE. | ||
+ | ! PEIE. | ||
+ | |- | ||
+ | |} | ||
+ | Es otro registro de control del SCI, que es poco usado, para más información dirigirse al [http://www.freescale.com/files/microcontrollers/doc/ref_manual/MC9S08QE128RM.pdf manual] del [[MC9S08QE128]] | ||
===''SCIxD''=== | ===''SCIxD''=== | ||
+ | El registro SCIxD se utiliza para recibir o transmitir un dato por el puerto serial. Para más detalles ver la sección de [[SCI (Interfaz de Comunicación Serial) - MC9S08QE128#Inicializaciones Generales del SCI|Inicializaciones Generales del SCI. | ||
− | == | + | {| border="0" style="padding: 0.1em; border-collapse: collapse;background:#FFFFFF" cellpadding="3" |
− | + | |- valign="bottom" style="background:#FFFFFF" | |
+ | | 7 6 5 4 ¦ 3 2 1 0 | ||
+ | |} | ||
+ | {| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="8" | ||
+ | |- valign="bottom" style="background:#F2F2F2" | ||
+ | ! R7/T7 | ||
+ | ! R6/T6 | ||
+ | ! R5/T5 | ||
+ | ! R4/T4 | ||
+ | ! R3/T3 | ||
+ | ! R2/T2 | ||
+ | ! R1/T1 | ||
+ | ! R0/T0 | ||
+ | |- | ||
+ | |} | ||
+ | Escribe: Recepción (Rx) de dato; Escribe: Transmisión (Rx) de dato. | ||
− | === | + | |
+ | |||
+ | == Serial por Encuesta == | ||
+ | |||
+ | === Transmisión === | ||
+ | |||
+ | Este programa se queda esperando hasta que transmita un dato, para luego salir del ciclo, enviar por el puerto el dato y finalmente limpiar la bandera, para volver a transmitir. | ||
==== '' En Assembler'' ==== | ==== '' En Assembler'' ==== | ||
− | ==== '' En Lenguaje C '' ==== | + | Esta es una sub-rutina para la cual se llama con la instrucción '''jsr Transmitir''' |
− | === | + | |
+ | <syntaxhighlight lang="asm"> | ||
+ | Transmitir: | ||
+ | lda dato ; Se coloca en el dato que se desea transmitir en el Acumulador. | ||
+ | sta SCI1D ; Se coloca el dato en el registro de data del puerto para ser enviado. | ||
+ | BRCLR SCI1S1_TDRE,SCI1S1,* ; Condición de salto que verifica si la | ||
+ | ;el dato fue transmitido. | ||
+ | lda SCI1S1 ; Se aclara la bandera MUY IMPORTANTE. | ||
+ | RTS ; Se sale de la sub rutina y vuelve al PC+1 de donde fue llamada. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==== '' En Lenguaje "C" '' ==== | ||
+ | Se crea como una función, la cual se llama con Transmitir_dato(dato) | ||
+ | |||
+ | <syntaxhighlight lang="c"> | ||
+ | |||
+ | void Transmitir_dato(byte dato) // Se ejecuta la transmisión de dato por encuesta | ||
+ | { byte bandera; | ||
+ | while (SCI1S1_TDRE == 0); // No finaliza ciclo hasta que esté libre el registro | ||
+ | // en el que se guardará el dato que se enviará. | ||
+ | bandera= SCI1S1; // Aclara la bandera. | ||
+ | SCI1D = dato; // Enviando dato. | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | === Recepción === | ||
+ | Este programa se queda esperando hasta que reciba un dato, para luego salir del ciclo, enviar el dato por el puerto y finalmente limpiar las banderas, para volver a recibir. | ||
==== '' En Assembler'' ==== | ==== '' En Assembler'' ==== | ||
+ | Esta es una sub-rutina para la cual se llama con la instrucción '''jsr RecepcionSerial''' | ||
− | = | + | <syntaxhighlight lang="asm"> |
+ | RecepcionSerial: | ||
+ | BRCLR SCI1S1_RDRF,SCI1S1,* ;Revisamos si se levanta la bandera de recepcion | ||
+ | LDA SCI1S1 ;Primer paso para limpiar la bandera | ||
+ | LDA SCI1D ;Segundo paso para limpiar la bandera. Se lee el dato recibido | ||
+ | STA DatoSerial ;Se coloca el valor del acumulador en la variable DatoSerial. | ||
+ | RTS | ||
+ | </syntaxhighlight> | ||
+ | Para un ejemplo más completo puede ver el artículo: [[Ejemplo SCI Recepción por encuesta]] | ||
+ | ==== '' En Lenguaje "C" '' ==== | ||
− | == Serial por | + | Se crea como una función, la cual se llama con Recibir_dato() |
− | + | ||
+ | <syntaxhighlight lang="c"> | ||
+ | byte Recibir_dato(void) // Se ejecuta la recepción de dato por encuesta. | ||
+ | { byte dato_R; | ||
+ | byte bandera; | ||
+ | while (SCI1S1_RDRF == 0); // No finaliza ciclo hasta que esté listo el dato. | ||
+ | bandera= SCI1S1; // Aclara la Bandera. | ||
+ | dato_R = SCI1D; // Se Salva el Dato. | ||
+ | return dato_R; // Retorna Dato. | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''Hay que aclarar las banderas cada vez que se termine de transmitir o recibir dependiendo de cual sea el caso, es sumamente importante. Si no se hace puede que el programa genere algún tipo de error. Para bajar la bandera solamente tienen que leer el registro SCI1S1.''' | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | == Serial por [[Interrupciones]] == | ||
+ | Antes de usar transmisión y recepción por interrupción se debe de usar la inicialización adecuada. | ||
− | === | + | === Transmisión === |
==== '' En Assembler'' ==== | ==== '' En Assembler'' ==== | ||
+ | En assembler hay que definir el vector de interrupción de la siguiente manera | ||
− | ==== '' En Lenguaje C '' ==== | + | |
− | === | + | |
+ | <syntaxhighlight lang="asm"> | ||
+ | ;************************************************************** | ||
+ | ;* Interrupt Vectors * | ||
+ | ;************************************************************** | ||
+ | ORG $FFDE ; Posición en memoria donde se encuentra el vector de interrupción | ||
+ | |||
+ | DC.W Transmite ; Rutina de Transmisión | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Si se escribe un valor en el registro SCI1D, este dato se empieza a transmitir, al finalizar la transmisión se produce la interrupción y en nuestro caso se atiende dicha interrupción en la etiqueta '''Transmite'''. | ||
+ | |||
+ | |||
+ | Un ejemplo para transmitir una serie de datos por serial es el siguiente: | ||
+ | |||
+ | <syntaxhighlight lang="asm"> | ||
+ | Transmite: lda dato ; Se carga a el acumulador el dato deseado | ||
+ | sta SCI1D ; Se transmite el dato por el puerto serial | ||
+ | lda SCI1S1 ; Se baja la bandera de transmisión para poder volverla usar | ||
+ | mov #$2C, SCI1C2 ; Se modifica el registro SCI1C2 para que interrumpa el programa cuando se reciba un dato si se recibir | ||
+ | ; Otro dato por interrupción de lo contrario borrar esta línea de código | ||
+ | RTI | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | Cabe destacar que la transmisión por serial está diseñada para enviar cadenas de datos, si se desea enviar uno solo, se debe deshabilitar la interrupción de transmisión utilizando una instrucción como Bclr SCI1C2_TIE, SCI1C2 en la rutina de transmisión y luego habilitarla de nuevo utilizando BSET SCI1C2_TIE, SCI1C2. De esta forma, es posible enviar dato por dato. | ||
+ | |||
+ | Para un ejemplo más completo puede ver el artículo: [[Ejemplo SCI Transmisión por Interrupciones]] | ||
+ | |||
+ | ==== '' En Lenguaje "C" '' ==== | ||
+ | Para transmitir por interrupción se tiene que usar el siguiente vector "void interrupt VectorNumber_Vsci1tx SCI_TX_ISR(void)". Este vector de interrupción se debe colocar después del "main". Un ejemplo de cómo usar el vector es el siguiente. | ||
+ | |||
+ | <syntaxhighlight lang="c"> | ||
+ | void interrupt VectorNumber_Vsci1tx SCI_TX_ISR(void){ | ||
+ | byte leer; | ||
+ | leer=SCI1S1; /*Baja la bandera de transmisión, por tal motivo para | ||
+ | volverlo a utilizar hay que ponerlo nuevamente en cero*/ | ||
+ | SCI1D=dato; // En el registro SCI1D se guarda lo que se quiere enviar por serial, | ||
+ | // la variable dato se tiene | ||
+ | // que inicializar como una variable global. | ||
+ | |||
+ | SCI1C2=0x2C; // Esta línea de código es opcional, se escribe si se quiere que el programa | ||
+ | // reciba por interrupción | ||
+ | //en caso contrario borrarla. | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''Bajar las banderas cada vez que transmitan es sumamente importante.''' | ||
+ | '''Si no lo hacen el programa no les volverá a transmitir. Para bajar la bandera solamente tienen que leer el registro SCI1S1''' | ||
+ | |||
+ | === Recepción === | ||
==== '' En Assembler'' ==== | ==== '' En Assembler'' ==== | ||
+ | En assembler hay que definir el vector de interrupción de recepción de la siguiente manera: | ||
− | = | + | <syntaxhighlight lang="asm"> |
+ | ;************************************************************** | ||
+ | ;* Interrupt Vectors * | ||
+ | ;************************************************************** | ||
+ | ORG $FFE0 ;Espacio en memoria donde se encuentra la interrupción. | ||
+ | DC.W RecepcionSerial ;Rutina de Recepción. | ||
+ | </syntaxhighlight> | ||
− | + | Un ejemplo para recibir por serial es el siguiente | |
− | + | <syntaxhighlight lang="asm"> | |
+ | RecepcionSerial: | ||
+ | LDA SCI1S1 ;Primer paso para limpiar la bandera | ||
+ | LDA SCI1D ;Segundo paso para limpiar la bandera. Se lee el dato recibido | ||
+ | STA DatoSerial ;Se coloca el valor del acumulador en la variable DatoSerial. | ||
+ | RTI ;Se sale de la rutina y vuelve al PC+1 de donde fue Llamada. | ||
+ | </syntaxhighlight> | ||
+ | Para un ejemplo más completo puede ver el artículo: [[Ejemplo SCI Recepción por Interrupciones]] | ||
− | + | ==== '' En Lenguaje "C" '' ==== | |
− | + | Para recibir por interrupción se tiene que usar el siguiente vector "void interrupt VectorNumber_Vsci1rx SCI_RX_ISR(void)". Este vector de interrupción se debe de colocar después del "main". Un ejemplo de cómo usar el vector es el siguiente. | |
− | + | ||
+ | <syntaxhighlight lang="c"> | ||
+ | //vector de interrupción por sci para recibir | ||
+ | void interrupt VectorNumber_Vsci1rx SCI_RX_ISR(void) { | ||
+ | byte leer; | ||
+ | byte dato; //Se declaran las variables que recibe el dato que se escribe. | ||
+ | leer = SCI1S1; //Baja la bandera de recepción, por tal motivo para volverlo a utilizar hay que ponerlo nuevamente en cero. | ||
+ | dato = SCI1D; //El registro SCI1D es donde se guarda el dato que se manda por puerto serial, dicho dato se le asigna a la variable dato. | ||
+ | SCI1C2=0x8C; //Esta línea de código es opcional, se escribe si se quiere que el programa transmita por interrupción. | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''Bajar las banderas cada vez que reciban es sumamente importante.''' | ||
+ | '''Si no lo hacen el programa no les volverá a recibir. Para bajar la bandera solamente tienen que leer el registro SCI1S1''' | ||
+ | |||
+ | == Referencias == | ||
+ | |||
+ | *[http://www.freescale.com/files/microcontrollers/doc/ref_manual/MC9S08QE128RM.pdf '''Reference Manual.''' ''Freescale''] | ||
− | + | *[http://www.freescale.com/files/microcontrollers/doc/user_guide/DEMOQE128UM.pdf ''DEMOQE128 User Manual'' DEMOQE rev A] |
Revisión actual del 13:27 17 abr 2013
El módulo del SCI del MC9S08QE128, es una gran herramienta para la recepción / transmisión serial.
El Microcontrolador MC9S08QE128, tiene dos puertos seriales, el SCI1 y el SCI2. En el desarrollo del tema se explicará solo el SCI1 ya que es el más usado, si requiere información sobre el SCI2 dirigirse al manual del MC9S08QE128.
En esta sección veremos los modos de uso y cómo se deben configurar los registros para la recepción y envío en general.
Contenido
Características Generales del SCI
- Formato Full-duplex, estándar sin retorno a cero (NRZ).
- Doble buffer de transmisión y recepción con habilitadores separados.
- Tasas de baudios programables (13-bits).
- Opera por Interrupciones o por encuesta las siguientes actividades:
- Transmisión registro de datos y registros completos.
- Recepción de registros de datos completos.
- Recepción de desbordamiento(carry) , error de paridad, error de framing y error de ruido.
- Recepción de inactividad.
- Pin receptor de flanco activo.
- Detección de banderas.
- Hardware de generación y comprobación de paridad.
- Programable a 8-bits o 9-bits de caracteres de longitud.
- Receptor de activación por línea libre o marca de dirección.
- Opcionales: Generación de salto de carácter de 13-bit / Detección de saltos de carácter de 11-bit.
- Transmisor de polaridad de salida seleccionable.
Estas características fueron extraídas del Capítulo 14 del Manual del MC9S08QE128
Inicializaciones Generales del SCI
A continuación se presentan algunos ejemplos de cómo configurar el SCI para que transmita y reciba por encuesta e interrupciones
En Assembler
Configuración más utilizada para transmitir y recibir por encuesta.
LDA #$00
STA SCI1BDH
LDA #$1A ;/* Pre-escaler ajustado: [SBR12:SBR0] = 4Mhz/(16*9600) =~ 26,04d= 1A (hex)*/
STA SCI1BDL ;/*Baud Rate = 9600bps para un clock de 4MHZ*/
LDA #$00
STA SCI1C1 ;/*Transmisión y recepción normal de 8 bits sin paridad*/
LDA #$0C
STA SCI1C2 ;/*Habilita transmisor y receptor*/
Configuración más utilizada para transmitir y recibir por interrupción del SCI
LDA #$00
STA SCI1BDH ;/* Tasa alta de transmisión deshabilitada (Baud high disabled)*/
LDA #$1A ;/* Pre-escaler ajustado: [SBR12:SBR0] = 4Mhz/(16*9600) =~ 26,04d= 1A (hex)*/
/* Valor requerido para trabajar a 9600bps*/
STA SCI1BDL ;/*Baud Rate = 9600bps*/
LDA #$00
STA SCI1C1 ;/*Transmisión y recepción normal de 8 bits sin paridad*/
LDA #$2C
STA SCI1C2 ;/*Habilita transmisor y receptor y habilita interrupciones*/
El bus clock de SCI1 y SCI2 está activado luego de cualquier reset, pero puede que sea necesario activar sólo el bus clock del SCI que se está utilizando, lo que se realiza modificando el registro de control de System Clock Gating 1 (SCGC1).
En Lenguaje "C"
Configuración más utilizada para transmitir y recibir por encuesta
// Inicializaciones para trabajar con SCI
SCI1BDH = 0x00;
SCI1BDL = 0x1A; /*Baud Rate = 9600bps*/
SCI1C1 = 0x00; /*Transmisión y recepción normal de 8 bits sin paridad*/
SCI1C2 = 0x0C; /*Habilita transmisor y receptor*/
Configuración más utilizada para transmitir y recibir por interrupción del SCI
// Inicializaciones para trabajar con SCI
SCI1BDH = 0x00;
SCI1BDL = 0x1A; /*Baud Rate = 9600bps*/
SCI1C1 = 0x00; /*Transmisión y recepción normal de 8 bits sin paridad*/
SCI1C2 = 0xAC; /*Habilita transmisor y receptor, habilito recepción y transmisión por interrupciones*/
Guía Rápida de los Módulos de Inicialización
Configuraciones de SCI para trabajar a diferentes velocidades
El puerto serial puede trabajar a la siguientes velocidades:
Velocidad |
---|
9600 baudios |
19200 baudios |
38400 baudios |
57600 baudios |
115200 baudios |
Para configurar la tasa de baudios (baud rate) para la sincronización del módulo SCI se han de configurar los registros [SBR12:SBR0] con el valor del prescaler deseado, para esto, tomar en cuenta la fórmula
[SBR12:SBR0] =(hex) [VelocidadDeReloj/(16*BaudrateDeseado)]
Assembler
Se ha de pasar el valor del prescaler a los registros SCI1BDH (parte alta) SCI1BDL (Parte baja). Se debe escribir primero la parte alta y luego la parte baja.
Ejemplo:
LDA #$00
STA SCI1BDH
LDA #$1A
STA SCI1BDL ;/*Baud Rate = 9600bps para un clock de 4MHZ*/
En Lenguaje "C"
Se asigna el valor del prescaler al registro SCI1BD Ejemplo:
SCI1BD=0x1A;
Registros SCI
Los Registros del SCI son de 8-bits. Cada registro tiene características para la configuración del puerto serial dependiendo de cómo se desea trabajar con él.
SCIxBDH y SCIxBDL
7 6 5 4 ¦ 3 2 1 0 |
LBKDIE | RXEDGIE | ////// | SBR12 | SBR11 | SBR10 | SBR9 | SBR8 |
---|
7 6 5 4 ¦ 3 2 1 0 |
SBR7 | SBR6 | SBR5 | SBR4 | SBR3 | SBR2 | SBR1 | SBR0 |
---|
Este par de registros son usados en la inicialización del puerto serial. Ellos controlan la escala de baudios a la cual se transmite y se recibe la información. Generalmente se configuran para 9600 Baudios
SCIxC1
7 6 5 4 ¦ 3 2 1 0 |
LOOPS | SCISWAI | RSRC | M | WAKE | ILT | PE | PT |
---|
Este registro es usado en la inicialización del puerto serial. Se utiliza para controlar varias características opcionales del sistema SCI. Generalmente se programa para la transmisión y recepción normal de 8 bits sin paridad
SCIxC2
7 6 5 4 ¦ 3 2 1 0 |
TI E | TCIE | RIE | ILIE | TE | RE | RWU | SBK |
---|
Este registro es usado en las inicializaciones para activar las interrupciones de transmisión y recepción. Cuando el bit 7 está en 1, se activa la transmisión y cuando el bit 5 está en 1, se activa la recepción.
SCIxS1
7 6 5 4 ¦ 3 2 1 0 |
TDRE | TC | RDRF | IDKE | OR | NF | FE | PF |
---|
Este registro contiene 8 banderas de estatus. El bit 7 contiene la bandera de estatus de transmisión, cuando se transmite dicha bandera se pone en 1. Cuando se recibe la bandera del bit 5 RDRF se pone en 1. Para limpiar las banderas hay que leer el registro SCI1S1 (Ej, Variable=SCI1S1 en C y LDA SCI1S1 en assembler)
SCIxS2
7 6 5 4 ¦ 3 2 1 0 |
LBKDIF | RXEDGIF | /////// | RXINV | RWUID | BRK13 | LBKDE | RAF |
---|
Configura las opciones de soporte LIN y supervisa la actividad del receptor.
SCIxC3
7 6 5 4 ¦ 3 2 1 0 |
R8 | T8 | TXDIR. | TXINV. | ORIE. | NEIE. | FEIE. | PEIE. |
---|
Es otro registro de control del SCI, que es poco usado, para más información dirigirse al manual del MC9S08QE128
SCIxD
El registro SCIxD se utiliza para recibir o transmitir un dato por el puerto serial. Para más detalles ver la sección de [[SCI (Interfaz de Comunicación Serial) - MC9S08QE128#Inicializaciones Generales del SCI|Inicializaciones Generales del SCI.
7 6 5 4 ¦ 3 2 1 0 |
R7/T7 | R6/T6 | R5/T5 | R4/T4 | R3/T3 | R2/T2 | R1/T1 | R0/T0 |
---|
Escribe: Recepción (Rx) de dato; Escribe: Transmisión (Rx) de dato.
Serial por Encuesta
Transmisión
Este programa se queda esperando hasta que transmita un dato, para luego salir del ciclo, enviar por el puerto el dato y finalmente limpiar la bandera, para volver a transmitir.
En Assembler
Esta es una sub-rutina para la cual se llama con la instrucción jsr Transmitir
Transmitir:
lda dato ; Se coloca en el dato que se desea transmitir en el Acumulador.
sta SCI1D ; Se coloca el dato en el registro de data del puerto para ser enviado.
BRCLR SCI1S1_TDRE,SCI1S1,* ; Condición de salto que verifica si la
;el dato fue transmitido.
lda SCI1S1 ; Se aclara la bandera MUY IMPORTANTE.
RTS ; Se sale de la sub rutina y vuelve al PC+1 de donde fue llamada.
En Lenguaje "C"
Se crea como una función, la cual se llama con Transmitir_dato(dato)
void Transmitir_dato(byte dato) // Se ejecuta la transmisión de dato por encuesta
{ byte bandera;
while (SCI1S1_TDRE == 0); // No finaliza ciclo hasta que esté libre el registro
// en el que se guardará el dato que se enviará.
bandera= SCI1S1; // Aclara la bandera.
SCI1D = dato; // Enviando dato.
}
Recepción
Este programa se queda esperando hasta que reciba un dato, para luego salir del ciclo, enviar el dato por el puerto y finalmente limpiar las banderas, para volver a recibir.
En Assembler
Esta es una sub-rutina para la cual se llama con la instrucción jsr RecepcionSerial
RecepcionSerial:
BRCLR SCI1S1_RDRF,SCI1S1,* ;Revisamos si se levanta la bandera de recepcion
LDA SCI1S1 ;Primer paso para limpiar la bandera
LDA SCI1D ;Segundo paso para limpiar la bandera. Se lee el dato recibido
STA DatoSerial ;Se coloca el valor del acumulador en la variable DatoSerial.
RTS
Para un ejemplo más completo puede ver el artículo: Ejemplo SCI Recepción por encuesta
En Lenguaje "C"
Se crea como una función, la cual se llama con Recibir_dato()
byte Recibir_dato(void) // Se ejecuta la recepción de dato por encuesta.
{ byte dato_R;
byte bandera;
while (SCI1S1_RDRF == 0); // No finaliza ciclo hasta que esté listo el dato.
bandera= SCI1S1; // Aclara la Bandera.
dato_R = SCI1D; // Se Salva el Dato.
return dato_R; // Retorna Dato.
}
Hay que aclarar las banderas cada vez que se termine de transmitir o recibir dependiendo de cual sea el caso, es sumamente importante. Si no se hace puede que el programa genere algún tipo de error. Para bajar la bandera solamente tienen que leer el registro SCI1S1.
Serial por Interrupciones
Antes de usar transmisión y recepción por interrupción se debe de usar la inicialización adecuada.
Transmisión
En Assembler
En assembler hay que definir el vector de interrupción de la siguiente manera
;**************************************************************
;* Interrupt Vectors *
;**************************************************************
ORG $FFDE ; Posición en memoria donde se encuentra el vector de interrupción
DC.W Transmite ; Rutina de Transmisión
Si se escribe un valor en el registro SCI1D, este dato se empieza a transmitir, al finalizar la transmisión se produce la interrupción y en nuestro caso se atiende dicha interrupción en la etiqueta Transmite.
Un ejemplo para transmitir una serie de datos por serial es el siguiente:
Transmite: lda dato ; Se carga a el acumulador el dato deseado
sta SCI1D ; Se transmite el dato por el puerto serial
lda SCI1S1 ; Se baja la bandera de transmisión para poder volverla usar
mov #$2C, SCI1C2 ; Se modifica el registro SCI1C2 para que interrumpa el programa cuando se reciba un dato si se recibir
; Otro dato por interrupción de lo contrario borrar esta línea de código
RTI
Cabe destacar que la transmisión por serial está diseñada para enviar cadenas de datos, si se desea enviar uno solo, se debe deshabilitar la interrupción de transmisión utilizando una instrucción como Bclr SCI1C2_TIE, SCI1C2 en la rutina de transmisión y luego habilitarla de nuevo utilizando BSET SCI1C2_TIE, SCI1C2. De esta forma, es posible enviar dato por dato.
Para un ejemplo más completo puede ver el artículo: Ejemplo SCI Transmisión por Interrupciones
En Lenguaje "C"
Para transmitir por interrupción se tiene que usar el siguiente vector "void interrupt VectorNumber_Vsci1tx SCI_TX_ISR(void)". Este vector de interrupción se debe colocar después del "main". Un ejemplo de cómo usar el vector es el siguiente.
void interrupt VectorNumber_Vsci1tx SCI_TX_ISR(void){
byte leer;
leer=SCI1S1; /*Baja la bandera de transmisión, por tal motivo para
volverlo a utilizar hay que ponerlo nuevamente en cero*/
SCI1D=dato; // En el registro SCI1D se guarda lo que se quiere enviar por serial,
// la variable dato se tiene
// que inicializar como una variable global.
SCI1C2=0x2C; // Esta línea de código es opcional, se escribe si se quiere que el programa
// reciba por interrupción
//en caso contrario borrarla.
}
Bajar las banderas cada vez que transmitan es sumamente importante. Si no lo hacen el programa no les volverá a transmitir. Para bajar la bandera solamente tienen que leer el registro SCI1S1
Recepción
En Assembler
En assembler hay que definir el vector de interrupción de recepción de la siguiente manera:
;**************************************************************
;* Interrupt Vectors *
;**************************************************************
ORG $FFE0 ;Espacio en memoria donde se encuentra la interrupción.
DC.W RecepcionSerial ;Rutina de Recepción.
Un ejemplo para recibir por serial es el siguiente
RecepcionSerial:
LDA SCI1S1 ;Primer paso para limpiar la bandera
LDA SCI1D ;Segundo paso para limpiar la bandera. Se lee el dato recibido
STA DatoSerial ;Se coloca el valor del acumulador en la variable DatoSerial.
RTI ;Se sale de la rutina y vuelve al PC+1 de donde fue Llamada.
Para un ejemplo más completo puede ver el artículo: Ejemplo SCI Recepción por Interrupciones
En Lenguaje "C"
Para recibir por interrupción se tiene que usar el siguiente vector "void interrupt VectorNumber_Vsci1rx SCI_RX_ISR(void)". Este vector de interrupción se debe de colocar después del "main". Un ejemplo de cómo usar el vector es el siguiente.
//vector de interrupción por sci para recibir
void interrupt VectorNumber_Vsci1rx SCI_RX_ISR(void) {
byte leer;
byte dato; //Se declaran las variables que recibe el dato que se escribe.
leer = SCI1S1; //Baja la bandera de recepción, por tal motivo para volverlo a utilizar hay que ponerlo nuevamente en cero.
dato = SCI1D; //El registro SCI1D es donde se guarda el dato que se manda por puerto serial, dicho dato se le asigna a la variable dato.
SCI1C2=0x8C; //Esta línea de código es opcional, se escribe si se quiere que el programa transmita por interrupción.
}
Bajar las banderas cada vez que reciban es sumamente importante. Si no lo hacen el programa no les volverá a recibir. Para bajar la bandera solamente tienen que leer el registro SCI1S1