|
|
(No se muestran 15 ediciones intermedias de 6 usuarios) |
Línea 1: |
Línea 1: |
| === IIC === | | === IIC === |
| | | |
− | == Introduccion IIC ==
| + | '''== Protocolo IIC ==''' |
− | | + | |
− | El Inter-Integrated Circuit (IIC) provee un método de comunicación entre varios dispositivos. Está diseñado para operar hasta los 100 kbps con la máxima carga del bus y del tiempo. El dispositivo es capaz de operar a tasas de baudios altas, sin sobrecargar el bus. La longitud máxima de comunicación y el número de dispositivos que pueden ser conectados está limitado por la capacitancia del bus, la cual es de 400 pF.
| + | |
− | | + | |
− | '''Configuración del módulo:''' | + | |
− | | + | |
− | Los pines SDA y SCL del módulo IIC1 pueden ser reposicionados por software usando el registro SOPT2[IIC1PS] tal como se muestra en la siguiente tabla. Este bit selecciona cual puerto de E/S con propósito general está asociado con la operación del IIC1.
| + | |
− | | + | |
− | {| class="wikitable"
| + | |
− | |+ Opciones de Posición del IIC1
| + | |
− | ! SOPT2[IIC1PS] !! Pines para SDA !! Pines para SCL
| + | |
− | | + | |
− | |-
| + | |
− | | 0 por defecto || PTA2 || PTB6
| + | |
− | |-
| + | |
− | | 1 || PTA3 || PTB7
| + | |
− | |}
| + | |
− | | + | |
− | '''Vectores de Interrupción:'''
| + | |
− | | + | |
− | Para la serie de microcontroladores MC9S08QE128, los cuales tienen dos IIC, el vector de interrupciones es compartido por ambos módulos IIC. Cuando las interrupciones son habilitadas para ambos módulos, se debe verificar el bit de IICIF (que hace referencia a la bandera de interrupciones) de los registros IIC1S y IIC2S (estos son los registros de status) para determinar cuál módulo es el causante de la interrupción.
| + | |
− | | + | |
− | '''Características:'''
| + | |
− | | + | |
− | El IIC incluye las siguientes características:
| + | |
− | | + | |
− | * Compatibilidad con el bus estándar del IIC.
| + | |
− | | + | |
− | * Operación con múltiples maestros.
| + | |
− | | + | |
− | * Software programable para una de las 64 frecuencias diferentes del reloj serial.
| + | |
− | | + | |
− | * Software que permite seleccionar el bit de reconocimiento (acknowledge bit)
| + | |
− | | + | |
− | * Manejo de interrupciones mediante la transferencia de datos byte por byte.
| + | |
− | | + | |
− | * Resolución de las interrupciones perdidas con un modo que hace intercambio automático de maestro a esclavo.
| + | |
− | | + | |
− | * Llamado a las direcciones de identificación de las interrupciones.
| + | |
− | | + | |
− | * Generación y detección de las señales START y STOP.
| + | |
− | | + | |
− | * Generación repetida de la señal START.
| + | |
− | | + | |
− | * Generación y detección del bit acknowledge.
| + | |
− | | + | |
− | * Detección de la disponibilidad del bus.
| + | |
− | | + | |
− | * Llamada general de reconocimiento.
| + | |
− | | + | |
− | * Extensión de la dirección a 10 bits.
| + | |
− | | + | |
− | '''Modos de Operación:'''
| + | |
− | | + | |
− | Se presenta a continuación una breve descripción de los modos de operación del IIC:
| + | |
− | | + | |
− | * Modo Corriendo o “Run”: Este es el modo de operación básico. Para conservar la energía en este modo, inhabilite el módulo.
| + | |
− | | + | |
− | * Modo de espera o “Wait”: El módulo seguirá funcionando mientras que el microcontrolador esté en modo de espera y pueda proporcionar una alarma de despertador.
| + | |
− | | + | |
− | * Modo detenido o “Stop”: El IIC está inactivo en el modo Stop para reducir el consumo de energía. La instrucción de Stop no afecta a los registros de estados del IIC. Esta instrucción reiniciará el contenido de los registros.
| + | |
− | | + | |
− | '''Descripción de Señales externas'''
| + | |
− | | + | |
− | Se describe a continuación las señales que son accesibles por cada usuario:
| + | |
− | | + | |
− | * SCL — Línea del Reloj Serial (Serial Clock Line): Es bidireccional, y es la línea del reloj serial del sistema del IIC.
| + | |
− | | + | |
− | * SDA - Línea de Data Serial (Serial Data Line): Es la línea de datos serial del sistema del IIC. Es bidireccional.
| + | |
− | | + | |
− | == Registros IIC == | + | |
− | La dirección del IIC tiene 10-bit de direccionamiento, 0x11110, se utilizan los primeros 5 bits del primer byte de dirección. Se pueden tener varias combinaciones de leer / escribir, estos formatos son posibles con cambios en los 10-bit de direccionamiento.
| + | |
− | | + | |
− | | + | |
− | '''Definición de Registros:''' Todos los registros y bits de control del IIC se especifican sólo por sus nombres, ya que Freescale proporciona una cabecera para trasladar los nombres a las apropiadas direcciones absolutas. | + | |
− | | + | |
− | *'''IIC Address Register (IICxA)'''
| + | |
− | | + | |
− | Esta direccion de registro tiene 8 bits donde los 7 de la izquierda a la derecha es la Slave Address(Dirección del Esclavo). Esta dirección contiene la dirección del esclavo que se utiliza el modulo IIC. Este campo es usado en el esquema de dirección de siete bits, donde son los 7 bits más bajos del esquema de direcciones de 10 bits.
| + | |
− | | + | |
− | *'''IIC Frequency Divider Register (IICxF)'''
| + | |
− | | + | |
− | Esta dirección de registro tiene 8 bits, donde los bits 7 y 8 son el factor multiplicador(MULT),los 2 bits MULT se usan para definir el factor mul, este factor se utiliza junto con el SCL para generar la baud rate ó la velocidad de transmisión del IIC. Esto 2 bit MULT definen el factor mul de la siguiente manera:
| + | |
− | | + | |
− | 00 mul = 01
| + | |
− | | + | |
− | 01 mul = 02
| + | |
− | | + | |
− | 10 mul = 04
| + | |
− | | + | |
− | 11 Reserved
| + | |
− | | + | |
− | Los últimos cinco bits de la izquierda a la derecha de esta dirección de registro son para la velocidad del reloj (ICR), estos bits se utiliza para pee-determinar del reloj de bus para la selección de la tasa de bits.
| + | |
− | | + | |
− | Los bits MULT y los bits del clock rate se usan para calcular la velocidad de transmisión, el tiempo de retención SDA, el tiempo de inicio del SCL y el tiempo de detenimiento del SCL. Cada una se puede calcular de la siguiente manera:
| + | |
− | | + | |
− | -IIC baud rate = bus speed (Hz)/(mul * SCL divider)
| + | |
− | | + | |
− | -SDA hold time = bus period (s) * mul * SDA hold value
| + | |
− | | + | |
− | -SCL Start hold time = bus period (s) * mul * SCL Start hold value
| + | |
− | | + | |
− | -SCL Stop hold time = bus period (s) * mul * SCL Stop hold value
| + | |
− | | + | |
− | *'''IIC Control Register (IICxC1)'''
| + | |
− | | + | |
− | Este registro de control esta definido por 8 bits, el bit 7 es el de habilitación (IICEN) donde con 0 el IIC no esta habilitado y con 1 el IIC esta habilitado.
| + | |
− | | + | |
− | El siguiente bit "6" es el de la habilitación de interrupción(IICIE), este determina cuando una interrupción fue solicitada, con 0 no fue solicitada la habilitación y con 1 si fue solicitada la interrupción.
| + | |
− | | + | |
− | El 5 bit es el del modo maestro seleccionado (MST), con este bit si se cambia de de 0 a 1 cuando la señal se genera en el bus y luego se selecciona el modo maestro. Cuando este bit cambia de 1 a 0 se genera una señal de detención o STOP, y el modo de operación cambia de maestro a esclavo.
| + | |
− | | + | |
− | 0 Slave mode.
| + | |
− | | + | |
− | 1 Master mode.
| + | |
− | | + | |
− | El 4 bit es el modo de transmicion seleccionado (TX), con este bit se selecciona el modo de transferencia entre el esclavo y el maestro.En el modo maestro de este bit debe establecerse de acuerdo con el tipo de transferencia requerida. Por lo tanto, para los ciclos de direcciones, este bit siempre será alto.Cuando se establezca en modo esclavo este bit debe establecerse por el software de acuerdo con el bit de SRW en el registro de estado.
| + | |
− | | + | |
− | Recibe 0.
| + | |
− | | + | |
− | Transmite 1.
| + | |
− | | + | |
− | El tercer bit es el de reconocimiento de transmicion habilitada (TXAK), este bit reconoce la transmitir habilitada Este bit especifica el valor llevado a la SDA durante el reconocimiento de datos en ciclos, para tanto receptor maestro como receptor esclavo.
| + | |
− | | + | |
− | 0 Se envia una señal de recepción al bus después de recibir un data byte.
| + | |
− | | + | |
− | 1 Ninguna señal de reconocimiento es enviada
| + | |
− | | + | |
− | El segundo es el de repetir inicio(RSTA) Escribir un 1 en este bit generará una condición de START repetida siempre y cuando sea el maestro. Este bit siempre será leído como bajo. El intento que se repita en el momento equivocado resultará en la pérdida de arbitraje.
| + | |
− | | + | |
− | *'''IIC Status Register (IICxS)'''
| + | |
− | | + | |
− | Este registro tiene 8 bits donde el bit 7 se llama bandera de transferencia completa(TCF), este bit se establece en la finalizacion de la transferencia de bytes.Tenga en cuenta que este bit sólo es válida durante o inmediatamente después de una transferencia al módulo IIC o desde el modulo IIC.El bit de TCF se elimina mediante la lectura del registro IICxD en el modo receptor o escribiendo en IICxD en el modo de transmisión.
| + | |
− | | + | |
− | 0 Transfer in progress.
| + | |
− | | + | |
− | 1 Transfer complete.
| + | |
− | | + | |
− | El sexto bit es el de dirigido como un esclavo(IAAS), esté bit se establece cuando la dirección de la llamada coincide con la dirección del esclavo programado, o cuando el bit GCAEN se establece y se recibe una llamada general.Escribir el registro IICxC borra este bit.
| + | |
− | | + | |
− | El quinto bit es el de bus ocupado(BUSY), indica el estado del bus independientemente del esclavo o del maestro. El bit BUSY está
| + | |
− | activa cuando se detecta una señal de arranque y se apaga cuando se detecta una señal de STOP.
| + | |
− | | + | |
− | 0 bus está inactivo.
| + | |
− | | + | |
− | 1 bus está ocupado.
| + | |
− | | + | |
− | El cuarto bit es el de arbitraje perdido(ARBL), este bit es activado por hardware cuando se pierde el procedimiento de arbitraje. El bit debe ser
| + | |
− | despejado por software, escribiendo un 1 a la misma.
| + | |
− | | + | |
− | 0 funcionamiento de bus estándar.
| + | |
− | | + | |
− | 1 La pérdida de arbitraje.
| + | |
− | | + | |
− | El 2 bit es el de esclavo de lectura/escritura(SRW),cuando es llamado como un esclavo del SRW bits indica el valor del bit de comando R / W de
| + | |
− | la dirección solicitante y la envía al maestro.
| + | |
− | | + | |
− | 0 Esclavo recibir, por escrito maestro a esclavo.
| + | |
− | | + | |
− | 1 Esclavo de transmisión, maestra de lectura del esclavo.
| + | |
− | | + | |
− | El bit 1 es el de bandera de interrupcion del ICC (IICIF), se establece cuando una interrupción está pendiente. Este bit debe ser limpiado por software, escribiendo un 1 en la rutina de interrupción. Uno de los siguientes eventos pueden establecer el bit IICIF:
| + | |
− | | + | |
− | • Una transferencia de bytes completa
| + | |
− | • Ajuste de la dirección del esclavo a la dirección llamando
| + | |
− | • Arbitraje perdió
| + | |
− | 0 No se interrumpen en espera.
| + | |
− | 1 interrupción pendiente
| + | |
− | | + | |
− | el bit 0 Recibe Reconocimiento(RXAK),cuando es baja, indica una señal de confirmación se ha recibido después
| + | |
− | la realización de un byte de la transmisión de datos en el bus. Si el bit es alto RXAK significaría que no se
| + | |
− | se detecta la señal.
| + | |
− | | + | |
− | 0 Reconocer recibido.
| + | |
− | | + | |
− | 1 No se reconocen recibido.
| + | |
− | | + | |
− | == Protocolo IIC ==
| + | |
− | | + | |
| | | |
| El Protocolo Inter-Integrated Circuit (IIC), se compone de 4 partes principales, las cuales componen el envío de un mensaje, descritos a continuación: | | El Protocolo Inter-Integrated Circuit (IIC), se compone de 4 partes principales, las cuales componen el envío de un mensaje, descritos a continuación: |
Línea 190: |
Línea 12: |
| | | |
| '''Señal de STOP:''' Cuando la transmisión de datos ha finalizado, ambos buses SDA Y SCL vuelven a su estado lógico inicial en 1 y tanto maestro como esclavo dan por finalizada la comunicación. | | '''Señal de STOP:''' Cuando la transmisión de datos ha finalizado, ambos buses SDA Y SCL vuelven a su estado lógico inicial en 1 y tanto maestro como esclavo dan por finalizada la comunicación. |
− |
| |
− | [[
| |
− |
| |
− |
| |
− | Image:iic1|thumb|widthpx| ]]
| |
− |
| |
| | | |
| Funcionamiento del protocolo | | Funcionamiento del protocolo |
Línea 221: |
Línea 37: |
| También se puede enviar un mensaje General del tipo “Broadcast”, con llaves de 10 o 7 bits seteando el registro GCAEN. | | También se puede enviar un mensaje General del tipo “Broadcast”, con llaves de 10 o 7 bits seteando el registro GCAEN. |
| | | |
− | == Interrupciones ==
| |
| | | |
− | El IIC puede generar sólo una interrupción. Para que se genere una interrupción, debe ocurrir cualquiera de los eventos de la tabla siguiente, siempre y cuando el bit IICIE esté activado:
| + | == Ejemplo IIC: Acelerómetro == |
| | | |
− | {| class="wikitable"
| + | El DEMOQE128 posee algunos perifericos con los cual puede tener comunicación. En este caso, el periferico utilizado sera el acelerómetro. |
− | |+ Interrupciones mediante IIC
| + | |
− | ! Fuente de interrupción !! Status !! Flag !! Local Enable
| + | |
| | | |
− | |-
| + | El acelerómetro que posee la DEMOQE128 es de tipo digital, y se encarga de tomas datos referentes a la aceleración que puede sufrir la tarjeta en cierto momento así como su posición. En este caso, se desea la aparición de los leds moviéndose en forma de "gotas", en consonancia con la posición dada a la tarjeta. Para ello se requiere la implementación de una subrutina mostrada a continuación: |
− | | Completar la transferencia de 1 byte || TCF || IICIF || IICIE
| + | |
− | |-
| + | |
− | | Ajuste de direcciones de llamada recibidas || IAAS || IICIF|| IICIE
| + | |
| | | |
− | |-
| + | ///////////////////////////////////////////////////////////////////////////////////////// |
− | | Pérdida arbitraria || ARBL || IICIF || IICIE
| + | // ShowAcceleration |
− | |}
| + | // -------------------------------------------------------------------------------------- |
− | | + | // - Prints the accelaration data in the terminal; |
− | La interrupción es impulsada por el bit IICIF (del IIC Status Register) y es enmascarada con el bit IICIE (del IIC Control Register). El bit IICIF se puede limpiar asignándole un 1 en la rutina de interrupción. El usuario puede determinar el tipo de interrupción mediante la lectura del Status Register.
| + | ///////////////////////////////////////////////////////////////////////////////////////// |
− | | + | void ShowAcceleration (void) |
− | '''Interrupción por transferencia de byte'''
| + | { |
− | | + | word SampleCNT; |
− | El bit TCF (transfer complete flag) se establece a flanco de bajada del 9th clock para indicar la completación de la transferencia del byte
| + | byte j,k; |
− | | + | <br> |
− | '''Interrupción por detección de dirección'''
| + | ReadAcceleration(); // Read acceleration data |
− | | + | ADCSC1 = 0x01; // Select ADC1 (PTA1) channel |
− | Cuando la dirección de llamadas coincide con la dirección del esclavo programado (IIC address register) o cuando el bit GCAEN está activado y una llamada general es recibida, el bit IAAS en el Status Register es activado. La CPU es interrumpida siempre y cuando se active el bit IICIE. La CPU debe revisar el bit SRW y activar su modo Tx en consecuencia.
| + | x.reading[samp] = (dword)( IIC_Converted_Data[0] 0;k--){} |
− | | + | |
− | '''Interrupción por pérdida de arbitraje'''
| + | |
− | | + | |
− | El IIC es un verdadero bus con múltiples maestros que permite más de un maestro para ser conectado en él. Si dos o más maestros tratan de controlar el bus al mismo tiempo, se determina la prioridad relativa de los maestros en contienda por un procedimiento de arbitraje de datos. El módulo IIC asegura esta interrupción cuando pierde el proceso de arbitraje de datos y el bit ARBL en el Status Register está activado.
| + | |
− | | + | |
− | El arbitraje se puede perder en las siguientes circunstancias:
| + | |
− | | + | |
− | *SDA probado como bajo cuando el maestro produce un alto durante un ciclo de dirección o de transmisión de datos.
| + | |
− | | + | |
− | *SDA probado como bajo cuando el maestro produce un alto durante el bit de aviso de un ciclo de recepción de datos
| + | |
− | | + | |
− | *Un ciclo de arranque se intenta cuando el bus está ocupado
| + | |
− | | + | |
− | *Un ciclo repetido de arranque es requerido en modo esclavo
| + | |
− | | + | |
− | *Se detecta una condición de parada cuando el maestro no lo solicitó
| + | |
− | | + | |
− | '''Resets'''
| + | |
− | | + | |
− | El IIC se desactiva luego de un RESET. El IIC no puede provocar un reinicio o reseteo del microcontrolador.
| + | |
− | | + | |
− | == Ejemplos de IIC en el QRUG ==
| + | |
− | | + | |
− | Los ejemplos aquí mostrados están disponibles en el sitio web de Freescale.
| + | |
− | | + | |
− | '''Proyecto del IIC: Configuración de Maestro.'''
| + | |
− | | + | |
− | En esta aplicación, dos pines son usados para trabajar con el protocolo del IIC. Uno de ellos es el PTH7, el cual es el pin de datos del protocolo de IIC. El segundo es el PTH6, el pin para el reloj.
| + | |
− | | + | |
− | Las funciones del IIC MASTER PROYECT son las siguientes:
| + | |
− | | + | |
− | * main: Es un ciclo infinito en el cual se manda un byte, el cual funciona como contador, y espera que ocurra la interrupción del IIC.
| + | |
− | * MCU_init: Se deshabilita el “watchdog” de la inicialización del MCU y se habilita el módulo del reloj del IIC.
| + | |
− | * GPIO_init: Se configuran los puertos PTE como las salidas, y los puertos PTH7 y PTH6 como entrada.
| + | |
− | * IIC_init: Se configura el módulo de IIC.
| + | |
− | * IIC_ISR: Configuración de la rutina de interrupción del IIC.
| + | |
− | * Delay: Retardos.
| + | |
− | | + | |
− | La Configuración del "Maestro", configura el MCU para trabajar como “maestro” y usa el protocolo del IIC para mandar un byte, que funciona como contador, al esclavo. La cuenta del contador se muestra en los ocho LEDS del microcontrolador.
| + | |
− | | + | |
− | La siguiente parte del código corresponde a la inicialización del MCU. Estas instrucciones deshabilitan al “watchdog”, habilitan la opción de “reset” y el Background Pin. El System Option Register 1 (SOPT1) es usado para la inicialización del MCU. El SCGC1 y el SCGC2 son registros usados para ahorrar energía, aquí el reloj de los puertos periféricos puede desactivarse. En este ejemplo, solo el reloj del módulo del IIC está activo y los “relojes” de otros puertos periféricos están desactivados.
| + | |
− | | + | |
− | <pre>void MCU_init(void){
| + | |
− | SOPT1 = 0x23; // Watchdog deshabilitado. Stop Mode habilitado. Background Pin habilitado.
| + | |
− | // Habilitado el pin de "reset".
| + | |
− | SCGC1 = 0x08; // Habilitado el pin del reloj del módulo de IIC.
| + | |
− | }</pre>
| + | |
− | | + | |
− | Las siguientes líneas de código corresponden a la configuración del General Purpose Input/Output. Está parte configura las direcciones para los puertos PTE y PTH. Ocho LEDs están conectados al puerto PTE, por lo que este esta configurado como la salida. El puerto PTH6 y el PTH7 están configurados como salidas también. Estos dos pines corresponden al Serial Clock (SCL) y a la Serial Data (SDA).
| + | |
− | | + | |
− | <pre>void GPIO_Init(void) {
| + | |
− | PTHPE = 0xC0; // Habilita Pull ups en los pines PTH7 y PTH6.
| + | |
− | PTEDD = 0xFF; // Configura los pines PTE como salidas
| + | |
− | PTED = 0x00; // Coloca 0's en los puertos PTE
| + | |
− | }</pre>
| + | |
− | | + | |
− | Lo siguiente corresponde a La inicialización del IIC usando el QE MCU. Aquí Se configura el modulo para que trabaje como “maestro”. El MCU trabaja con una velocidad de transmisión de 4 MHz, La tasa de baudios del IIC puede ser calculada de La siguiente manera:
| + | |
− | | + | |
− | IIC tasa de baudios = velocidad de transmisión (Hz) / (mul * Divisor de SCL);
| + | |
− | IIC tasa de baudios = 4000000 / (1 * 32);
| + | |
− | IIC tasa de baudios = 125000;
| + | |
− | | + | |
− | La tasa de baudios de este ejemplo es 125000 porque el módulo ICS no está configurado y el MCU trabaja con su velocidad por defecto (4MHz).
| + | |
− | | + | |
− | <pre>void IIC_Init (void) {
| + | |
− | IIC2F = 0x09; // Multiplica por un factor de 1. Divisor SCL de 32.
| + | |
− | IIC2C1 = 0xC0; // Habilita el módulo de IIC y las interrupciones.
| + | |
− | }</pre>
| + | |
− | | + | |
− | La siguiente es la función de retardos, usada antes de que el MCU comience a mandar el siguiente byte (luego de enviar el contador) al esclavo. Esta función sólo se usa para observar los cambios que ocurren en los LEDs.
| + | |
− | | + | |
− | <pre>void Delay (int16 c) {
| + | |
− | int16 i = 0;
| + | |
− | for (i; i<=c; i++) {
| + | |
− | }
| + | |
− | }</pre>
| + | |
− | | + | |
− | Ahora se presenta la función principal. Se incluyen las funciones antes mencionadas y se habilitan todas las interrupciones. En el ciclo infinito, el IIC envía un byte contador al esclavo. La función de retardo es llamada entre cada transferencia de bytes.
| + | |
− | | + | |
− | <pre>void main(void) {
| + | |
− | MCU_Init(); // Función que inicializa el MCU.
| + | |
− | GPIO_Init(); // Función que inicializa los puertos del MCU.
| + | |
− | IIC_Init(); // Función que inicializa el módulo de IIC.
| + | |
− | EnableInterrupts; // Habilita las interrupciones.
| + | |
− | for(;;) {
| + | |
− | Delay(60000);
| + | |
− | PTED = counter;
| + | |
− | counter++;
| + | |
− | if (PTHD_PTHD7 == 0) {
| + | |
− | while (PTHD_PTHD7 == 0); // Espera mientras el pin es bajo.
| + | |
− | while (IIC2C1_MST == 1); // Espera mientras el IIC esta detenido.
| + | |
− | MasterTransmit(1,1); // Inicializa la transmisión.
| + | |
− | }
| + | |
− | else {
| + | |
− | }
| + | |
− | while (IIC2C1_MST == 1); // Espera mientras el IIC está detenido.
| + | |
− | Master_Receive();
| + | |
− | } // ciclo infinito.
| + | |
− | // Asegurarse de nunca salir de esta función.
| + | |
− | } </pre>
| + | |
− | | + | |
− | Las siguientes funciones son usadas cuando el IIC es configurado como “maestro”:
| + | |
− | | + | |
− | <pre>void Master_Read_and_Store(void) {
| + | |
− | if (rec_count == num_to_rec) {
| + | |
− | last_byte_to_rec = 2;
| + | |
− | }
| + | |
− | IIC_Rec_Data[rec_count] = IIC2D;
| + | |
− | rec_count++;
| + | |
− | }</pre>
| + | |
− | | + | |
− | <pre>void Master_Transmit(uint8 a, uint8 b) {
| + | |
− | // Esta función inicia la transmisión. | + | |
− | last_byte = 0; // Inicializa.
| + | |
− | count = 0;
| + | |
− | bytes_to_trans = a; // Selecciona el número de bytes a transferir.
| + | |
− | num_to_rec = b;
| + | |
− | IIC2C1_TX = 1; // Establece un bit TX para el ciclo llave.
| + | |
− | IIC2C1_MST = 1; // Establece un bit Maestro para generar la señal de "start".
| + | |
− | IIC2D = 0xAA; // Envia la llave de datos LSB, la cual es R o W para el esclavo.
| + | |
− | } </pre>
| + | |
− | | + | |
− | <pre>void Master_Receive() {
| + | |
− | rec_count = 0;
| + | |
− | last_byte_to_rec = 0;
| + | |
− | last_byte = 0;
| + | |
− | count = 0;
| + | |
− | num_to_rec = 0;
| + | |
− | IIC2C1_TXAK = 0;
| + | |
− | IIC2C1_TX = 1; // Set TX bit for Address cycle
| + | |
− | IIC2C1_MST = 1; // Set Master Bit to generate a Start
| + | |
− | add_cycle = 1; // This variable sets up a master rec in the ISR
| + | |
− | IIC2D = 0xAB; // Send Address data LSB is R or W for Slave
| + | |
− | } </pre>
| + | |
− | | + | |
− | La siguiente, es la rutina del IIC. Estas rutinas manejan al maestro y al esclavo en ambos modos, como transmisor y receptor. Si el dispositivo está funcionando como maestro, basta con seguir la lógica del maestro. En cambio, si el dispositivo está trabajando como esclavo, basta con que siga la lógica del esclavo.
| + | |
− | | + | |
− | <pre>interrupt VectorNumber_iicx void IIC_ISR(void) {
| + | |
− | // IIC interrupt vector number = 17 (S08)
| + | |
− | // IIC interrupt vector number = 79 (V1)
| + | |
− | IIC2S_IICIF = 1; // Clear Interrupt Flag
| + | |
− | if (IIC2C1_MST){ // Master or Slave?
| + | |
− | /***************************** Master **********************************/ | + | |
− | if (IIC2C1_TX) { // Transmit or Receive?
| + | |
− | /**************************** Transmit *********************************/ | + | |
− | if (last_byte) { // Is the Last Byte?
| + | |
− | IIC2C1_MST = 0; // Generate a Stop
| + | |
− | }
| + | |
− | else if (last_byte != 1) {
| + | |
− | if (IIC2S_RXAK) { // Check for ACK
| + | |
− | IIC2C1_MST = 0; // No ACk Generate a Stop
| + | |
− | }
| + | |
− | else if (!IIC2S_RXAK) {
| + | |
− | if (add_cycle) { // Is Address Cycle finished? Master done addressing Slave?
| + | |
− | add_cycle = 0; // Clear Add cycle
| + | |
− | IIC2C1_TX = 0; // Switch to RX mode
| + | |
− | IIC2D; // Dummy read from Data Register
| + | |
− | }
| + | |
− | else if (add_cycle !=1) {
| + | |
− | IIC2D = counter; // Transmit Data
| + | |
− | count++;
| + | |
− | if (count == bytes_to_trans) {
| + | |
− | last_byte = 1;
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | else {
| + | |
− | /**************************** Receive **********************************/ | + | |
− | if (last_byte_to_rec == 1) {
| + | |
− | IIC2C1_MST = 0; // Last byte to be read?
| + | |
− | Master_Read_and_Store();
| + | |
− | }
| + | |
− | else if (last_byte_to_rec == 2){ // Second to last byte to be read?
| + | |
− | last_byte_to_rec = 1;
| + | |
− | IIC2C1_TXAK = 1; // This sets up a NACK
| + | |
− | Master_Read_and_Store();
| + | |
− | }
| + | |
− | else {
| + | |
− | Master_Read_and_Store();
| + | |
− | }
| + | |
| } | | } |
| } | | } |
− | else {
| |
− | /***************************** Slave ***********************************/
| |
− | if (IIC2S_ARBL) {
| |
− | IIC2S_ARBL = 1;
| |
− | if (IIC2S_IAAS) { // Chequea las coincidencias en la llave.
| |
− | count = 0;
| |
− | SRW();
| |
− | }
| |
− | }
| |
− | else {
| |
− | if (IIC2S_IAAS) { // No se pierde el arbitraje.
| |
− | count = 0;
| |
− | SRW();
| |
− | }
| |
− | else {
| |
− | if (IIC2C1_TX) { // Chequa el rec ACK
| |
− | if (!IIC2S_RXAK) { // ACK recibido.
| |
− | IIC2D = IIC_TX_Data[count];
| |
− | count++;
| |
− | }
| |
− | else {
| |
− | IIC2C1_TX = 0;
| |
− | IIC2D;
| |
− | }
| |
− | }
| |
− | else {
| |
− | Slave_Read_and_Store();
| |
− | }
| |
− | }
| |
− | }
| |
− | }
| |
− | } </pre>
| |
| | | |
− | Esta función es utilizada para inicializar el proceso de transferencia de datos. Se inicializan algunas variables. Se establece el bit maestro (MST) y se genera una señal de inicio, de modo que el proceso de comunicación comience a partir de ese momento. Luego se envía la llave del esclavo.
| + | // Display Acceleration |
− | | + | SendMsg("\r\n"); |
− | <pre>void Master_Transmit(uint8 a, uint8 b) {
| + | SendMsg(word2asc((word)x.result[samp],dis_base)); |
− | last_byte = 0; | + | SendMsg(","); |
− | count = 0; | + | SendMsg(word2asc((word)y.result[samp],dis_base)); |
− | bytes_to_trans = a; // Número de bytes a transferir. | + | SendMsg(","); |
− | num_to_rec = b; // Numero de bytes a almacenar. | + | SendMsg(word2asc((word)z.result[samp],dis_base)); |
− | IIC2C1_TX = 1; // Set TX bit for Address cycle | + | SendMsg(","); |
− | IIC2C1_MST = 1; // Set Master Bit to generate a Start | + | SendMsg(word2asc(SampleCNT,dis_base)); |
− | IIC2D = 0xAA; // Send Address data LSB is R or W for Slave | + | <br> |
− | }</pre>
| + | //145B min Y -> |
− | | + | //2F00 max Y |
− | Esta función es usada para leer la data recibida desde el dispositivo esclavo y para almacenar dicha información en el arreglo llamado IIC_Rec_Data array. En este ejemplo sólo se usa el primer byte.
| + | if (y.result[samp]>=0x2cec) |
− | | + | PTCD = 0x3E; |
− | <pre>void Master_Read_and_Store(void) {
| + | else if (y.result[samp]>=0x2ac9) |
− | if (rec_count == num_to_rec) { | + | PTCD = 0x3D; |
− | last_byte_to_rec = 2;
| + | else if (y.result[samp]>=0x2619) |
| + | PTCD = 0x3B; |
| + | else if (y.result[samp]>=0x2169) |
| + | PTCD = 0x37; |
| + | else if (y.result[samp]>=0x1cb9) |
| + | { |
| + | PTCD = 0x2F; |
| + | PTED = 0xc0; |
| } | | } |
− | IIC_Rec_Data[rec_count] = IIC2D; | + | else if (y.result[samp]>=0x1809) |
− | rec_count++;
| + | { |
− | }</pre>
| + | PTCD = 0x1F; |
− | | + | PTED = 0xc0; |
− | Esta función es usada para inicializar el proceso de recepción y almacenamiento en el MCU. Se inicializan algunas variables y se establece el bit MST para generar la señal de entrada.
| + | |
− | | + | |
− | <pre>void Master_Receive() {
| + | |
− | rec_count = 0;
| + | |
− | last_byte_to_rec = 0;
| + | |
− | last_byte = 0;
| + | |
− | count = 0;
| + | |
− | num_to_rec = 0;
| + | |
− | IIC2C1_TXAK =0;
| + | |
− | IIC2C1_TX = 1; // Establece un bit TX para la llave del ciclo.
| + | |
− | IIC2C1_MST = 1; // Establece un bit Maestro para generar el comienzo.
| + | |
− | add_cycle = 1; // Esta variable establece un rec Maestro en el ISR
| + | |
− | IIC2D = 0xAB; // Envía la llave de datos LSB, R o W para el esclavo.
| + | |
− | } </pre>
| + | |
− | | + | |
− | | + | |
− | | + | |
− | | + | |
− | '''Proyecto del IIC: Configuración de Esclavo.'''
| + | |
− | | + | |
− | Este proyecto es similar al proyecto del IIC Maestro. Este ejemplo muestra como configurar el MCU como esclavo. El ISR utilizado es el mismo, al igual que las funciones utilizadas. Para información mas detallada de los códigos visite la pagina web www.freescale.com
| + | |
− | | + | |
− | Esta función es usada cuando el dispositivo esta trabajando como esclavo y es necesario saber si el dispositivo esta realizando un “dummy read” o escribe datos al maestro.
| + | |
− | | + | |
− | El “dummy read” no es una verdadera lectura del bus I2C, pero es una lectura del registro IICD en el bloque del IIC. No será visto en el bus o en cualquier especificación del I2C porque es interna al diseño del bloque de hardware I2C.
| + | |
− | | + | |
− | | + | |
− | <pre>void SRW(void) {
| + | |
− | if (IIC2S_SRW) { // Chequea por Slave Rec o si transmite | + | |
− | IIC2C1_TX = 1; // Configurar el bit Tx para tramsmitir
| + | |
− | IIC2D = IIC_TX_Data[count];
| + | |
− | count++;
| + | |
| } | | } |
− | else { | + | else if (y.result[samp]>=0x1359) |
− | | + | { |
− | IIC2C1_TX = 0;
| + | PTED = 0x80; |
− | IIC2D; // Dummy read
| + | PTCD = 0x3F; |
− | | + | } |
| + | else if (y.result[samp]>=0x0fa0) |
| + | { |
| + | PTED = 0x40; |
| + | PTCD = 0x3f; |
| } | | } |
− | } </pre>
| + | <br> |
| + | // Shift array of results if we hit max |
| + | if (samp >= max-1) { |
| + | for (j=0;j max) |
| + | <br> |
| + | }// end ShowAcceleration |
| | | |
− | Esta función lee datos del buffer del IIC y lo guarda en el arreglo IIC_Rec_Data. En este ejemplo solo se utiliza el primer byte de este arreglo.
| + | El efecto mostrado se muestra en el siguiente video: |
| | | |
− | <pre>void Slave_Read_and_Store(void) {
| + | https://youtu.be/hkCpcnWNMu0 |
− | if (rec_count == num_to_rec) {
| + | |
− | last_byte_to_rec = 2;
| + | |
− | }
| + | |
− | IIC_Rec_Data[rec_count] = IIC2D;
| + | |
− | rec_count++;
| + | |
− | if (rec_count == num_to_rec) {
| + | |
− | rec_count = 0;
| + | |
− | }
| + | |
− | }</pre>
| + | |
− | | + | |
− | == Ejemplos IIC ==
| + | |
− | === Acelerometro ===
| + | |
| | | |
| [[Articulo de ejemplo DEMOQE128]] | | [[Articulo de ejemplo DEMOQE128]] |
Línea 547: |
Línea 115: |
| '''Formato:''' | | '''Formato:''' |
| '''Estudiante : Artículo aprobado''' | | '''Estudiante : Artículo aprobado''' |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
| | | |
| [[Categoría: EC2783 - Lab. Arquitectura del Computador - Ing. Telecom.]] | | [[Categoría: EC2783 - Lab. Arquitectura del Computador - Ing. Telecom.]] |
El Protocolo Inter-Integrated Circuit (IIC), se compone de 4 partes principales, las cuales componen el envío de un mensaje, descritos a continuación:
Como ya se mencionó, cada 9 flancos de reloj ocurre un reconocimiento del byte inmediatamente enviado. La dirección del esclavo, o “llave” como ya se hizo referencia, se encuentra contenida en una combinación de 10-bits, configurados de la siguiente manera:
El primer byte enviado del maestro al esclavo contiene necesariamente el siguiente contenido:
Bits 0-4 (11110x): Son bits constantes, e indican que una dirección de esclavo será enviada posteriormente.
Bits 5-6 (AD10-AD9): pertenecen a los primeros 2 bits de los 10 que componen la dirección de esclavo.
Bit 7 (R/W): debe estar configurado obligatoriamente en 0 ya que es el maestro quien transmite, y en este caso los esclavos quienes escuchan. NOTA: hasta este punto pueden seguir escuchando mas de un esclavo, ya que la llave será completada por 8-bits, enviados posteriormente.
Luego el maestro debe esperar el bit de reconocimiento, para proceder a enviar la segunda cadena de bit, compuesta por los 8 bits restantes que completan la llave, para la cual solo debe existir una respuesta de reconocimiento, del esclavo respectivo con quien se establece la comunicación.
Comunicación Maestro a esclavo: Posteriormente al procedimiento explicado se proceden a enviar los bits de datos, los cuales son recibidos por el esclavo hasta que ocurra la condición de STOP.
Comunicación Esclavo a maestro: Una vez recibido el segundo bit de reconocimiento(A2), se debe enviar un tercer byte con los primeros 7-bits idénticos al primer byte enviado (1110xxx0) con la diferencia del bit 0, el cual es sustituido con 1, para configurar el modo de lectura del maestro.
También se puede enviar un mensaje General del tipo “Broadcast”, con llaves de 10 o 7 bits seteando el registro GCAEN.
El DEMOQE128 posee algunos perifericos con los cual puede tener comunicación. En este caso, el periferico utilizado sera el acelerómetro.
El acelerómetro que posee la DEMOQE128 es de tipo digital, y se encarga de tomas datos referentes a la aceleración que puede sufrir la tarjeta en cierto momento así como su posición. En este caso, se desea la aparición de los leds moviéndose en forma de "gotas", en consonancia con la posición dada a la tarjeta. Para ello se requiere la implementación de una subrutina mostrada a continuación:
/////////////////////////////////////////////////////////////////////////////////////////
// ShowAcceleration
// --------------------------------------------------------------------------------------
// - Prints the accelaration data in the terminal;
/////////////////////////////////////////////////////////////////////////////////////////
void ShowAcceleration (void)
{