Está en la página 1de 101

MICROCONTROLADORES Y LENGUAJE C

Fundamentos de Lenguaje C para PICs
Introducción
En un programa en C se pueden diferenciar varios elementos. * Directivas de preprocesado
- Indican al compilador cómo debe generar el código máquina. - Bloques funcionales del programa. - Siempre debe incluirse una función llamada main(). - Instrucciones que definen lo que hace el programa y la secuencia de ejecución del mismo. - Imprescindibles como documentación del código fuente.
/* FORMATO TIPO DE FICHERO C*/ #include <stdio.h> //Directiva

* Funciones

* Sentencias

/* Suma dos enteros */ int suma (int a,b) { return (a+b); //Devuelve suma }

* Comentarios

/* Función principal */ main() { int dato1,dato2; //Declaración int res; //Declaración dato1=5; //Asignación dato2=3; //Asignación res=suma(dato1,dato2); }

Fundamentos de Lenguaje C para PICs
Variables
Una variable es un nombre asignado a una o varias posiciones de memoria RAM. En C es necesario declarar todas las variables antes de poder utilizarlas, indicando el nombre asignado y el tipo de datos que en ella se van a almacenar (opcionalmente también el valor inicial asignado). tipo nombre_variable [=valor]; p.e.: int i;

Los tipos de datos aceptados en C estándar son cinco: char (carácter) int (entero) float (coma flotante en 32 bits) double (coma flotante en 64 bits) void (sin valor)

Las variables pueden ser locales o globales. Las variables locales sólo pueden ser usadas en la función en que se declaran, mientras que las variables globales son compartidas por todas las funciones del programa (deben declararse fuera de cualquier función y antes de ser utilizadas).

1

Fundamentos de Lenguaje C para PICs
El compilador de CCS acepta los siguiente tipos de variable.
Especificación
Los tipos básicos en C

Significado carácter entero coma flotante
float doble precisión

Tamaño 8 bits 8 bits 32 bits no soportado nulo 1 bit 8 bits 16 bits 32 bits 1 bit 16 bits

Rango 0 a 255 (sin signo) 0 a 255 (sin signo) 6 bits de precisión No para PCM ninguno 0a1 0 a 255 (sin signo) 0 a 65535
(sin signo)

char int float double void int1 int8 int16 int32 short long

sin valor entero de 1 bit entero de 8 bits entero de 16 bits entero de 32 bits entero de 1 bit entero de 16 bits

0 a (2 32-1) 0a1 0 a 65535
(sin signo)

Los tipos de variable short y long pueden tener detrás la palabra int sin efecto alguno.

Fundamentos de Lenguaje C para PICs
Todos los tipos de datos son por defecto sin signo (unsigned) salvo los de tipo float. Para almacenar datos con signo, hay que introducir el modificador signed delante del tipo. El efecto que se consigue es el recogido en la siguiente tabla.
Especificación signed char signed int signed long Significado
carácter con signo

Tamaño 8 bits 8 bits 16 bits

Rango -128 a 127 -128 a 127 -32768 a 32767

entero con signo coma flotante

Los números negativos se codifican en complemento a 2. Cuando se opera con distintos grupos de datos en una misma expresión, se aplican una serie de reglas para resolver las diferencias. En general se produce una “promoción” hacia los tipos de datos de mayor longitud presentes en la expresión.

2

return expresión. tipo param2 . Fundamentos de Lenguaje C para PICs La manera que tiene una función para devolver un valor es mediante la sentencia return. } Las funciones pueden devolver un valor a la sentencia que las llama.Fundamentos de Lenguaje C para PICs Funciones Las funciones son los bloques constructivos fundamentales en C. se entiende que devuelve un entero. las funciones terminan su ejecución y vuelven al lugar desde donde se les llamó cuando alcanzan la llave de cierre de función } tras ejecutar la última sentencia de la misma. El tipo de dato devuelto se indica mediante tipo_dato. Si no devuelve nada. se finaliza con return. La expresión debe proporcionar el mismo tipo de dato que el especificado en la función. Todas las sentencias deben encontrarse dentro de funciones. return (expresión). Formato general de definición de una función tipo_dato nombre_func (tipo param1 . Cuando una función se encuentra con una sentencia return se vuelve a la rutina de llamada inmediatamente y las sentencias posteriores a return no se ejecutan. Además de con las sentencia return. … ) { cuerpo de la función (sentencias). debe incluirse una especificación tipo void. Si no se indica nada. Las funciones deben ser definidas antes de ser utilizadas. 3 . Si no debe devolver nada.

23). Se consigue usando punteros o arrays. No modifica su valor en la función de partida. por ejemplo. } c = suma (10 . es más habitual ver a += b. Por ejemplo: int suma (int a . Parámetros formales Argumentos de llamada Los argumentos se pueden pasar a las funciones por valor o por referencia. La llamada por referencia usa la dirección de la variable que se pasa a la función. Operadores aritméticos + * / % (resto de división de enteros) x-ó --x != Operadores incremento y decremento x++ > ó ++x Operadores relacionales >= < <= == Operadores lógicos && || ! ^ XOR a^b (usados en los condicionales) ~ >> Comp1 Dcha ~a a >> n << Izda a << n Operadores a nivel de bits & AND a&b | OR a|b En lenguaje C “profesional” es muy frecuentes usar abreviaturas. } main() { int c.Fundamentos de Lenguaje C para PICs Además de devolver valores. int b) { return (a+b). Así. 4 . que a = a + b. una función también puede recibir parámetros (denominados argumentos) según se indicó en su definición. Fundamentos de Lenguaje C para PICs Operadores El lenguaje C define numerosos operadores mediante los cuales se construyen las expresiones (combinación de operadores y operandos). La llamada por valor copia el argumento de llamada en el parámetro formal de la función.

.Fundamentos de Lenguaje C para PICs Sentencias de control de programa Sentencia if. Se evalúa una expresión y. Si es cero (falso) continúa sin ejecutar la sentencia o bloque de sentencias. Si es falsa. default: } grupo n de sentencias. el cuerpo de sentencias asociadas a esa constante se ejecuta hasta que aparezca break. else sentencia 2. ombin ra n c pa uede p e ls les Se i f -e últip m s io var lecer . se ejecuta el segundo.. ar if (expresión) sentencia 1. case constante 2: grupo 2 de sentencias. si es cierta. Cuando se da una coincidencia. Substituye a if-else cuando se realiza una selección múltiple que compara una expresión con una lista de constantes enteras o caracteres. de la switch encia t n e s . Se ejecuta una sentencia o bloque de código si la expresión que acompaña al if tiene un valor distinto a cero (verdadero). break es opcional. . } Sentencia if-else. n isió b esta s de dec o camin Abreviatura (expresión) ? (sentencia 1) : (sentencia 2). Si no aparece se sigue con el case siguiente. if (expresión) sentencia. Fundamentos de Lenguaje C para PICs Sentencia switch. switch (expresión) { case constante 1: grupo 1 de sentencias. sentencia 2. default es opcional y el bloque asociado se ejecuta sólo si no hay ninguna coincidencia con las constantes especificadas.. 5 . break. se ejecuta el primer bloque de código (o sentencia 1). break. r habe uede es t No p n a onst ase dos c en dos c s le a a m u ig mis . if (expresión) { sentencia 1..

se ejecuta el bucle. Es posible anidar bucles for para modificar dos o más variables de control. La repetición se lleva a cabo mientras sea cierta una expresión.Fundamentos de Lenguaje C para PICs Sentencia de bucle for. se sale del mismo. incremento) { sentencia(s). ya no se ejecuta la sentencia o bloque de sentencias. La condición se evalúa antes de ejecutar la sentencia. } En la inicialización se le asigna un valor inicial a una variable que se emplea para el control de la repetición del bucle. do { sentencia(s). Si es falsa. Sentencia de bucle do-while. El incremento establece cómo cambia la variable de control cada vez que se repite el bucle. condición . 6 . } La expresión se evalúa antes de cualquier iteración. Si es cierta. while (expresión) { sentencia(s). } while (expresión) Las sentencias se ejecutan antes de que se evalúe la expresión. Si no. por lo que el bucle se ejecuta siempre al menos una vez. for (inicialización . Fundamentos de Lenguaje C para PICs Sentencia de bucle while. Se emplea para repetir una sentencia o bloque de sentencias.

Empiezan por /* y finalizan por */.y #BYTE id=x Las líneas entre estas dos directivas deben ser instrucciones ensamblador que se insertan tal y como aparecen. Un comentario se puede colocan en cualquier lugar del programa y pueden tener la longitud y el número de líneas que se quiera. No es posible anidar comentarios con este formato. Al final de esta sección se incluyen sendas listas con las di rectivas y las funciones integradas correspondientes al compilador de CCS. // Esto es un comentario.Fundamentos de Lenguaje C para PICs Comentarios Los comentarios se incluyen en el código fuente para explicar el sentido y la intención del código al que acompañan. Hay dos formatos posibles para los comentarios. /* Esto también es un comentario */ /* Pero esto que /* parece un comentario válido*/ no lo es */ Fundamentos de Lenguaje C para PICs C específico para los PIC Las principales diferencias entre compiladores residen en las directivas (pre-processor commands) y en las funciones integradas (built-in functions). Formato 1. Empiezan por // y finalizan con el final de la línea. Son ignorados por el compilador y no afectan a la longitud ni rapidez de ejecución del código final. Si ya existía esa variable. Se crea una variable tipo bit correspondiente al bit y del byte x en memoria. 7 . Se crea una variable y se sitúa en el byte x en memoria. Formato 2. se coloca físicamente en la posición especificada. Directivas de preprocesado más habituales #ASM #ENDASM #BIT id=x.

Define el micro para el que se escribe el código. 8 . La función que sigue a esta directiva se implementa de manera separada (no INLINE). #PRIORITY ints #USE DELAY (clock = frecuencia en Hz) Define la frecuencia del oscilador que se va a utilizar. #INLINE La función que sigue a esta directiva se copia en memoria de programa cada vez que se le llame. No se incluye código de salvaguarda de registros ni de recuperación como cuando se usa #INT_xxxx. que se emplea para realizar los cálculos para funciones integradas de retardo. De esta manera se ahorra ROM Sitúa el código a partir de una determinada posición de la memoria de programa #SEPARATE #ORG start Fundamentos de Lenguaje C para PICs #INT_xxxx #INT_GLOBAL Indica que la función que sigue es un programa de tratamiento de la interrupción xxxx. Define la palabra de configuración para la grabación del microcontrolador. #USE FAST_IO (puerto) #USE FIXED_IO (puerto) #USE STANDARD_IO (puerto) Indican al compilador cómo debe generar código para las instrucciones de E/S. Puede servir para mejorar la velocidad. Establece un orden de prioridad en las interrupciones.Fundamentos de Lenguaje C para PICs #DEFINE id texto #DEVICE chip #FUSES options El identificador se sustituye por el texto adjunto. Indica que la función que sigue es un programa genérico de tratamiento de interrupción. #INCLUDE <fichero> Se incluye el texto del fichero especificado en el #INCLUDE “fichero” directorio o fuera de él.

Funciones Integradas para Compiladores de CCS (I) Directivas de Preprocesado para compiladores de CCS Fundamentos de Lenguaje C para PICs Fundamentos de Lenguaje C para PICs 9 .

Funciones Integradas para Compiladores de CCS (II) Fundamentos de Lenguaje C para PICs 10 .

PUERTOS DE E/S .

el código que introduce el compilador puede variar en cuanto a tamaño y tiempo de ejecución. * Usando las funciones integradas específicas del compilador. Cuando se usan las funciones integradas del compilador de CCS.#USE FIXED_IO . (0X06 y 0x106) (0X07) (0X08) (0X09) TOTAL 33 pines de E/S Dirección de los datos configurables. * * * * * TRISA TRISB TRISC TRISD TRISE (0x85) (0x86) (0x87) (0x88) (0x89) Puertos de E/S Gestión de los puertos E/S Existen dos opciones para configurar y manejar los puertos E/S * Definiendo los registros como variables localizadas en RAM.#USE STANDARD_IO) Funcionamiento Multiplexado con otros módulos * * * * * PORTA PORTB PORTC PORTD PORTE 6 pines 8 pines 8 pines 8 pines 3 pines (0X05) 1 .Puertos de E/S Características generales en el PIC16F877 Presenta cinco puertos E/S configurables. La primera de las dos opciones indicadas constituye la manera más directa de trabajar con los puertos E/S. Se definen la dirección de datos si es necesario y se gestionan las entradas y las salidas mediante funciones relativas al manejo de todo el puerto o de bits particulares del mismo. Se definen los puertos y los registros de dirección como variables de C y se colocan en las posiciones reales de estos registros en la memoria RAM de datos. Registros de dirección de datos. Dependerá de la activación de ciertas directivas de preprocesado (#USE FAST_IO .

. #BYTE TRISB = 0x86 #BYTE PORTB = 0x06 // Define la variable TRISB y la sitúa en 86h..... Puertos de E/S El compilador de CCS incorpora una serie de funciones integradas que permite manejar los bits de una variable previamente definida. Muestra el bit especificado de la variable.4 .. . if (PORTB & 0xF0) PORTB|= 0x0F. bit). Definiendo los registros en la RAM Definir los registros PORTx y TRISx como bytes y situarlos en las posiciones que les correspondan en el mapa de memoria del PIC.. // Asignación a los 4 bits de salida. #BIT nombre = posición..... 5).. . bit_test (var ... bit). RA4 = 0.... A partir de este punto. // Define la variable PORTB y la sitúa en 06h. 2). estas variables permiten controlar los puertos y se pueden utilizar en sentencias de asignación.. numero = PORTB.bit #BIT RA4 = 0x05. Pone a 1 el bit especificado de la variable. También se puede declarar un bit de un registro con una variable mediante la directiva #BIT y trabajar directamente con la variable. 2)) bit_set (PORTB . 2 . TRISB = 0xF0. . PORTB = 0x0A.Puertos de E/S Opción 1. bit_clear (var . // 4 bits altos entradas y 4 bajos. if (! bit_test (PORTB . .. Intercambia los nibbles de la variable... bit)... #BYTE PORTB = 0x06 // Declaración previa de PORTB. swap (var).. Para ello resulta muy adecuada la directiva #BYTE. bit_set (PORTB . bit_set (var . Pone a 0 el bit especificado de la variable.. salidas. // Lectura del puerto B.

Puertos de E/S
Opción 2. Usando funciones integradas del compilador
El compilador de CCS incorpora una serie de funciones integradas orientadas a trabajar con los puertos E/S. output_low (pin*); output_high (pin*); output_bit (pin* , valor); output_float (pin*); Pone a 0 el pin especificado. Pone a 1 el pin especificado. Pone el pin especificado al valor indicado. Define el pin como entrada, quedando a tensión flotante (simula salida en drenador abierto) Saca el valor indicado (0-255) en el puerto correspondiente.

output_a output_b output_c output_d output_e

(valor); (valor); (valor); (valor); (valor);

port_b_pullups (valor);

Activa (valor=TRUE) o no (valor=FALSE) las resistencias de pull-up asociadas a los pines definidos como entrada en PORTB.

Puertos de E/S
set_tris_a set_tris_b set_tris_c set_tris_d set_tris_e (valor); (valor); (valor); (valor); (valor); Carga el registro de dirección de datos con el valor indicado.

input (pin*); input_a input_b input_c input_d input_e ( ( ( ( ( ); ); ); ); );

Devuelve el estado del pin señalado. Devuelve el valor presente en el puerto correspondiente.

Los parámetros de tipo pin* se corresponden con identificadores definidos en el 16F877.h cuyo formato es PIN_Xn (X es el puerto y n es el número de pin). Ejemplo en 16F877.h #define PIN_A0 40 !! ¡¡OJO #define PIN_A1 41 LES RIAB #define PIN_A2 42 N VA O S #define PIN_A3 43 NO

3

Puertos de E/S
La generación de código para las funciones output_x( ) e input_x( ) depende de la última directiva del tipo #USE *_IO que esté activa. #USE FAST_IO (PUERTO) PUERTO: A , B , C , D , E Cada vez que se emplea una función output...() se saca el valor directamente al puerto, y cada vez que se emplea una función input...() se lee el puerto, pero no se modifican previamente el registro TRIS correspondiente. El usuario debe asegurarse de que los registros TRIS están cargados adecuadamente antes de llamar a las funciones. Ej. #USE FAST_IO (B) #USE STANDARD_IO (PUERTO) PUERTO: A ... E Cada vez que se emplea una función output...() se inserta código previo para forzar a que el bit particular o el puerto completo sean de salida (mediante la carga del TRIS correspondiente). Si se trata de una función input...() se carga código para definir bit o puerto completo como de entrada. Ésta es la opción activa por defecto. Ej. #USE STANDARD_IO (C)

Puertos de E/S
#USE FIXED_IO (PUERTO_OUTPUTS=pin* , ...) PUERTO: A ... E Se genera código relativo a la dirección de los datos de manera previa cada vez que aparece una función integrada del tipo input …( ) ó output…( ), pero los pines se configuran de acuerdo con la información que acompaña a la directiva (sólo se indican los pines de salida) y no dependiendo de que la operación sea de entrada o de salida como sucede con #USE STANDARD_IO(PUERTO) Ej. USE FIXED_IO (B_OUTPUTS = PIN_B2 , PIN_B3)

El efecto de colocar una u otra directiva se puede observar en los ficheros *.lst que se generan como resultado de la compilación. En general se puede decir que resulta más cómodo gestionar los pines de E/S de modo STANDARD, pero haciéndolo de modo FAST se adquiere más control de lo que se le está mandando al PIC y se optimiza código.

4

INTERRUPCIONES

(CCP2IF) #INT_SSP Envío / Recepción de dato serie síncrono. En ese caso. (RBIF) #INT_EXT Flanco en pin RB0. guardar y recuperar el contexto existente antes de producirse la interrupción y poner a cero el flag asociado a la misma para permitir posteriores identificaciones. 3. (ADIF) #INT_TBE Buffer de transmisión USART vacío. En el caso de los PIC 16F877 hay 14 posibles directivas. (CCP1IF) #INT_CCP2 Captura / Comparación en módulo CCP2. el flag asociado se pone a 1 y. se acepta la interrupción. Se almacena la dirección de retorno en la pila. 1. el hardware interno del PIC ejecuta varias acciones. si las máscaras global (GIE) y particular (y en algunos casos la de periféricos (PEIE)) están habilitadas. Interrupciones Las directivas #INT_xxxx Indican que la función que aparece a continuación corresponde al tratamiento de una interrupción (no tiene ni necesita parámetros). (SSPIF) #INT_PSP Dato entrante en puerto esclavo paralelo. (TXIF) #INT_RDA Dato recibido en USART. (BCLIF) #INT_EEPROM Escritura completa en EEPROM de datos. (TMR1IF) #INT_TIMER2 Desbordamiento de TMR2. (RCIF) #INT_TIMER1 Desbordamiento de TMR1. (INTF) #INT_AD Fin de conversión A/D. #INT_RTCC Desbordamiento de TMR0. (EEIF) 1 .Interrupciones Introducción En los 16F877 hay 14 fuentes posibles de interrupción. Estas tareas quedan enormemente simplificadas usando directivas y funciones del lenguaje C del compilador de CCS. Se pone GEIE a cero para no aceptar otra interrupción. (TMR2IF) #INT_CCP1 Captura / Comparación en módulo CCP1. El contador de programa se carga con la dirección 0x0004 (que es la dirección común para todas las interrupci ones). Cuando se da un evento en un determinado módulo. El programador debe asegurarse de que el código se encarga de identificar la fuente de la interrupción. 2. (T0IF) #INT_RB Cambio en los pines RB<4:7>. (PSPIF) #INT_BUSCOL Colisión de bus I2C.

Interrupciones La directiva #INT_DEFAULT Indica que la función que viene a continuación será llamada si se dispara una interrupción y ninguno de los flags está activo. La directiva #INT_GLOBAL Indica que la función que va a continuación sustituye todas las acciones que inserta el compilador al aceptarse una interrupción. Sólo se ejecuta lo que vaya en dicha función. Interrupciones Funciones para gestión de interrupciones El compilador C de CCS incluye algunas funciones integradas destinadas a manejar interrupciones. poniendo a 0 las máscaras relacionadas con la interrupción indicada. El programador debe seguir encargándose de habilitar las interrupciones. nivel es una constante definida en 16F877. disable_interrupts (nivel). Hace la acción contraria a la función anterior. enable_interrupts (nivel). 2 . También genera código para salvar al principio y restituir al final el contexto. y borrará el flag que se activó con la interrupción. Ventajas de usar las directivas de interrupciones El compilador genera el código necesario para saltar a la función que va tras esta directiva en el momento de la interrupción. Las otras sólo activan la máscara particular y el PEIE si es necesario.h y genera el código necesario para activar las máscaras necesarias. Etiquetas de nivel definidas para el 16F877: GLOBAL INT_RTCC INT_RB INT_EXT INT_AD INT_TBE INT_RDA INT_TIMER1 INT_TIMER2 INT_CCP1 INT_CCP2 INT_SSP INT_PSP INT_BUSCOL INT_EEPROM La máscara global (la que hace GIE=1) debe activarse de manera independiente.

/* Si entra una interrupción por flanco de bajada en RB0. Selecciona flanco de subida para activar el flag INTF.} enable_interrupts (INT_EXT). Selecciona flanco de bajada para activar el flag INTF.. // Flag INTF si flanco de bajada. // Habilita máscara global de int. // Desactiva todas las interrupciones.Interrupciones Existe también una función adicional destinada a configurar el flanco activo que genera la interrupción externa (en RB0). // Activa máscara INTE ext_int_edge (H_TO_L)... // Desactiva interrupciones en RB0. 3 . disable_interrupts (GLOBAL). #INT_EXT ext_isr() { . se irá a la función que aparece tras la directiva #INT_EXT */ disable_interrupts (INT_EXT). enable_interrupts (GLOBAL). ext_int_edge (L_TO_H).. ext_int_edge (H_TO_L)..

TEMPORIZADORES MÓDULOS .

Puede activarse o desactivarse. 1:128 para TMR0 / 1:64 para WDT. Temporizador de 8 bits que se pueden leer y escribir. 1 . 1:4 para TMR0/ 1:2 para WDT. Módulos Temporizadores Temporizador TMR0 / WDT Registro OPTION_REG (81h . Temporizador TMR2. Prescaler de 8 bits programable por software. Prescaler programable por software. Temporizador TMR1. TMR2 se incrementa hasta alcanzar el valor de PR2. 1:16 para TMR0 / 1:8 para WDT. Generación de interrupción al desbordarse de FFFFh a 0000h. 1:64 para TMR0 / 1:32 para WDT. Generación de interrupción al desbordarse de FFh a 00h. 1:256 para TMR0 / 1:128 para WDT. 181h) RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0 bit 7 bit 6 bit 5 bit 4 bit 3 RBPU INTEDG T0CS: Selección del reloj a utilizar 0: Reloj interno (fCLK /4) 0: Flanco de subida 1 : Reloj externo (RA4) T0SE: Selección del flanco activo del reloj externo 1 : Flanco de bajada PSA: Asignación del prescaler 0: Asignado a TMR0 1 : Asignado a WDT 1 00: 1 01 : 110: 111: 1:32 para TMR0 / 1:16 para WDT. bits 2:0 PS2:PS0: Prescaler 000: 001: 010: 011 : 1:2 para TMR0 / 1:1 para WDT. Prescaler para el reloj y postscaler para la salida.Módulos Temporizadores Características generales Temporizador TMR0. Contador / Temporizador de 16 bits que se pueden leer y escribir. Contador / Temporizador de 8 bits que se pueden leer y escribir. 1:8 para TMR0 / 1:4 para WDT. Puede activarse o desactivarse. Se puede seleccionar el flanco activo si se usa reloj externo.

CLKOUT (f O S C/4) 0 Bus de datos RA4 / T0CKl T0SE 1 M P X T0CS 1 0 M P X PSA SYNC 2 ciclos 8 TMR0 Levanta flag T0IF al desbordarse 0 1 Watchdog Habilitación de WDT M P X PSA Prescaler de 8 bits 8 Mpx 8:1 0 1 PSA PS2:PS0 MPX Temporización del WDT Módulos Temporizadores TMR0 / WDT en el compilador C de CCS Configuración del módulo TMR0. 2 . setup_timer_0 (modo).Módulos Temporizadores Diagrama de bloques de TMR0 / WDT. modo : RTCC_INTERNAL RTCC_EXT_L_TO_H RTCC_EXT_H_TO_L RTCC_DIV_2 RTCC_DIV_4 RTCC_DIV_8 RTCC_DIV_16 RTCC_DIV_32 RTCC_DIV_64 RTCC_DIV_128 RTCC_DIV_256 (OPTION_REG ← 00h) (OPTION_REG ← 20h) (OPTION_REG ← 30h) (OPTION_REG (OPTION_REG (OPTION_REG (OPTION_REG (OPTION_REG (OPTION_REG (OPTION_REG (OPTION_REG ← 00h) ← 01h) ← 02h) ← 03h) ← 04h) ← 05h) ← 06h) ← 07h) Se pueden agrupar constantes de distintos grupos con | .

NOWDT [opciones] Watchdog activado Watchdog desactivado Módulos Temporizadores Configuración de los módulos TMR0 y WDT (obsoleto). modo : WDT_18MS WDT_36MS WDT_72MS WDT_144MS WDT_288MS WDT_576MS WDT_1152MS WDT_2304MS (OPTION_REG ← 08h) (OPTION_REG ← 09h) (OPTION_REG ← 0Ah) (OPTION_REG ← 0Bh) (OPTION_REG ← 0Ch) (OPTION_REG ← 0Dh) (OPTION_REG ← 0Eh) (OPTION_REG ← 0Fh) Para que el temporizador watchdog pueda llevar a cabo su misión es necesario indicarlo así con la directiva #fuses . Funciones implementadas en el compilador por compatibilidad con versiones anteriores. setup_counters (rtcc . WDT [opciones] [opciones]. No se recomienda su uso. #fuses #fuses [opciones]. 3 .. prescaler)... rtcc: RTCC_INTERNAL RTCC_EXT_L_TO_H RTCC_EXT_H_TO_L RTCC_DIV_2 . setup_wdt (modo ). RTCC_DIV_256 WDT_18MS WDT_36MS WDT_72MS WDT_144MS WDT_288MS WDT_576MS WDT_1152MS WDT_2304MS (OPTION_REG ← 00h) (OPTION_REG ← 20h) (OPTION_REG ← 30h) (OPTION_REG ← 00h) (OPTION_REG ← 07h) (OPTION_REG ← 08h) (OPTION_REG ← 09h) (OPTION_REG ← 0Ah) (OPTION_REG ← 0Bh) (OPTION_REG ← 0Ch) (OPTION_REG ← 0Dh) (OPTION_REG ← 0Eh) (OPTION_REG ← 0Fh) prescaler: ..Módulos Temporizadores Configuración del módulo WDT.

.NOLVP. Activar Activar el el watchdog watchdog para para evitar bucles evitar bucles infinitos. } setup_timer _0 (RTCC_INTERNAL ). valor: Entero de 8 bits.. 4 . infinitos. valor: Entero de 8 bits.NOPROTECT.BROWNOUT. WDT.NOCPD #int_ rtcc rutina() { . 183 TMR0 ← 10110111 while (1) restart_wdt(). f osc = 3MHz Banco 1 W ← OPTION_REG W ← W & 11 000000 OPTION_REG ← W Banco 0 setup_wdt (WDT_72MS).Módulos Temporizadores Escritura en el módulo TMR0. (TMR0 ← valor) Lectura del módulo TMR0. INTCON ← 1 1 100000 TMR0 = 183 (prescaler 1:1) set_timer0 (183). W ← OPTION_REG W ← W & 11000000 W ← W | 00001 01 0 enable_interrupts (INT_RTCC). enable_interrupts (GLOBAL). Configurar Configurar el el módulo módulo TMR0 para generar TMR0 para generar una una interrupción interrupción cada cada 100µs. valor = get_timer0 (). restart_wdt ().NOWRT. 100µs. (valor ← TMR0) Puesta a cero del Watchdog. (equivale a CLRWDT) Módulos Temporizadores Ejemplo #fuses RC. No precisa ningún parámetro. set_timer0 (valor ).PUT.

2. Levanta flag TMR1IF al desbordarse 0 TMR1H TMR1L TMR1ON On/off Entrada de reloj sincronizada 1 RC0 T1OSO T1CKl RC1 T1OSI CCP2 T1OSC 1 T1SYNC 0 TMR1CS T1OSCEN Habilita oscilador fOSC/4 Reloj interno Prescaler 1. 1 : Reloj externo (↑ en RC0).8 T1CKPS1:T1CKPS0 Detección de sincronización Reloj interno 2 5 . bit 3 bit 2 T1OSCEN: Habilitación del oscilador de TMR1 0 : Apagado 1 : Habilitado T1SYNC: Control de la sincronización con el reloj externo Sólo si TMR1CS=1 0: Sincronizar 1 : No sincronizar bit 1 bit 0 TMR1CS: Reloj de TMR1 0: Reloj interno (fOSC /4). 1 0: 11 : Prescaler 1:4. Prescaler 1:2.Módulos Temporizadores Temporizador TMR1 Registro T1CON (10h) T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON bits 5-4 T1CKPS1:T1CKPS0: Selección del prescaler 00: 01 : Prescaler 1:1. Módulos Temporizadores Diagrama de bloques de TMR1. TMR1ON: Bit de encendido de TMR1 0: TMR1 apagado. 1 : TMR1 encendido . Prescaler 1:8.4.

cont++. setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8). set_timer1 (valor ). while (cont<2) { set_timer1 (18661)... 1s.Módulos Temporizadores TMR1 en el compilador C de CCS Configuración del módulo TMR1.. while (get_timer1()>=18661). setup_timer_1 (modo). valor = get_timer1 (). } 6 .. f osc = 3MHz 2 × TMR1 = 18661 (prescaler 1:8) } main () { . temp1s(). modo : T1_DISABLED T1_INTERNAL T1_EXTERNAL T1_EXTERNAL_SYNC T1_CLK_OUT T1_DIV_BY_1 T1_DIV_BY_2 T1_DIV_BY_4 T1_DIV_BY_8 (T1CON (T1CON (T1CON (T1CON ← ← ← ← 00h) 85h) 87h) 83h) (T1CON ← 08h) (T1CON ← 00h) (T1CON ← 10h) (T1CON ← 20h) (T1CON ← 30h) Se pueden agrupar constantes de distintos grupos con | . . valor: Entero de 16 bits.. } Configurar Configurar el el módulo módulo TMR1 para TMR1 para generar generar una una temporización temporización de de 1s.. Módulos Temporizadores Ejemplo temp1s() { unsigned cont=0. Lectura / Escritura en el módulo TMR1. T1CON ← 1011 0101 .

..Módulos Temporizadores Temporizador TMR2 Registro T2CON (12h) TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0 bits 6-3 TOUTPS3:TOUTPS0: Selección del postscaler 0000: 0001 : 0010 : .. 7 .. 16 2 T2CKPS1:T2CKPS0 fOSC/4 Reloj interno Postscaler 1:1 a 1:16 4 T2OUTPS3:T2OUTPS0 = (1) La salida de TMR2 puede ser usada por el módulo SSP. 4 . Levanta flag TMR2IF al desbordarse Salida de TMR2 (1) RESET TMR2 Comparador PR2 Prescaler 1 . 1111: Postscaler 1:1 Postscaler 1:2 Postscaler 1:3 Postscaler 1:16 bit 2 TMR2ON: Bit de encendido de TMR2 0 : Apagado 1 : Habilitado bits 1:0 T2CKPS1:T2CKPS0: Selección del prescaler 00: 01 : 1x: Prescaler 1 Prescaler 4 Prescaler 16 Módulos Temporizadores Diagrama de bloques de TMR2.

valor = get_timer2 (). Módulos Temporizadores Ejemplo #int_timer2 rutina() { . 94 . 8 .. f osc = 3MHz PR2 = 94 (prescaler 1:16) (postscaler 1:5) setup_timer_2 (T2_DIV_BY_16 . setup_timer_2 (modo. Valor del postscaler (1-16). PIE1 ← 0000001 0 INTCON ← 1 1 000000 while (1).postscaler). enable_interrupts (GLOBAL). 5). 10ms. set_timer2 (valor ). Lectura / Escritura en el módulo TMR2.. modo : T2_DISABLED T2_DIV_BY_1 T2_DIV_BY_4 T2_DIV_BY_16 (T2CON ← (T2CON ← (T2CON ← (T2CON ← 00h) 04h) 05h) 06h) periodo : postscaler: Entero de 8 bits (0-255) que se pasa al registro PR2. Postscaler 1:5 Prescaler 1:16 y encendido PR2 = 94 W ← 20h W ← W | 00000110 T2CON ← W W ← 1Ch Banco 1 PR2 ← W Banco 0 enable_interrupts (INT_TIMER2).periodo. valor: Entero de 8 bits.Módulos Temporizadores TMR2 en el compilador C de CCS Configuración del módulo TMR2. } Configurar Configurar el el módulo módulo TMR2 para generar TMR2 para generar una una interrupción interrupción cada cada 10ms.

PERIFÉRICOS DE E/S .

de efecto Hall. +Vcc E0 E1 De este modo. se sabrá que se ha pulsado una tecla y. se sabrá cuál ha sido. de efecto capacitivo. u1 +Vcc SOLUCIONES SOLUCIONES IDEAL u1 R u1 REAL t Hw: Hw: Red Red R-C R-C Biestables Biestables Sw: Sw: Espera Espera de de un un tiempo tiempo suficiente suficiente t Periféricos de E/S Teclados lineales Muy sencillos. se producen oscilaciones en la señal tanto al pulsar como al soltar la tecla.Periféricos de E/S Teclados Muy utilizado para introducir información al microcontrolador. Los hay de varios tipos: de lámina flexible. Los más comunes son los de lámina flexible. además. Debido al efecto muelle del pulsador. 1 . de efecto inductivo. En Basta con que el programa compruebe periódicamente el estado de las entradas a las que se ha conectado el teclado. cuando el microcontrolador detecte un “0” al final de la línea. pero no permiten disponer de muchas teclas. El problema de los rebotes.

+Vcc SF1 SF2 SF3 SF4 E C1 E C2 E C3 E C4 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 S F1 S F2 S F3 S F4 EC1 EC2 EC3 EC4 1 0 1 1 1 1 0 1 Es un método sencillo de implementar. se sabe que se ha pulsado una tecla de la tercera columna. se cambia el valor de las salidas en el microcontrolador de modo que sólo una de ellas valga ‘0’ en cada instante. La combinación que dé lugar a un ‘0’ en alguna de las entradas identificará la tecla que se ha pulsado. pero tardará más o menos en encontrar la tecla pulsada en función de la posición que ocupe ésta. 2 . pero no se sabe cuál. Periféricos de E/S Muestreo secuencial. +Vcc SF1 SF2 SF3 SF4 E C1 E C2 E C3 E C4 0 0 0 0 1 1 1 0 1 La pulsación de una tecla se pone de manifiesto en las entradas del microcontrolador conectadas al teclado. Una vez que se ha detectado que se ha pulsado una tecla.Periféricos de E/S Teclados matriciales Varias teclas controladas con un número reducido de puertos E/S. Se necesita desarrollar algoritmos que permitan determinar cuál es la tecla que se ha pulsada. En este ejemplo.

se almacena el valor que hay en las entradas. se invierten las líneas (las que eran entradas pasan a ser salidas y viceversa) y se saca por las nuevas salidas la combinación almacenada. C1 C2 C3 C4 3 . Como todos los bits son entrada en algún momento.Periféricos de E/S Inversión de línea. Tras detectar que hay una tecla pulsada. se necesita colocar resistencias en los 8 bits. * La existencia de una interrupción asociada a cambios en los bits RB<4:7> avisa de que se ha pulsado una tecla. Periféricos de E/S Conexión de teclados matriciales en los PIC. +Vcc EF1 EF2 EF3 EF4 S C1 S C2 S C3 S C4 1 0 1 1 1 1 1 0 1 Esto dará lugar a que en las nuevas entradas sólo aparezca un cero en la fila a la que pertenece la tecla pulsada. El puerto B de los microcontroladores PIC está especialmente pensado para conectar un teclado matricial de 4×4. Este método es más rápido que el anterior y tarda lo mismo en identificar cualquier tecla. +Vcc pull-up resistors RB0 0 [S] RB1 0 RB2 0 RB3 0 RB4 1 [E] RB5 1 RB6 1 RB7 1 F1 F2 F3 F4 * La posibilidad de habilitar resistencias de pull-up reduce el número de componentes externos.

Control bastante complejo. 4 .Periféricos de E/S Extensión a teclados de más de 16 teclas. Lo más habitual es utilizar un LCD con un driver específico: el HD44780 de Hitachi o compatible. Se puede ampliar el tamaño del teclado sin más que utilizar codificadores y decodificadores. El control directo de los electrodos del LCD casi necesitaría un microcontrolador dedicado exclusivamente a esta tarea. 4 ÷ 16 Teclado Matricial 16 × 16 Periféricos de E/S Pantallas de cristal líquido (LCD) Usado para representar caracteres alfanuméricos. +Vcc SF1 SF2 SF3 SF4 E C1 E C2 E C3 E C4 0 0 0 0 1 1 1 1 Codif 16 ÷ 4 Decodif.

SEG40 Cursor Ejemplo en 5× 8 y 8 caracteres/línea Ejemplo en 5× 10 y 8 caracteres/línea Periféricos de E/S Memoria RAM de pantalla (Display Data RAM: DDRAM) con un total de 80 posiciones × 8 bits/posición. SEG40 HD44780 COM1 .. de los cuales 208 de tamaño 5×8 y 32 de tamaño 5×10.. . En los 8 bits se almacena el código del carácter para un generador de caracteres ROM que dispone de 240 caracteres posibles y 8 posiciones (dobles) para caracteres definibles por el usuario en una memoria CGRAM (caracteres gráficos).. 26 ... . COM11 Cursor SEG1 . ... Dispone de 240 patrones de caracteres almacenados en ROM. .. . ... . Ventana de caracteres visibles (16 posiciones) Display real Registro: 1 2 .. 39 40 Memoria de pantalla para una línea (40 posiciones) Display virtual 5 . . 11 .. .. HD44780 COM1 . .. COM8 SEG1 . .Periféricos de E/S Características del HD44780 Driver para LCD de matriz de puntos para representación de caracteres y símbolos en formato 5× 8 ó 5× 10.. Visibles 1 ó 2 líneas con 16 caracteres/línea.

8.. Display real inicial Periféricos de E/S Interface hardware LCD con driver HD44780 Pines externos.14. Direcciones DDRAM 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 ..3. Tiene un tamaño de 2 líneas × 40 bytes/línea = 80 bytes. 0x40 a 0x67: 40 caracteres de la línea 2.6.9.5V Alimentación Ajuste de Contraste Máximo contraste a VSS Selección de Registro Bits de control Lectura / Escritura (entradas al driver) Enable Bit de Datos menos significativo Bit de Datos Bit de Datos Bit de Datos Bits de datos Bit de Datos (entradas/salidas) Bit de Datos Bit de Datos Bit de Datos más significativo 6 . Direcciones no contiguas entre las líneas 1 y 2.Periféricos de E/S La DDRAM almacena el código de los caracteres que están siendo visualizados o que se encuentran en posiciones no visibles debido a la posición de la ventana de visualización. x: posición horizontal (de 1 a 40). 25 26 27 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 .7..12. y: línea (1 ó 2).10. 65 66 67 Localización en display virtual (x. 1.VSS VDD VEE RS R/W E D0 D1 D2 D3 D4 D5 D6 D7 Masa 2.. 0x00 a 0x27: 40 caracteres de la línea 1.4.5.2.y).13.11.7V a 5.

R/W: R/W: Operación Operación de de lectura lectura (1) (1) oo de de escritura escritura (0). debe permanecer a 0. RS: Se selecciona uno de los dos Registros Internos del LCD. (0). definir interface a 4 u 8 bits. Periféricos de E/S Control del LCD E: Señal de validación de datos. IR (Registro de Instrucciones). 7 . etc. pero es posible leer la RAM y el estado del LCD (ocupado o disponible) y el contador de direcciones. datos.Periféricos de E/S DATOS DATOS CONTROL Internos Internos El El LCD LCD trabaja trabaja con con 8 8 bits bits MCU DATOS LCD Externos Externos Hay Hay dos dos posibilidades: posibilidades: •• 8 8 bits bits (D7 (D7 a a D0) D0) •• 4 bits (D7 a 4 bits (D7 a D4) D4) 1º 1ºlos los4 4bits bitsmás másaltos altos 2º 2ºlos los4 4bits bitsmás másbajos bajos BITS BITS DE DE CONTROL CONTROL E: E: Validación Validación de de datos. Almacena códigos de instrucciones relativas al manejo del display: borrar display. En las transferencias de información con el LCD (lecturas o escrituras) se debe poner a 1. Almacena datos a leer o escribir en RAM. RS: RS: Selección Selección de de Registro Registro Interno Interno (1: (1: datos datos // 0: 0: control). control). DR (Registro de Datos). Si no se usa el LCD. desplazar cursor. R/W: Selecciona lectura (1) o escritura (0) en el LCD. Lo normal es escribir en el LCD.

3. AC: Periféricos de E/S Secuencias de operación Escritura en un Registro del LCD 1. 2. Si está a 1. 5. el LCD está en modo de operación interna y no puede procesar nuevos comandos hasta que se pone a 0. 4. E←0 RS ← 0 ó 1 y R/W ← 0 E←1 Situar dato en el bus E←0 Lectura de un Registro del LCD 1. 4. 3.Periféricos de E/S Operaciones de control en el LCD RS=0 (Registro de Control) R/W=1 R/W=0 Leer flag de ocupado (BF) y puntero de direcciones (AC) Envío de comando para funcionamiento interno RS=1 (Registro de Datos) Leer contenido de DDRAM o CGRAM Escribir en DDRAM o CGRAM BF: Busy Flag o Flag de Ocupado. 5. El puntero se incrementa o se decrementa (según el modo elegido) de manera automática. 2. Address Counter o Contador de Direcciones. E←0 RS ← 0 ó 1 y R/W ← 1 E←1 Leer dato del bus E←0 8 . Es el puntero de la dirección DDRAM o CGRAM a la que se accedería con un comando de lectura o escritura a RAM.

2) . Control de Display.1) 0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0A 0B 0C 0D 0E 0F 1 0 1 1 1 2 1 3 1 4 . (1.2) 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 4A 4B 4C 4D 4E 4F 5 0 5 1 5 2 5 3 5 4 (16. pero no aparecerá nada en pantalla. 25 26 27 (1. Si C=1. Para volver a visualizar normalmente los caracteres de la DDRAM hay que poner D=1. Si S=1. No se modifica el contenido de la DDRAM Periféricos de E/S Modo de Funcionamiento: 0 0 0 0 0 1 I/D S El bit I/D especifica incremento y desplazamiento del cursor a la derecha (I/D=1 ) o decremento y desplazamiento del cursor a la izquierda (I/D=0 ) tras realizar una lectura o escritura en DDRAM. el LCD no muestra nada pero la DDRAM mantiene su contenido.. Cursor y Parpadeo: 0 0 0 0 1 D C B Si D=0.Periféricos de E/S Descripción de los comandos Borrar Display: 0 0 0 0 0 0 0 1 Borra todas las posiciones de la DDRAM y sitúa el display real en la posición inicial. Si B=1.1) (16.. se desplaza el display real cada vez que se imprime un carácter. el carácter situado en la posición del cursor parpadea con una frecuencia aproximada de 2Hz. se hace visible el cursor que indica la siguiente posición donde se imprimiría el siguiente carácter que se envíe.. Este comando envía el cursor a la posición (1. 9 . Además sitúa el puntero en la posición 0 de la DDRAM.1) (puntero en 0x00) y el display real se sitúa en la posición inicial.. Se pueden enviar y leer datos normalmente. 65 66 67 Cursor a “Casa”: 0 0 0 0 0 0 1 x El cursor es un indicador de la posición que se puede escribir a continuación en el LCD. Indica la posición actual del puntero de direcciones. El desplazamiento será a la izquierda o a la derecha según el valor de I/D.

al llegar a la posición final (carácter 40º) se volvería a la primera con un desplazamiento del cursor. Si se desplaza el display real (S/C=1). será de 4 bits. se gestionan dos líneas. Si DL=1. tras el 40º carácter de la primera línea se pasaría al principio de la segunda línea. Leer Contenido de DDRAM Se lee el contenido de la posición DDRAM a la que apunte el contador de direcciones. Transferencia y Representación: 0 0 1 DL N F x x El bit DL define el tamaño del interface de datos externo. Si el display está definido para 2 líneas. Periféricos de E/S Situar Puntero en DDRAM: 1 A6 A5 A4 A3 A2 A1 A0 A6-A0 válidas de 0x00 a 0x27 para la primera línea A6-A0 válidas de 0x40 a 0x67 para la segunda línea Leer Flag de Ocupado y Puntero de Direcciones Con la combinación adecuada en RS y R/W las líneas de datos del LCD pasan a ser salidas y en el puerto del MCU se puede leer el estado del BF (bit 7) y la dirección actual del contador (bits 6 a 0). si F=0. se tendrá una única línea activa en el display. Tras la lectura. Si el display se define de una línea. no cambia el puntero de direcciones de la DDRAM. Si F=1. si N=0.Periféricos de E/S Desplazar Cursor / Display: 0 0 0 1 S/C R/L x x Se emplea para desplazar una posición a la derecha (R/L=1 ) o a la izquierda (R/L=0 ) el cursor o el display real sin escribir o leer la DDRAM. son de 5×8 puntos. 10 . también se modifica el contador de direcciones. Si N=1. se emplean patrones de tamaño 5× 10. este contador se incrementa o decrementa dependiendo del modo configurado con I/D. será de 8 bits y si DL=0. Si lo que se desplaza es el cursor (S/C=0 ). Enviar Datos a DDRAM Se carga la dirección de la DDRAM a la que esté apuntando el contador de direcciones y éste se incrementa o decrementa dependiendo del estado configurado con I/D.

Recuérdese que la primera posición de la primera línea tiene coordenadas (1 . 2). Debe llamarse antes que ninguna otra función del fichero lcd.) F=0 (5× 8 puntos) B=0 (sin parpadeo) Durante todo el proceso de inicialización se tiene BF=1. con dos líneas y con caracteres de 5 ×8 puntos. DL=1 (8 bits) D=0 (display off) I/D=1 (incremento) N=0 (1 línea) C=0 (cursor off) S=0 (sin desplaz. y que la primera posición de la segunda línea es la (1 . Esto puede asegurare de dos modos: a) Esperar a que el Flag de Ocupado (BF) pase a 0. Establece la posición del LCD a la que se debe acceder.c que define las funciones indicadas a continuación. configura el LCD para trabajar como sigue: a) En formato de 4 bits. 1). Tal y como aparece en el fichero.5V y dura unos 10ms. además de borrar el display. es necesario que se haya finalizado el anterior. lcd_gotoxy (x . cursor apagado y sin parpadeo. Periféricos de E/S LCD en el compilador C de CCS El compilador C de CCS incluye un driver para manejar LCDs: el fichero lcd. En el encendido se produce un reset de inicialización con varios efectos preestablecidos. b) Establecer pausas entre comandos que sean superiores a los tiempos máximos especificados para cada comando. c) Con autoincremento del puntero de direcciones y sin desplazamiento del display real.Periféricos de E/S Procesado de los comandos El LCD precisa de un cierto tiempo para procesar los comandos que se le van enviando. 11 .c. y ). lcd_init (). Se produce tras superar los 4. Para que se ejecute un determinado comando. b) Con display encendido.

Devuelve el carácter que ocupa la posición (x .9 Indica cuántos decimales se han de mostrar t: c s u xóX d % Carácter Cadena o carácter Entero sin signo Entero hexadecimal Entero con signo Simplemente un ‘%’ e f lu lx ó lX ld Flotante (formato exp) Flotante Entero largo sin signo Entero largo hexadecimal Entero largo con signo 12 . donde w es opcional. La variable dato es de tipo char. Por defecto.1-9. se usa el formato %wt. y se definen algunos caracteres especiales: \f Borra el display \n Se posiciona en el inicio de la segunda línea \b Retrocede una posición lcd_getc (x . Para indicar la posición y el tipo de las variables a incluir en la cadena. vars: Variables incluidas en la cadena (separadas por comas). cadena: Cadena de caracteres que puede formarse usando el contenido de una o más variables. B0 Enable B4 Bit de datos D4 B1 RS B5 Bit de datos D5 B2 R/W B6 Bit de datos D6 B3 B7 Bit de datos D7 Periféricos de E/S También es posible escribir en el LCD usando la siguiente función.Periféricos de E/S lcd_putc (dato). este driver usa siete bits del puerto B para establecer la comunicación entre el LCD y el microcontrolador. w: 1-9 Indica el número de caracteres a mostrar (opcional) 01-09 Indica el número de ceros a la izquierda 1.cadena . y) del LCD. printf(lcd_putc.vars). Escribe dato en la posición a la que apunta el puntero de direcciones. y ).

c está pensado para manejar un LCD usando 4 bits de datos externos al interface. cont ). ”Tecla %c pulsada %u veces” .Periféricos de E/S Algunos ejemplos.c de CCS. key . Especificador %03u %u %2u %3u %d %x %X %4X Valor=18 018 18 18 _18 _18 12 12 0012 Valor=254 254 254 ??? 254 -2 fe FE 00FE NOTA: Sólo se puede visualizar enteros y caracteres en el LCD. 13 . La inicialización que por defecto lleva a cabo este driver también puede modificarse sin más que cambiar un par de líneas del mismo. NOTA El compilador de CCS no admite salida formateada de flotantes. Periféricos de E/S La comunicación entre el microcontrolador y el LCD se lleva a cabo mediante 7 bits del Puerto B usando el driver lcd. Ejemplos de formato. printf(lcd_putc . Este hecho haría que la conexión de un LCD fuera incompatible con la conexión típica de un teclado matricial 4×4. El driver lcd. Sería posible adaptarlo para que usara 8 bits. printf(lcd_putc .c que se facilita con este curso lleva a cabo las modificaciones necesarias. El driver lcd_ATE. En concreto hay que cambiar 3 ó 4 valores que se hacen llegar al LCD como comando. ”Hola”).

Periféricos de E/S Para evitar conflicto con la conexión de teclados matriciales. 0x20 0 0 1 0 0 0 0 0 Transferencia y Representación 0 0 1 DL N F x x DL → Nº bits de datos N → Nº líneas F → Nº ptos/carácter 0 0 1 0 1 0 0 0 lcd_type << 2 0 0 0 0 0 1 0 1 0 1 0 14 . 0xc. 1=5x10. #if defined (__PCH__) #byte lcd = 0xF81 #else #byte lcd = 6 #endif // This puts the entire structure // on to port B (at address 6 ) #if defined (__PCH__) #byte lcd = 0xF83 #else #byte lcd = 8 #endif // This puts the entire structure // on to port D (at address 8 ) Periféricos de E/S #define lcd_type 2 // 0=5x7. 6}. 1. haremos que el LCD se comunique con el microcontrolador mediante el puerto D (ubicado en la dirección 08h) en lugar de hacerlo a través del puerto B. // These bytes need to be sent to the LCD // to start it up. 2=2 lines #define lcd_line_two 0x40 // LCD RAM address for the second line byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2).

/ Decrem. Resto bits → int otros : 4.c. 0xc. S → Shift display on/off Periféricos de E/S El driver lcd_ATE. de datos #byte lcd_control = 5 #byte trisa = = 0x85 #byte lcd_datos = 8 #byte trisd = 0x88 PORTA PORTD 15 .Periféricos de E/S #define lcd_type 2 // 0=5x7. // These bytes need to be sent to the LCD // to start it up. } lcd_control. 6}. Bit 2 → boolean rw. struct lcd_pines_datos { int datos:8. Bit 3 → boolean enable. también en este caso es posible cambiar la asignación de los pines. ã 8 bits } lcd_datos. Como sucede con el driver lcd.c lleva a cabo una comunicación con el LCD usando 8 bits de datos. 1=5x10. 0xc 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 6 Control del Display y del Cursor 0 0 0 0 1 D C B D → Display on/off C → Cursor on/off B → Parpadeo on/off Modo de Funcionamiento 0 0 0 0 0 1 I/D S I/D → Increm. 1. Bit 1 → boolean rs. 2=2 lines #define lcd_line_two 0x40 // LCD RAM address for the second line byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2). En su versión original las líneas usadas son: RA1=RS – RA2=R/W – RA3=E RD<0:7>=D0÷ D7 struct lcd_pines_control { Bit 0 → boolean nada.

0 1 D C B Display 0 0 1 I/D S El driver lcd_ATE.0b00001100). lcd_send_byte(0. // // // // Se Se Se Se envía envía envía envía 0 0 1 0 0 0 Clear 0 0 0 DL N F .Periféricos de E/S Es posible cambiar los bits de configuración para conseguir que el LCD se comporte como desea el usuario.0b00111000). Borra la línea 'line' y sitúa el cursor en la primera posición de dicha línea. Lo único que es obligatorio respetar es el bit DL=1 (comunicación a 8 bits) lcd_send_byte(0. Avanza el cursor una posición.0b00000110). lcd_putc(\v). Retrocede el display real una posición. 16 . lcd_putc(\r).0b00000001).c define alguna función que no se recoge en el driver lcd. lcd_send_byte(0. // // // // // lcd_putc(\t). Avanza el display real una posición.c suministrado por CCS. lcd_send_byte(0. lcd_clr_line(line).

MÓDULOS DE COMPARACIÓN CAPTURA Y PWM .

Acción especial: Generada mediante una comparación. Acción especial: Generada mediante una comparación. Módulo CCP1. que borra TMR1 La(s) comparación(es) deben configurarse con la acción especial. Registro de comparación de 16 bits. Modo captura ⇒ Modo comparación ⇒ PWM ⇒ TMR1 TMR1 TMR2 Interacción entre los dos módulos CCP. Registro de ciclo de trabajo PWM. Módulos CCP Condiciones de funcionamiento Temporizadores necesarios. Resetea Timer1. CCPx Captura Captura CCPy Captura Comparación Interacción Misma base de tiempos definida en TMR1 La comparación debe configurarse con la acción especial. Módulo CCP2.Módulos CCP Características generales Dos módulos con idéntico funcionamiento. Registro de control: CCP1CON. Lanza una conversión A/D. que borra TMR1 Las PWMs tendrán la misma frecuencia y tasa de actualización (interrupción TMR2) Ninguna Comparación Comparación PWM PWM PWM PWM Captura Comparación Ninguna 1 . Consta de dos registros de 8 bits: CCPR1H y CCPR1L. Consta de dos registros de 8 bits: CCPR2H y CCPR2L. Registro de captura de 16 bits. Registro de control: CCP2CON. Resetea Timer1.

Módulos CCP Registro CCP1CON / CCP2CON (17h / 1Dh) CCPxX CCPxY CCPxM3 CCPxM2 CCPxM1 CCPxM0 bit 5-4 CCPxX:CCPxY: Bits menos significativos del PWM En modo PWM: Los dos bits menos significativos del ciclo de trabajo. 4 . captura. 16 Detección de flanco y CCPxIF ← 1 CCPRxH CCPRxL Habilita Captura TMR1H TMR1L Qs CCPxCON<3:0> 2 . genera interrupción al igualarse (CCPx invariable. CCPx=0 al igualarse (CCPxIF=1) 1010 = Modo de comparación. CCPx=1 al igualarse (CCPxIF=1) 1001 = Modo de comparación. lanza acción especial (CCPxIF=1. Cada flanco de bajada en CCPx gar a Cada flanco de subida en CCPx da lu tura p a c Cada 4º flanco de subida en CCPx Cada Cada 16º flanco de subida en CCPx Diagrama de bloques del modo de captura. CCPxIF=1) 1011 = Modo de comparación. bit 3-0 CCPxM3:CCPxM0: Bits de selección del modo CCP a utilizar 0000 = Comparación/Captura/PWM desactivada (reset del módulo CCP) 0100 0101 0110 0111 = = = = Modo Modo Modo Modo de de de de captura. captura. CCPx invariable) CCP1 resetea TMR1 / CCP2 resetea TMR1 y lanza una conversión A/D 11xx = Modo PWM Módulos CCP Modo captura Captura en CCPRxH:CCPRxL los 16 bits de TMR1. RCy / CCPx IF=1 CCPx Prescaler ÷ 1 . Los ocho bits más significativos están en CCPRxL. captura. cada cada cada cada flanco descendente flanco ascendente 4º flanco ascendente 16º flanco ascendente 1000 = Modo de comparación.

Tambi én podría generarse una falsa interrupción al cambiar el prescaler. TMR1 ← 0 (no alza flag TMR1F) GO/DONE ← 1 Lanza acción especial CCPxIF ← 1 RCy / CCPx CCPRxH CCPRxL Q TRISC<2> S R Lógica de salida Coincidencia Comparador TMR1H TMR1L CCPxCON<3:0> 3 . Módulos CCP Modo comparación Cuando CCPRx coincide con TMR1 (en sus 16 bits): El pin RCy/CCPx se pone a 1 gar a da lu El pin RCy/CCPx se pone a 0 encia id c in 1 co IF= Se genera una interrupción Cada CCPx Lanza una acción especial Diagrama de bloques del modo comparación. Se evitan estas situaciones reseteando el módulo CCP (CCPxCON ← 0) antes de llevar a cabo un cambio de modo y/o un cambio de prescaler. Podría generarse una falsa interrupción de captura al cambiar el modo de captura. Además. Se aconseja deshabilitar CCPxIE al cambiar el modo de captura.Módulos CCP Condiciones de funcionamiento en el modo captura El pin CCPx debe configurarse como entrada. TMR1 debe funcionar en modo temporizador o en modo contador síncrono. En modo contador asíncrono puede que la captura no funcione. un cambio directo no resetea la cuenta de flancos.

En ningún ca so se pone a 0 el flag TM R1 IF CCP1: Resetea TMR1. En modo contador asíncrono puede que la comparación no funcione. CCP2: Resetea TMR1 y lanza una conversión A/D (si está activado). el pin CCPx no se ve afectado. Cuando se selecciona generar interrupción. Registros de Duty Cycle TMR2 = 0 TMR2 = D CCPRxL CCPxCON<5:4> CCPRxH (esclavo) Comparador TMR2 (*) R S Q RCy / CCPx TRISC<2> (*) TMR2 se concatena con un reloj interno de 2 bits con frecuencia fosc para poder crear una base de tiempos de 10 bits Comparador PR2 TMR2 ← 0 CCPx ← 1 (si D ≠ 0) CCPRxH ← CCPRxL 4 .Módulos CCP Condiciones de funcionamiento en el modo comparación El pin CCPx debe configurarse como salida. Se puede generar una acción especial por hardware. Módulos CCP Modo PWM Genera una salida PWM de 10 bits de resolución D TMR2 = PR2 T Diagrama de bloques del modo PWM. TMR1 debe funcionar en modo temporizador o en modo contador síncrono.

(T2CON) 5 . Establecer el ciclo de trabajo D en CCPRxL y en CCPxCON<5:4>.   f osc  log f  ⋅ PS  PWM TMR 2  Res = log(2) bits que bits ir o de in úmer para def n o Máxim den usar abajo. Configurar el módulo CCP para funcionar en modo PWM.53kHz 78. 2. D = (CCPRxL:CCPxCON<5:4>) · TOSC · PRESCALER TMR2 CCPRxH es de sólo lectura en PWM.3kHz 1 0xFFh 10 bits 1 0x3Fh 8 bits 1 0x1Fh 7 bits 1 0x17h 5.12kHz 156.5 bits (f osc = 20MHz) Pasos a seguir para definir una PWM 1.88kHz 4 0xFFh 10 bits 19. CCPx ← 0.Módulos CCP Condiciones de funcionamiento en el modo PWM El periodo T se indica en el registro PR2. 3. Establecer el periodo T escribiendo en el registro PR2. Configurar el pin CCPx como salida. 4.3kHz 208.22kHz 16 0xFFh 10 bits 4. Fijar el prescaler de TMR2 y activar el temporizador. Cuando TMR2 (+ 2 bits) se iguala a CCPxH (+ 2 bits). Existe una resolución (número de bits) máxima que se puede obtener con el funcionamiento en modo PWM. T = (PR2 + 1) · 4 · TOSC · PRESCALERTMR2 El ciclo de trabajo D se indica en CCPRxL y en CCPxCON<5:4>. 5. r e se pu ciclo de t el Módulos CCP f PWM PRESCALERTMR2 PR2 Resolución máxima 1.

set_pwm2_ duty (valor ). #byte CCP_2 = 0x15 #byte CCP_2_LOW = 0x15 #byte CCP_2_HIGH = 0x16 6 . valor:Dato (8 ó 16 bits) que fija el duty cycle de la PWM.Módulos CCP Módulos CCP en el compilador C de CCS Configuración del módulo CCP setup_ccp1 (modo). valor XXXXXXXX Y Y Y Y Y YXXXXXXXXXX CCPRxL:CCPxCON<5:4> XXXXXXXX 0 0 XXXXXXXXXX Variables definidas en 16F877.h long CCP_1. (CCPxCON ← 00h) (CCPxCON (CCPxCON (CCPxCON (CCPxCON ← ← ← ← 04h) 05h) 06h) 07h) (CCPxCON ← 08h) (CCPxCON ← 09h) (CCPxCON ← 0Ah) (CCPxCON ← 0Bh) (CCPxCON ← 0Ch) (CCPxCON ← 1Ch) (CCPxCON ← 2Ch) (CCPxCON ← 3Ch) Módulos CCP Definición del ciclo de trabajo en modo PWM set_pwm1_ duty (valor ). modo : CCP_OFF CCP_CAPTURE_FE CCP_CAPTURE_RE CCP_CAPTURE_DIV_4 CCP_CAPTURE_DIV_16 CCP_COMPARE_SET_ON_MATCH CCP_COMPARE_CLR_ON_MATCH CCP_COMPARE_INT CCP_COMPARE_RESET_TIMER CCP_PWM CCP_PWM_PLUS_1 CCP_PWM_PLUS_2 CCP_PWM_PLUS_3 setup_ccp2 (modo). #byte CCP_1 = 0x15 #byte CCP_1_LOW = 0x15 #byte CCP_1_HIGH = 0x16 long CCP_2.

se tomará Para uso con los módulos postscaler = 1 7 . Módulos CCP Configuración del temporizador TMR2 setup_timer_2 (modo. modo : T1_DISABLED T1_INTERNAL T1_EXTERNAL T1_EXTERNAL_SYNC T1_CLK_OUT Def in pre e el sca ler (T1CON (T1CON (T1CON (T1CON ← ← ← ← 00h) 85h) 87h) 83h) (T1CON ← 08h) (T1CON ← 00h) (T1CON ← 10h) (T1CON ← 20h) (T1CON ← 30h) T1_DIV_BY_1 T1_DIV_BY_2 T1_DIV_BY_4 T1_DIV_BY_8 Se pueden agrupar constantes de distintos grupos con | .Módulos CCP Configuración del pin CCPy como entrada/salida set_tris_C (valor ).postscaler). (“1”⇒E / “0”⇒S) Configuración del temporizador TMR1 setup_timer_1 (modo). CCP. cada uno de los cuales representa la la configuración de un pin del puerto. Es un valor entre 1 y 16. valor: Entero de 8 bits.periodo. modo : Def in pre e el sca ler T2_DISABLED T2_DIV_BY_1 T2_DIV_BY_4 T2_DIV_BY_16 PR2 ← periodo (T2CON (T2CON (T2CON (T2CON ← ← ← ← 00h) 04h) 05h) 06h) periodo: postscaler: Número de overflows necesarios para generar una interrupción.

01 001 01 1 CCPR1L 01 CCP1CON<5:4> Módulos CCP Ejemplo 1 (cont. 1). 224 .) setup_timer_2 (T2_DIV_BY_1 . 224 . 300µs 224 100µs W ← 00000000 W ← W | 00000100 T2CON ← W W ← E0h Banco 1 PR2 ← W Banco 0 (f osc = 3MHz) setup_ccp1 (CCP_PWM_PLUS_1). 4Bh 8 . siempre siempre borra borra el el registro registro CCPxCON CCPxCON setup_ccp1 (CCP_PWM). (modo).Módulos CCP Ejemplo 1 setup_timer_2 (T2_DIV_BY_1 . W ← 00000000 W ← W | 00000100 T2CON ← W W ← E0h Banco 1 PR2 ← W Banco 0 RC2 ← 0 CCP1CON ← 0 W ← 00001100 CCP1CON ← W CCPR1L ← 01001011 W ← CCP1CON W ← W & 11 00 1111 W ← W | 00010000 CCP1CON ← W 224 ¡¡ATENCIÓN!! ¡¡ATENCIÓN!! La La instrucción instrucción setup_ccpx setup_ccpx (modo). #use fast_io (C) set_pwm1_ duty (301). 1). #use standard_io (C) W ← 111111 011 Banco 1 TRISC ← W Banco 0 RC2 ← 0 CCP1CON ← 0 W ← 00011100 CCP1CON ← W CCPR1L ← 01001011 T = 300µs ⇒ PR2 = 224 D = 100µs ⇒ carga = 301 Carga = 301 01 001 01 1 01 set_pwm1_ duty (0x4B).

750 W ← 02h CCPR2H ← W W ← EEh CCPR2L ← W setup_ccp2 (CCP_COMPARE_RESET_TIMER). CCP2CON ← 0 W ← 00001011 CCP2CON ← W 9 .Módulos CCP Ejemplo 2 setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1). TMR1H ← 0 TMR1L ← 0 CCP2 = 750. 1ms. W ← 100001 01 T1 CON ← W Configurar Configurar uno uno de de los los módulos módulos CCP CCP para para lanzar lanzar de de manera manera automática automática una una conversión conversión A/D A/D cada cada 1ms. f osc = 3MHz TMR1 = 750 (sin prescaler) set_timer1 (0).

MÓDULO DE CONVERSIÓN A/D .

Sistema Sistema (Analógico) (Analógico) A/D A/D D/A D/A Control Control (digital) (digital) Circuitos de Conversión A/D y D/A Conversión A/D Permite hacer llegar al controlador digital la información suministrada por el proceso analógico que se desea controlar. tiene una banda de frecuencia en la que fm es la mayor frecuencia. Si una señal continua. 1 .Circuitos de Conversión A/D y D/A Pieza fundamental en muchos sistemas de medida y control desarrollados mediante sistemas mixtos analógico-digitales. dicha señal podrá reconstruirse sin distorsión a partir de muestras de la señal tomadas a una frecuencia de valor fs > 2·fm. S(t). Establecen una relación biunívoca entre el valor de la señal en su entrada y la palabra digital obtenida en su salida La conversión A/D tiene se fundamenta en la teoría de muestreo.

Útil sólo en casos de baja resolución. durante el tiempo que dura la transformación A/D propiamente dicha. generalmente en un condensador.Convertidor de alta velocidad. Muestrean la señal analógica (durante un intervalo de tiempo) y mantienen ese valor. Ve C Vs C/M Ve S&H Vs C/M Circuitos de Conversión A/D y D/A Tipos de convertidores A/D Convertidor A/D directo VREF R ue S/H . Para N bits se necesitan 2·N-1 comparadores (complejidad y coste excesivos). . Tiempo de conversión igual a la suma de los tiempos de propagación en el comparador y el codificador. 4÷ 2 E3 R E2 E1 E0 Q1 A1 A0 Q0  2N ⋅ ue  E   VREF  R Vcc 2 . R Codif.Circuitos de Conversión A/D y D/A Circuitos de captura y mantenimiento Denominados S/H: Sample and hold.

. Adapt. Se van eliminando mitades de tabla hasta quedarse con el valor que más se aproxima a la tensión analógica a convertir.5V) 2. Captura µP Selección 3 .2 → mitad superior a) Prueba con 1011 (⇒3.125 < 3. 5V 0V 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 Sea ue=3.Por paso intermedio a frecuencia.De simple rampa.4375V) 3.De doble rampa.2V 1) Prueba con 1000 (⇒2. Adapt.125V) 3.75 > 3.5 < 3.2 → mitad superior 2) Prueba con 1100 (⇒3.Circuitos de Conversión A/D y D/A Convertidor A/D por aproximaciones sucesivas Es el implementado en los microcontroladores PIC. Fin conversión S&H A/D Inicio conversión Sistema Captad. Circuitería adicional Mpx analógico Captad.4375 > 3.75V) 3. Captad.2 → mitad inferior a) Prueba con 1010 (⇒3. Adapt. El proceso siempre acaba tras N pasos.2 → valor inferior Circuitos de Conversión A/D y D/A Otros convertidores A/D indirectos . .

abierto Ai = “1” → Int. Adapt. Adapt. Actuad. D/A µP Inicio conversión Sistema Retenc. Actuad. Adapt.Circuitos de Conversión A/D y D/A Conversión D/A No incluido en los microcontroladores PIC. Retenc. Actuad. Selección 4 . Deben generar una tensión de salida según la siguiente expresión: us = VREF ⋅ A0 + A1 ⋅ 21 + L + AN -1 ⋅ 2N −1 2N VREF 2 N-1 ·R i1 ( ) Ejemplo: Red 2N ·R 2 N·R Ai = “0” → Int. cerrado i0 2 1 ·R iN-1 R A N-1 i +ucc A0 A1 us V -N 1-N -1 / ⋅ ∑ N REF u s = −R ⋅ i = − R ⋅ Ak = −VREF ⋅ A0 ⋅ 2 + A1 ⋅ 2 + L + AN -1 ⋅ 2 -k ⋅R / k =0 2 N -1 ( ) -ucc Circuitos de Conversión A/D y D/A Circuitería adicional Dmpx analógico Fin conversión Retenc.

Posibilidad de seguir funcionando cuando el PIC está en modo SLEEP. Hay 11 registros asociados a este periférico.PIE1 .ADRESH .ADRESL El Módulo de Conversión A/D de los PIC Estructura interna RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA5/AN4 RE0/AN5 RE1/AN6 RE2/AN7 000 001 010 011 100 101 110 111 CHS2:CHS0 Convertidor A/D VAIN (Input Voltage) PCFG3:PCFG0 VDD VREF+ PCFG3:PCFG0 VREF VS S 1 . Cinco pines E/S de PORTA y los tres de PORTE. Convierte la señal analógica en un número digital de 10 bits.ADCON1 .PORTA .PIR1 TRISA . Puede ser VDD o la tensión aplicada en los pines RA2 y/o RA3. Tensión de referencia seleccionable por software. Definición de pines de entrada Manejo de interrupciones INTCON .El Módulo de Conversión A/D de los PIC Características generales en el PIC16F877 Ocho canales de conversión.PORTE Control del conversor A/D ADCON0 .TRISE .

El Módulo de Conversión A/D de los PIC Registro ADCON0 (1Fh) ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE ADON bit 7-6 ADCS1:ADCS0: Selección del reloj para la conversión A/D 00 = fOSC / 2 01 = fOSC / 8 10 = fOSC / 32 11 = fRC bit 5-3 CHS2:CHS0: Selección del canal de conversión 000 = Canal 0 100 = Canal 4 001 = Canal 1 101 = Canal 5 010 = Canal 2 110 = Canal 6 011 = Canal 3 111 = Canal 7 bit 2 GO/DONE: Estado de la conversión Si ADON=1: 1 = Conversión en progreso 0 = Conversión finalizada bit 0 ADON: Bit de encendido del convertidor A/D 1 = Módulo A/D encendido 0 = Módulo A/D apagado El Módulo de Conversión A/D de los PIC Registro ADCON1 (9Fh) ADFM PCFG3 PCFG2 PCFG1 PCFG0 bit 7 ADFM: Selección de formato del resultado 1 = Ajuste a la derecha 0 = Ajuste a la izquierda bit 3-0 PCFG3:PCFG0: Configuración de las entradas al módulo A/D PCFG3: AN7 PCFG0 RE2 0000 0001 0010 0011 0100 0101 011x 1000 1001 1010 1011 1100 1101 1110 1111 A A D D D D D A D D D D D D D AN6 RE1 A A D D D D D A D D D D D D D AN5 RE0 A A D D D D D A A A A D D D D AN4 RA5 A A A A D D D A A A A A D D D AN3 RA3 A V REF+ A V REF+ A V REF+ D V REF+ A V REF+ V REF+ V REF+ V REF+ D V REF+ AN2 RA2 A A A A D D D AN1 RA1 A A A A A A D A A A A A A D D AN0 RA0 A A A A A A D A A A A A A A A V REFA A V REFV REFV REFD V REF- 2 .

Esperar a que transcurra el tiempo de adquisición. .Habilitar la interrupción del convertidor A/D. (ADCON0) . Configurar la interrupción por conversión A/D. . (PIR1) . (ADCON0) . 0 = Conversión A/D aún no completada. 8Bh . . .Los valores típicos del tiempo de adquisición son del orden de 20µs. (ADCON0) 2. .Tiempo necesario para capturar el valor analógico a convertir. (ADCON1) (PIE1) (INTCON) (INTCON) 3. .Habilitar las interrupciones de los periféricos.Bajar el flag ADIF.El Módulo de Conversión A/D de los PIC Registro INTCON (0Bh . 3 .Habilitar la máscara global de interrupciones.Seleccionar el reloj de la conversión.Seleccionar el canal de la conversión. 10Bh .Encender el módulo A/D. 18Bh) GIE PEIE T0IE INTE RBIE T0IF INTF RBIF bit 7 bit 6 GIE: Habilitación global de interrupciones PEIE: Habilitación de interrupciones de periféricos Registro PIE1 (8Ch) PSPIE ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE bit 6 ADIE: Habilitación de la interrupción del convertidor A/D Registro PIR1 (0Ch) PSPIF ADIF RCIF TXIF SSPIF CCP1IF TMR2IF TMR1IF bit 6 ADIF: Flag de la interrupción del convertidor A/D 1 = Conversión A/D completada.Definir entradas analógicas y tensión de referencia. El Módulo de Conversión A/D de los PIC Pasos en una conversión A/D 1. Configurar el módulo A/D. .

Llevar a cabo la siguiente conversión.Volver al paso 1 ó 2. . b) Esperando a que llegue la interrupción del convertidor.Disponible en los registros ADRESH:ADRESL. según convenga. En estas condiciones. 4 . b) tras seleccionar un nuevo canal.Poner a “1” el bit GO/DONE. 7. . Esperar TACQ : a) tras una conversión. TAD: Tiempo necesario para la conversión de un bit. 6.El Módulo de Conversión A/D de los PIC 4. El Módulo de Conversión A/D de los PIC Tiempo de adquisición Tiempo necesario para cargar el condensador de mantenimiento (CHOLD ). . . Esperar a que se complete la conversión A/D. . no empieza otra adquisición. Comenzar la conversión. TACQ ≈ 20µs. Mientras no se complete la conversión. Leer el resultado de la conversión.Espera mínima antes de empezar la siguiente adquisición: 2·TAD. a) Controlando cuándo el bit GO/DONE se pone a “0”. c) tras encender el módulo A/D. VDD RS VA AN X CPIN 5pF R IC ≤ 1K IFUGAS ±500nA SS R SS CHOLD 120pF VSS Máxima impedancia recomendada para la fuente: 10K.Bajar el flag ADIF si se están usando interrupciones. (ADCON0) No activar este bit a la vez que se enciende el convertidor A/D 5.

) (VREF+) 1021 LSb 1022 LSb 1023 LSb 1024 LSb 1 LSb 2 LSb 3 LSb 4 LSb 5 . El Módulo de Conversión A/D de los PIC Función de transferencia La primera transición tiene lugar cuando la tensión analógica de entrada alcanza el valor VREF.T AD=32·TOSC .VREF-)/1024 ≡ 1LSb.6µs. GO/DONE ← 1 100ns) CHOLD Se carga ADRES Se pone GO/DONE a “0” Se levanta el flag ADIF conectado a entrada analógica TAD configurable en ADCON0 (reloj de la conversión). Tciclo ÷ T AD TAD TAD b9 TAD b8 TAD b7 TAD b6 TAD b5 TAD b4 TAD b3 TAD b2 TAD b1 TAD b0 Comienza la conversión Se abre SS (típ.El Módulo de Conversión A/D de los PIC Tiempo de conversión La conversión de 10 bits dura 12·TAD.T AD=2µs÷6µs (típ.TAD=8·TOSC . FFh FEh FDh FCh 04h 03h 02h 01h 00h (VREF. TAD=2·TOSC .+ (VREF+ . 4µs) Para un funcionamiento correcto se necesita un valor mínimo de TAD=1.

canal: 0 1 2 3 (AN0) (AN1 ) (AN2) (AN3) 4 5 6 7 (AN4) (AN5) (AN6) (AN7) 6 .El Módulo de Conversión A/D de los PIC Conversión A/D en el compilador C de CCS Configuración del módulo conversor A/D setup_adc (modo).) setup_adc_ports (valor ). valor: NO_ANALOGS ALL_ANALOG ANALOG_RA3_REF A_ANALOG A_ANALOG_RA3_REF RA0_RA1_RA3_ANALOG RA0_RA1_ANALOG_RA3_REF (ADCON1 (ADCON1 (ADCON1 (ADCON1 (ADCON1 (ADCON1 (ADCON1 ← ← ← ← ← ← ← 86h) 80h) 81h) 82h) 83h) 84h) 85h) El Módulo de Conversión A/D de los PIC Definición de entradas analógicas (cont. valor: ANALOG_RA3_RA2_REF ANALOG_NOT_RE1_RE2 ANALOG_NOT_RE1_RE2_REF_RA3 ANALOG_NOT_RE1_RE2_REF_RA3_RA2 A_ANALOG_RA3_RA2_REF RA0_RA1_ANALOG_RA3_RA2_REF RA0_ANALOG RA0_ANALOG_RA3_RA2_REF (ADCON1 (ADCON1 (ADCON1 (ADCON1 (ADCON1 (ADCON1 (ADCON1 (ADCON1 ← ← ← ← ← ← ← ← 88h) 89h) 8Ah) 8Bh) 8Ch) 8Dh) 8Eh) 8Fh) Selección del canal analógico set_adc_channel (canal). modo : ADC_OFF ADC_CLOCK_DIV_2 ADC_CLOCK_DIV_8 ADC_CLOCK_DIV_32 ADC_CLOCK_INTERNAL (ADCON0 (ADCON0 (ADCON0 (ADCON0 (ADCON0 ← ← ← ← ← 00h) 01h) 41h) 81h) C1h) Definición de entradas analógicas setup_adc_ports (valor ).

Es necesario incluir información del tipo de conversor A/D. valor: Entero de 16 bits según la directiva #device adc= empleada. setup_adc (ADC_CLOCK_INTERNAL). La influencia de dicha directiva se recoge en la siguiente tabla #device adc=8 adc=10 adc=11 adc=16 8 bits 00-FF x x 0-FF00 10 bits 00-FF 0-3FF x 0-FFC0 11 bits 00-FF x 0-7FF 0-FFE0 16 bits 00-FF x x 0-FFFF El fichero 16f877. setup_adc (ADC_OFF).h incluye como primera directiva #device PIC16F877 .El Módulo de Conversión A/D de los PIC Lectura del resultado valor = read_adc (). Por ello los ficheros C que usen este módulo deberán comenzar por #include “16f877. valor = read_adc (). set_adc_channel (3). delay_us (20).h” #device adc=10 El Módulo de Conversión A/D de los PIC Ejemplo setup_adc_ports (A_ANALOG). W ← 10000010 Banco 1 ADCON1 ← W Banco 0 W ← ADCON0 W ← W & 00111000 W ← W | 11 000001 ADCON0 ← W W ← ADCON0 W ← W & 11000111 W ← W | 00011000 ADCON0 ← W GO/DONE ← 1 Espera a GO/DONE=0 W ← ADRESH TEMP ← W Banco 1 W ← ADRESL Banco 0 REGL ← W W ← TEMP REGH ← W W ← ADCON0 W ← W & 00111000 ADCON0 ← W 7 .

MÓDULOS DE COMUNICACIÓN SERIE .

Comunicación serie asíncrona Características generales de la comunicación serie Los datos se envían bit a bit por una misma línea durante un tiempo fijo. NRZ: Nivel alto: 1 / NRZI: Cambio de nivel: 1 / RZ: Impulso: 1 / . De los sucesivos bits. Posibles codificaciones de cada bit. Así se consiguen menores retardos en las transiciones y mejores flancos en la señal de reloj recibida. Se puede llevar a cabo varios tipos de sincronización.. De cada paquete de bits (8 ó 9 bits) Se envía la señal de reloj si la distancia entre Emisor y Receptor es corta. Asíncrona: Se necesitan “relojes” en el emisor y el receptor de la misma frecuencia y en fase Datos Datos EMISOR ¿Reloj? Referencia de tensión RECEPTOR Reloj Bit i Bit i+1 t t Comunicación serie asíncrona Se emplean dos registros de desplazamiento (uno en el emisor y otro en el receptor) encadenados para la conversión paralelo/serie en la emisión y serie/paralelo en la recepción. Síncrona: Se envía la señal de reloj para sincronizar cada bit. La velocidad de transmisión se indica en baudios (número de bits enviados por segundo). Nivel bajo: 0 Sin cambio de nivel: 0 Sin impulso: 0 1 . La transferencia puede ser síncrona o asíncrona..

2 . El módulo USART puede actuar como sistema asíncrono full duplex. También se conoce como Serial Communications I nterface (SCI). Si se desea enviar un dato se manda un bit de arranque. Permite comunicarse con periféricos como CRTs y PCs. desplazamiento Reloj Datos Reg. El módulo USART también permite localizar direcciones de 9 bits. Reloj Referencia Comunicación serie asíncrona Comunicación serie asíncrona en microcontroladores PIC Se va a implementar haciendo uso del módulo USART Universal Synchronous Asynchronous Receiver Transmitter . Para comunicación con circuitos A/D o D/A. que sitúa a “0” la línea durante el tiempo correspondiente a un bit (START). desplazamiento Sincr. Deben configurarse adecuadamente. Reg. memorias serie EEPROM. la línea se sitúa a “1” al menos durante el tiempo de un bit: bit de parada (STOP). Al finalizar el envío de un dato. Terminales asociados: RC6/TX/CK y RC7/RX/DT. También puede configurarse como sistema síncrono half duplex. etc. Es uno de los dos módulos de E/S serie del PIC. Cada paquete de bits de tamaño fijo se “enmarca” con bits de arranque y de parada que sirven para sincronizar los relojes del emisor y del receptor. La línea de datos está inactiva a “1”.Comunicación serie asíncrona Transferencia asíncrona Se emplean relojes de igual frecuencia (se acuerda y se configura la velocidad de transmisión) pero también es necesario que estén en fase (sincronizados).

Comunicación serie asíncrona Registro TXSTA (98h) CSRC TX9 TXEN SYNC BRGH TRMT TX9D bit 6 bit 5 bit 4 bit 2 bit 1 bit 0 TX9: Bit de habilitación de la transmisión de 9 bits 0: Transmisión de 8 bits 1 : Transmisión de 9 bits TXEN: Bit de habilitación de la transmisión 0: Transmisión deshabilitada 1 : Transmisión habilitada SYNC: Bit de selección del modo de funcionamiento 0: Transmisión asíncrona 1 : Transmisión síncrona smisión sínc rona BRGH: Bit de selección de alto valor de baudios N o se usa en tran 0: Baja velocidad 1 : Alta velocidad TRMT: Bit de estado del registro TSR 0: TSR lleno 1 : TSR vacío TX9D: 9 bit de datos transmitido. por ejemplo Comunicación serie asíncrona Registro RCSTA (18h) SPEN RX9 SREN CREN ADDEN FERR OERR RX9D bit 7 bit 6 bit 4 bit 3 bit 2 bit 1 bit 0 SPEN: Bit de habilitación del puerto serie 0: Deshabilitado 1 : Habilitado como pines del Configura RC<6:7> ie ser rto pue RX9: Bit de habilitación de la recepción de 9 bits 0: Recepción de 8 bits 1 : Recepción de 9 bits No se usa en transmisión síncrona CREN: Bit de habilitación de recepción continua 0: Deshabilitada 1 : Habilitada ADDEN: Bit de habilitación de detección de dirección 0: Deshabilitada 1 : Habilitada Sólo si RX9=1 FERR: Bit de error de framing 0: No hubo error 1 : Sí hubo error Se actualiza al leer RCREG Se pone a 0 si CREN ← 0 OERR: Bit de error de overrun 0: No hubo error 1 : Sí hubo error RX9D: 9 bit de datos transmitido. 3 . Puede ser el bit de paridad.

Así se eliminan posibles errores debidos a las diferencias en los relojes del emisor y el receptor. SPBRG=129 ⇒ 9615Bd (error=0.73%) BRGH=1 . Si se desea 9600Bd con fosc=20MHz: BRGH=0 .Comunicación serie asíncrona Generador de baudios (BRG) La velocidad de la comunicación serie se controla mediante el valor cargado en el registro SPBRG (99h). Puede dar lugar a menores errores relativos. El receptor incorpora un circuito de muestreo de la línea de datos que lee el valor del bit en la mitad del periodo de muestreo. el usuario debe calcularlo e interpretarlo en el software. Aunque comparten el mismo formato de datos y la misma velocidad de la comunicación (baudios). La expresión matemática que determina los baudios de la comunicación serie asíncrona es la siguiente: fosc   64 ⋅ (SPBRG + 1)   Baudios =   fosc  16 ⋅ (SPBRG + 1)  si BRGH = 0 1 bau dio = 1 bit / sg si BRGH = 1 En muchos casos resulta ventajoso usar BRGH=1 incluso para generar comunicaciones lentas. SPBRG=31 ⇒ 9766Bd (error=1.16%) Comunicación serie asíncrona Comunicación serie asíncrona con el SCI La información se transmite en formato NRZ Se transmite primero el bit menos significativo. que se selecciona haciendo SYNC ← 0. No se genera paridad mediante hardware. no funciona en modo SLEEP. Si se quiere enviar como 9º bit el bit de paridad. El emisor y el receptor son funcionalmente independientes. 4 . La comunicación asíncrona.

La transmisión no empieza hasta que TXREG haya sido cargado con un dato y se genere un reloj de los baudios deseados. TRMT no está ligado a ninguna interrupción.Cuando TXREG queda vacío. . . . .Si TSR está vacío. TRMT ← 1.El paso del contenido de TXREG a TSR se realiza en un ciclo de instrucción.Comunicación serie asíncrona Emisor asíncrono en el SCI Diagrama de bloques. . TXIF sólo se borra escribiendo en TXREG.Además debe estar habilitada la transmisión (TXEN=1). el contenido de TXREG pasa a TSR para ser enviado. Bus de datos TXIE TXIF TXREG 8 (8) 7 6 5 4 3 2 1 0 TSR Interrupción Control RC6 TX CK TXEN SPBRG CLK TX9D TRMT SPEN TX9 Comunicación serie asíncrona Funcionamiento Desde el programa se carga el buffer de transmisión TXREG. 5 . el 9º bit debe escribirse antes de escribir los otros 8 bits en TXREG. al escribir en TXREG podría comenzar la transferencia de inmediato.Del mismo modo. En cuanto se haya enviado un bit de STOP. cuando TSR queda vacío. Si se usa una transmisión de 9 bits (TX9=1). TXIF ← 1 (si TXEN=1). con lo que el 9º bit sería erróneo.

Dato 1 Dato 2 Escritura en TXREG Salida BRG Pin RC6/TX/CK Bit TXIF Bit TRMT Dato 1 en el TSR Dato 2en el TSR START Bit 0 Bit 1 Bit 7/8 STOP START Bit 0 Bit 1 Bit 2 Dato 1 Dato 2 6 .Comunicación serie asíncrona Transmisión serie asíncrona de un dato Dato 1 Escritura en TXREG Salida BRG Pin RC6/TX/CK Bit TXIF Bit TRMT START Bit 0 Bit 1 Bit 2 Bit 3 Bit 7/8 STOP Dato 1 Dato 1 en el TSR Comunicación serie asíncrona Transmisión serie asíncrona back to back Se escribe un dato en TXREG antes de que se haya terminado de enviar el anterior.

(TXSTA<0>) 7. hacer TXIE ← 1. cargar el noveno bit en TX9D. 6. Habilitar la transmisión serie. CLK fosc CREN OERR FERR SPBRG MSb (8) 7 6 5 4 3 2 1 0 LSb STOP RC7 RX DT RSR START Control Recuperación de datos RX9 SPEN RCIF RCIE RX9D RCREG FIFO 8 Bus de datos Interrupción 7 . Si se ha seleccionado una transmisión de 9 bits. (PIE1<4>) (TXSTA<6>) 4.Comunicación serie asíncrona Pasos a seguir para transmitir datos 1. Si se van a transmitir datos de 9 bits. Si se van a usar interrupciones. TXEN ← 1 . SYNC ← 0 . 8. (INTCON<7:6>) Comunicación serie asíncrona Receptor asíncrono en el SCI Diagrama de bloques. 5. 3. Si se van a usar interrupciones. hacer TX9 ← 1. Habilitar el puerto serie asíncrono. Cargar el dato a transmitir en el registro TXREG. SPEN ← 1 Usando el registro SPBRG y el bit BRGH (TXSTA<2>). 2. esto hará que TXIF ← 1 también. Seleccionar los baudios de la comunicación. asegurarse de que los bits GIE y PEIE están a “1”.

RCIF ← 1. El registro RCREG es una cola FIFO de dos posiciones. En cuanto RSR haya recibido un bit de STOP.Al leer RCREG. OERR ← 1.El bit FERR se gestiona del mismo modo que el 9º bit del dato. se carga un nuevo dato de RSR. . FERR ← 1.El tercer dato se pierde. . Si RSR recibe un “0” cuando espera el bit de STOP. su contenido pasa a RCREG (si está vacío). . RCIF sólo se borra cuando se ha leído RCREG (y queda vacío). Habría que leer RCREG dos veces. . Comunicación serie asíncrona Recepción serie asíncrona de un dato Pin RC7/RX/DT Recibido en RSR Leído de RCREG Bit RCIF Bit OERR Bit CREN STT b0 b7/8 STP STT b0 b7/8 STP STT b0 b7/8 STP Dato 1 pasa a RCREG Dato 2 pasa a RCREG 8 . OERR se borra reseteando la lógica de recepción (CREN←0 y CREN←1).Cuando se haya completado esta transferencia.Puede haber dos datos en RCREG y estar recibiéndose un tercero en RSR. Si RSR recibe el bit de STOP de un tercer byte. .Comunicación serie asíncrona Funcionamiento La recepción de datos queda habilitada haciendo CREN ← 1. Hay que leer el 9º dato (y el bit FERR) antes que RCREG. Puede variar RX9D y FERR.

Habilitar la recepción serie. hacer RX9 ← 1. BITS=8) 0 0 1 0 0 0 1 0 TXSTA RCSTA SPBRG = 4 1 0 0 1 0 0 0 0 set_uart_speed ( baud). SYNC ← 0 . RCV=PIN_C7 . ¡¡IMPORTANTE!! Es imprescindible que aparezca una directiva #use delay antes de que se pueda utilizar una directiva #use rs232. 8. 2. hacer RCIE ← 1. Si ha habido algún error. Habilitar el puerto serie asíncrono. SPEN ← 1 3.. resetearlo haciendo CREN ← 0. se tendrá RCIF ← 1.Comunicación serie asíncrona Pasos a seguir para recibir datos 1. Si se van a usar interrupciones. #use delay (clock=3000000).. asegurarse de que GIE=1 y PEIE=1. Cuando se complete una recepción. (PIR1<5>) 10. 5. Si se van a usar interrupciones. baud: Constante entre 100 y 115. Leer los 8 bits recibidos en el registro RCREG. Seleccionar los baudios de la comunicación. 4. Leer RX9D y determinar si se ha producido algún error. CREN ← 1 (PIE1<5>) (RCSTA<6>) 6. Si se van a recibir datos de 9 bits. 7. 9. #use rs232 (BAUD=9600 . Comunicación serie asíncrona Comunicación serie asíncrona en el compilador C de CCS Configuración del módulo CCP #use rs232 (opciones) opciones: BAUD = x XMIT = pin RCV = pin BITS = x .200 nte la mbiar dura Permite ca s baudios lo a m ra og l pr rs232 ejecución de e us # n definidos co 9 . XMIT=PIN_C6 .

1-9. Muy a menudo estas funciones se ven remplazadas por la función printf. La función puts manda los caracteres de la cadena uno a uno a través del bus RS-232 utilizando la función putc. función : Función a utilizar para escribir la cadena indicada. 01-09 Nº de posiciones a completar con 0s.9 Nº de decimales. string: Cadena de caracteres constante o array de caracteres terminado con un 0. dato: putchar (dato). Flotante Long en hexadecimal Ídem en mayúsculas Long sin signo (en decimal) Long con signo (en decimal) Simplemente un % 10 . valores. en la cadena se indicará como %wt . más versátil que cualquiera de ellas.] ). t: C S U x X D Carácter Cadena o carácter Entero con signo Entero en hexadecimal Ídem en mayúsculas Entero con signo e f Lx LX lu ld % Flotante en formato exp. string: Cadena de caracteres (constante) o array de caracteres terminado con un 0. 1. Comunicación serie asíncrona Transmisión serie (cont. que permite escribir en el bus RS-232. Por defecto es putc .] string [. valores: Variables a incluir en la cadena Cuando se usan variables. Detrás de la cadena envía un RETURN (13) y un retorno de carro (10). puts (string). Carácter de 8 bits.) printf ([función..Comunicación serie asíncrona Transmisión serie putc (dato).. donde w : 1-9 Nº de caracteres.

ptr=strchr(s1. strcpy (s1. Copia cad en s1 . Como anterior pero empieza búsqueda desde final. valor: valor = getch(). Comunicación serie asíncrona Funciones estándar CCS para cadenas de caracteres Funciones que facilitan el trabajo con cadenas de caracteres. Almacena caracteres (leídos con getc) en el array hasta que recibe un RETURN (13).s2).c).s2. ptr=strlwr(s1). string: Puntero a un array de caracteres.s2.s2). ptr=strncpy(s1. Localiza c en s1 y devuelve su dirección: &s1[i]. valor = getchar(). Termina la cadena con un 0. res=strlen(s1). ptr=strpbrk(s1.c). res=strcspn(s1. valor: 0 (FALSE) si getc debe esperar a que llegue un carácter. 1 (TRUE) si ya hay un carácter listo para ser leído por getc. res=strncmp(s1.s2). ptr=strrchr(s1. Espera que llegue un carácter por la línea RS-232 y da su valor.s2).h s1. res=strspn(s1. Encadena s2 a s1. res=stricmp(s1.s2). Compara s1 y s2 y devuelve TRUE si coinciden.cad). res=strcmp(s1.Comunicación serie asíncrona Recepción serie valor = getc(). Carácter de 8 bits. Compara n caracteres entre s1 y s2 Compara ignorando si son mayúsculas o minúsculas Copia n caracteres de s2 en s1 Cuenta caracteres de s1 que no están en s2 Cuenta caracteres de s1 que también están en s2 Cuenta los caracteres de s1 Convierte todas las mayúsculas a minúsculas Busca posición en s2 donde empieza copia de s1 ptr res Copia del puntero s1 Entero de 8 bits Necesitan el fichero de inclusión string. se pueden almacenar hasta tres caracteres.n ).s2). Para no estar continuamente esperando.n). ptr=strcat(s1. s2 cad n c Punteros a array de caracteres Puntero a array de caracteres o cadena constante Máximo nú mero de caracteres con que trabajar Carácter de 8 bits 11 . valor = kbhit(). gets(string). se puede usar kbhit(). En los PIC con USART.

Conector SUB-D de 25 pins. Conector SUB-D de 9 pins. Presentan de manera mayoritaria conectores SUB-D de 9 pines hembra (aunque la norma original dice que los DTE deben ser macho) 5 1 9 6 Pin 1 Pin 2 Pin 3 Pin 4 Pin 5 Pin 6 Pin 7 Pin 8 Pin 9 DCD (E) Detección de Portadora RXD (E) Recepción de Datos TXD (S) Transmisión de Datos DTR (S) PC listo para recibir ß Es la respuesta a CTS MASA COMÚN DSR (E) PC puede enviar datos ß Es la respuesta a RTS RTS (S) PC solicita envíar datos ß Le responderán con DSR CTS (E) Le preguntan si PC listo para recibir ß Responderá con DTR RI (E) Indicador de llamada ß Sólo si el otro equipo es realmente un módem RTS – DSR CTS – DTR Protocolo de envío de datos desde el PC Protocolo de recepción de datos en el PC 12 . (El menos habitual) El conector de 25 pines es el único que dispone de todas las señales definidas en la norma original. Los equipos pueden utilizar distintos conectores.Comunicación serie asíncrona La Norma RS232 Nace con la idea de comunicar un computador o equipo terminal de datos (DTE o Data Terminal Equipment ) y un módem o equipo de comunicación de datos (DCE o Data Communications Equipment ). Su uso se extendió a otras aplicaciones y hoy se emplea para comunicar equipos que no respetan íntegramente la norma y que no necesitan la mayoría de las líneas de la norma original: detector de portadora (DCD). indicador de llamada (RI). canal secundario. Comunicación serie asíncrona Ejemplo: Los puertos serie de un PC (COMn). Conector SUB-D de 15 pins de alta densidad. por ejemplo. como dos PCs o un PC y un microcontrolador.… Se emplea. para comunicar equipos que son ambos DTE.

Comunicación serie asíncrona Emisores/Receptores de 2 canales para adaptación TTL-RS232 Una sola alimentación de 5V para generar tensiones de ±10V. El truco pasa por “puentear” las líneas de petición de envío y las respuestas. será necesario realizar la correspondiente adaptación de los niveles de tensión que utiliza el microcontrolador a los niveles de la norma RS232 “1” -> 5V “0” -> 0V Micro a 5V lectura y escritura “1” -> -5V a -15V “0” -> +5V a +15V Escritura RS232 “1” -> -3V a -15V “0” -> +3V a +15V Lectura RS232 Existen varios circuitos integrados comerciales que realizan esta adaptación con muy pocos componentes (p. Se puede simplificar el conexionado y obviar las líneas de pregunta-respuesta “engañando” al emisor para hacerle creer que el receptor está siempre listo. 13 . la familia MAX220 a 249) La conexión puede realizarse utilizando las líneas que se consideren oportunas.Comunicación serie asíncrona Para realizar la conexión entre un microcontrolador y un PC.e.

Comunicación serie asíncrona Conexión serie según norma RS232: Comunicación PIC .PC “1” -> 5V “0” -> 0V RX TX GND EJEMPLO DE CONEXIÓN A 3 HILOS FULL DÚPLEX Driver RS232 (MAX232) Niveles escritura RS232 “1” -> -5V a -15V “0” -> +5V a +15V TX RX GND Niveles lectura RS232 “1” -> -3V a -15V “0” -> +3V a +15V Pin3 Pin2 Pin5 Puentes Pins 4 y 8 Pins 6 y 7 14 .

La velocidad de transmisión se indica en baudios (número de bits enviados por segundo). Nivel bajo: 0 Sin cambio de nivel: 0 Sin impulso: 0 . NRZ: Nivel alto: 1 / NRZI: Cambio de nivel: 1 / RZ: Impulso: 1 / . La transferencia puede ser síncrona o asíncrona.Comunicación Serie Síncrona I2C Características generales de la comunicación serie Los datos se envían bit a bit por una misma línea durante un tiempo fijo.. Asíncrona: Se necesitan “relojes” en el emisor y el receptor de la misma frecuencia y en fase Datos Datos EMISOR ¿Reloj? Referencia de tensión RECEPTOR Reloj Bit i Bit i+1 t t Comunicación Serie Síncrona I2C Se emplean dos registros de desplazamiento (uno en el emisor y otro en el receptor) encadenados para la conversión paralelo/serie en la emisión y serie/paralelo en la recepción. Posibles codificaciones de cada bit. De cada paquete de bits (8 ó 9 bits) Se envía la señal de reloj si la distancia entre Emisor y Receptor es corta. Síncrona: Se envía la señal de reloj para sincronizar cada bit. Se puede llevar a cabo varios tipos de sincronización.. De los sucesivos bits. Así se consiguen menores retardos en las transiciones y mejores flancos en la señal de reloj recibida.

Comunicación Serie Síncrona I2C
Transferencia síncrona
La comunicación síncrona entre dos dispositivos requiere que uno de ellos actúe como maestro y el otro, como esclavo. Dispositivo Maestro: Es el que genera la señal de reloj y el que tiene capacidad de iniciar o finalizar una transferencia. Dispositivo Esclavo: Recibe la señal de reloj y no tiene capacidad para iniciar una transferencia de información. Es posible efectuar una transmisión continua de bits de información.
Dato Dato

Maestro

Clk

Esclavo

Maestro

Clk

Esclavo

Ref. Maestro Emitiendo

Ref. Maestro Recibiendo

Comunicación Serie Síncrona I2C
Comunicación serie síncrona en microcontroladores PIC
Se implementa mediante el módulo SSP Synchronous Serial Port : Interfaz de comunicación serie síncrona. Está pensado para poder comunicarse con otros microcontroladores o periféricos mediante transmisión serie síncrona. EEPROM serie Almacenamiento de datos no volátiles Registros de Desplazamiento Expansión de entradas y/o salidas Drivers de Displays Reducción de conexiones Conversores A/D Digitalización externa de señales .... El módulo SSP tiene dos posibles modos de funcionamiento. SPI (Serial Peripheral I nterface: Interface de Periféricos Serie)
SPI: Es una Marca Registrada de Motorola Corporation I2C: Es una Marca Registrada de Philips

I 2C (I nter-I ntegrated Circuit: Entre Circuitos Integrados)

Comunicación Serie Síncrona I2C
Características generales del bus I2C
El bus Inter-Integrated-Circuit (I 2C) fue creado por Philips. Para transferencia de datos entre CIs de una PCB. Soporta transmisión de datos de hasta 400kbd.

Es más lento que el módulo SPI.

Un bus I 2C puede tener distintas configuraciones. Configuración de un Maestro y varios Esclavos. Configuración multiMaestro. En cualquiera de estas configuraciones, el dispositivo Maestro es el único que tiene capacidad de iniciar la transferencia, decidir con quién se realiza, el sentido de la misma (envío o recepción desde el punto de vista del Maestro) y cuándo se finaliza. El bus I 2C consiste físicamente en dos líneas de colector abierto. SCL para el reloj (pin RC3). SDA para los datos (pin RC4).
La comunicación es, por tanto, half-duplex.

Comunicación Serie Síncrona I2C
Las líneas necesitan resistencias externas de pull-up. Para poder implementar un wire-AND (Y cableado). Cuando el bus está inactivo, ambas líneas están a “1”. El protocolo I 2C puede usar direcciones de 7 ó de 10 bits. Puede haber hasta 128 ó hasta 1024 dispositivos colgados del bus. Con la dirección se informa si el Maestro quiere leer o escribir. El protocolo I 2C incluye un mecanismo de comprobación (handshaking ). - Cada transferencia de 8 bits, el Maestro envía un 9º pulso de reloj. - En ese instante, el dispositivo “transmisor” suelta la línea SDA y el “receptor” reconoce el dato enviado mediante un ACK (SDA←0). - Se envía un NACK (deja SDA=1) para finalizar la transmisión. Todos los cambios en SDA deben ocurrir mientras SCL=0. Así se permite diferenciar dos condiciones únicas: Secuencia START (S). El Maestro hace SDA←0 mientras SCL=1. Secuencia STOP (P). El Maestro hace SDA←1 mientras SCL=1.

Comunicación Serie Síncrona I2C
Fácil inclusión de nuevos dispositivos I 2C en el bus. Una vez disponible el microcontrolador con sus funciones de interface con bus I2C, la inclusión de un dispositivo I 2C adicional sólo precisa su conexión a las dos líneas del bus (SDA y SCL), que son las mismas para todos, y asignarle una dirección.

Conexiones en el bus I 2C.

VDD

Rp ≥
Rp Rp

Periférico
Rs Rs

VDD − VOL iOL
Número máx. de dispositivos definidos por la capacidad en el bus: C max=400pF

SDA SCL
C bus=10 – 400pF

Comunicación Serie Síncrona I2C
Direccionamiento de dispositivos en el bus I 2C Formato de 7 bits: (A7-A6-...-A1)
En la línea SDA: Start S Lo “pone” el Maestro Reconocimiento (lo debe poner el Esclavo)

A7 A6 A5 A4 A3 A2 A1 R/W ACK Dirección de 7 bits del esclavo Lectura (1) o Escritura (0)

Formato de 10 bits: (A9-A8-A7-...-A0)
En la línea SDA: Start Primer byte del Maestro S 1 1 1 1 0 A9 A8 2º byte del Maestro R ACK A7 A6 A5 A4 A3 A2 A1 A0 ACK W ACK S Reconocimientos del Esclavo después de cada byte del Maestro

Lectura (1) o Escritura (0)

el Maestro debe abortar la transferencia generando un bit de fin (STOP). El Esclavo puede retardar el envío del siguiente byte (porque no lo tiene todavía disponible. SDA: S Dirección del Esclavo R/W A Dato A Dato A/A P De Maestro a Esclavo De Esclavo a Maestro “0” porque el Maestro quiere escribir (enviar) Reconocimiento (A) o no reconocimiento (A) Secuencia de recepción I 2C por parte del Maestro. por lo que el Esclavo debe dejar su salida SDA a “1” para que el Maestro pueda generar el STOP (paso de “0” a “1” con SCL=“1”) Si el receptor es el dispositivo Maestro. genera un ACK tras cada byte recibido. SDA: S Dirección del Esclavo R/W A Dato A Dato A P “1” porque el Maestro quiere leer (recibir) No reconocimiento por Maestro y Parada . forzando así al Maestro a situarse en un estado de “Espera” puesto que no podrá generar flancos en SCL. permitiendo al Esclavo que continúe enviando bytes. genera un bit de STOP tras colocar un bit de no-reconocimiento (NACK).e.Comunicación Serie Síncrona I2C Reconocimiento de transferencia (ACK) Los datos se transmiten en paquetes de 8 bits (bytes). Si el Maestro decide finalizar la transferencia.) situando la línea SCL en estado bajo. En este caso. Tras cada byte el receptor debe intercalar un bit de reconocimiento (ACK). y dado que las etapas de salida son de drenador abierto. Si el receptor es el Esclavo y no genera el bit de reconocimiento después de cada byte. Comunicación Serie Síncrona I2C Secuencia de transmisión I 2C desde el Maestro. los niveles lógicos “0” son dominantes en las líneas. p.

Recibe la dirección A7 A6 A5 A4 A3 A2 A1 R/W ACK Puesto por el Maestro Envía el dato NACK D7 D6 D5 D4 D3 D2 D1 D0 S 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 P Pulso ACK El Esclavo pone SCL a 0 para darse tiempo de preparar el dato Pulso ACK Comunicación Serie Síncrona I2C Repetición de START (Sr) Si un dispositivo Maestro no desea abandonar el bus tras una transferencia. Recibe la dirección A7 A6 A5 A4 A3 A2 A1 R/W ACK Recibe el dato ACK D7 D6 D5 D43 D3 D2 D1 D0 Recibe el dato D7 D6 D5 D4 D3 D2 Puesto por el Esclavo NACK D1 D0 S 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 P Pulso ACK Pulso ACK Pulso ACK Típica transmisión I 2C por parte del Esclavo.Comunicación Serie Síncrona I2C Típica transmisión I 2C para lectura desde el Esclavo. La Repetición de START es idéntica a la condición de START (SDA pasa de 1 a 0 con SCL en estado alto) pero se produce tras un pulso de reconocimiento de bus (ACK) y no desde un estado inactivo. . en lugar de generar un bit de STOP y volver a generar el nuevo START. puede generar una Repetición de START (Sr).

16C65. 16C64. 16F87x MSSP (M aster Synchronous S erial Port ) Ambos módulos son idénticos en lo que se refiere al interface SPI. Modo Maestro: Completo por hardware. 16C74. Maestro I2 C con reloj SCL de frecuencia fSCL = fOSC /[4·(SSPADD+1)] SSPCON SSPADD SSPCON2 SSPBUF SSPSTAT SSPSR .Seis registros asociados al funcionamiento de este módulo. . . Comunicación Serie Síncrona I2C Diagrama de bloques del bus I2C en modo Esclavo Bus de datos Leer Escribir RC3 / SCL RC4 / SDA Reloj SSPBUF SSPSR MSb LSb Buffer Buffer para para envío envío y y recepción recepción Registro Registro E/S E/S No Noaccesible accesible directamente directamente Detector de dirección SSPADD Detección de START/STOP Detecta coincidencia en la dirección o llamada general Control de los bits S y P del registro SSPSTAT Dirección Dirección asignada asignada al al Esclavo Esclavo . Modo Maestro: Detección de bits START y STOP por hardware. BSSP (B asic Synchronous Serial Port ) Modo Esclavo: Completo por hardware. Modo Esclavo: Completo por hardware. Esclavo I2 C con dirección de 7 bits. Características del interface I 2C en el módulo MSSP.. .Detecta condiciones START y STOP en el bus por interrupción.Permite seleccionar tres modos de operación. 16C73.Comunicación Serie Síncrona I2C El interface I2C en los microcontroladores PIC Puede implementarse en dos módulos (según el tipo de PIC). Esclavo I2 C con dirección de 10 bits..

Comunicación Serie Síncrona I2C Diagrama de bloques del bus I2C en modo Maestro Bus de datos Leer Escribir SSPM3:SSPM0 SSPADD<6:0> SSPBUF RC4 SDA SDA In SSPSR MSb Habilita recepción LSb Reloj Generador de baudios Ctrl CLK (detiene fuente de CLK) (SSPSTAT) (SSPCON2) RC3 SCL Detección de START/STOP SCL In Colisión de bus Detección de colisión Control de CLK S . P . BCLIF ACKSTAT . WCOL SSPIF . PEN Comunicación Serie Síncrona I2C Registro SSPSTAT (94h) SMP CKE D/A P S R/W UA BF bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 SMP: Bit de control de slew rate 0: Velocidad estándar 0: Especificaciones I2 C 0: Dirección 1 : Alta velocidad (400kHz) 1 : Especificaciones SMBus 1 : Dato Ctrl CLK Generación de START/STOP ACK Maestro CKE: Bit de selección de niveles umbral en los pines D/A: Información del último byte transmitido P: Bit de STOP S: Bit de START Se pone a 1 si la última secuencia detectada es un bit de STOP Se pone a 1 si la última secuencia detectada es un bit de START R/W: Información de lectura/escritura 0: Escritura 0: No hay transmisión 1 : Lectura 1 : Transmisión en progreso (Esclavo ) (Maestro ) bit 1 bit 0 UA: Actualización del byte de dirección 0: No hace falta 1 : Es necesario actualizar la dirección 1 : SSPBUF está lleno BF: Bit de estado del buffer 0: SSPBUF está vacío .

Maestro controlado por Fw (dir. Maestro con CLK=Fosc / [4·(SSPADD+1)]. Esclavo con direcciones de 10 bits. interrup. interrup. Maestro controlado por Fw (dir. por bits de START y STOP). Comunicación Serie Síncrona I2C Registro SSPCON2 (91h) GCEN ACKSTAT ACKDT ACKEN RCEN PEN RSEN SEN bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 GCEN: Habilita Llamada General 0: Deshabilitada 0: Recibido ACK del Esclavo 0: ACK 0: Desactivada 0: Recepción desactivada 0: Desactivada 0: Desactivado 0: Desactivada 1 : Habilita interrupciones por Llamada General ( Maestro / Recepción) (Maestro / Recepción) 1 : No se ha recibido ACK del Esclavo 1 : NACK (Maestro / Recepción) (Maestro ) (Maestro ) (Maestro ) (Maestro ) Esclavo ACKSTAT: Bit de reconocimiento ACKDT: Valor a transmitir tras una recepción ACKEN: Habilitación de secuencia ACK RCEN: Bit de habilitación de recepción PEN: Habilitación de una secuencia STOP RSEN: Habilitación de START repetido 1 : Inicia secuencia de reconocimiento en SDA y SCL 1 : Activa modo recepción 1 : Inicia situación de STOP en SDA y SCL 1 : Inicia repetidas situaciones de START 1 : Inicia situación de START en SDA y SCL SEN: Habilitación de una secuencia START . por bits de START y STOP). de 7 bits.Comunicación Serie Síncrona I2C Registro SSPCON (14h) WCOL SSPOV SSPEN CKP SSPM3 SSPM2 SSPM1 SSPM0 bit 7 bit 6 bit 5 bit 4 WCOL: Bit de detección de colisión 0: No ha habido colisión 1 : Ha habido colisión SSPOV: Bit indicador de overflow en la recepción 0: No ha habido overflow 1 : Ha habido overflow SSPEN: Habilitación del puerto serie síncrono 0: Desabilitado 1 : Habilitado (usa SCL y SDA) CKP: Control de SCL 0: Mantiene SCL a “0” 1 : Reloj habilitado bits 3:0 SSPM3:SSPM0: Modo de funcionamiento 0110: 0111 : 1000 : 1011 : 1110 : 1111: Esclavo con direcciones de 7 bits. de 10 bits. Modo Maestro controlado por firmware (Esclavo inactivo).

Buffer de transmisión/recepción serie. Los sucesos I2C que percibe el Esclavo pueden ser de 5 tipos. Configurar el MSSP en el registro SSPCON. La dirección viene indicada por SSPADD<7:1> . 8Bh . Registro de desplazamiento SSP (no accesible directamente). 18Bh) Comunicación Serie Síncrona I2C Funcionamiento en modo Esclavo Antes de activar el módulo hay que configurar RC<3:4> como entradas. (87h) SSPBUF SSPSR (13h) SSPADD (93h) PIR1 – PIE1 (0Ch – 8Ch) PIR2 – PIE2 INTCON (0Dh – 8Dh) (0Bh . 10Bh . Esclavo I 2C con direcciones de 7 bits o con direcciones de 10 bits. Define la dirección del Esclavo o los baudios de la comunicación (Maestro). . Escribirla en el registro SSPADD. Habilita interrupciones de periféricos. Esclavo I 2C con o sin interrupciones por bits de START y STOP.Comunicación Serie Síncrona I2C Otros registros relacionados con el módulo MSSP TRISC Para definir RC3 y RC4 como entradas. Lo más habitual es que no se usen interrupciones por START/STOP Establecer la dirección del esclavo. Se puede determinar con la ayuda del bit SSPIF.SSPADD<0>=0 LSb se usa para determinar la operación solicitada por el Maestro Esperar por un suceso I 2C. Interrupción por colisión del bus (BCLIF – BCLIE). La interrupción puede estar activada o no Identificar el suceso y actuar en consecuencia. Interrupciones del módulo SSP (SSPIF – SSPIE).

SSPOV ← 1 y se envía un NACK. Último byte fue un dato Tras el byte de dirección. Si SSPBUF no estaba lleno antes de la escritura. Bits del registro SSPSTAT. Esta acción borra el bit BF y evita posteriores overflows. seguida del envío de la dirección del Esclavo. Lo hace el MSSP automáticamente. Si coincide con la suya. Comunicación Serie Síncrona I2C Maestro solicita escritura. Último byte fue una dirección El Maestro ha comenzado una operación de escritura con el inicio de una secuencia START o RESTART en el bus. el Maestro puede enviar uno o más bytes de datos al Esclavo. el Esclavo envía un reconocimiento ACK en el 9º pulso de reloj. Si ya estaba lleno. . S=1 R/W = 0 D/A = 1 BF = 1 La última secuencia detectada fue un START El Maestro escribe datos en el Esclavo El último byte recibido fue un dato El buffer está lleno Debe leerse el registro SSPBUF. La dirección que hay en el bus pasa al registro SSPSR del Esclavo. Bits del registro SSPSTAT.Comunicación Serie Síncrona I2C Maestro solicita escritura. S=1 R/W = 0 D/A = 0 BF = 1 La última secuencia detectada fue un START El Maestro va a escribir datos en el Esclavo El último byte recibido fue una dirección El buffer está lleno Debe leerse el registro SSPBUF aunque no se vaya a usar la información que contiene. la dirección recibida pasa a SSPBUF.

Y debe hacer CKP ← 1 para liberar la línea SCL. Bits del registro SSPSTAT. El Esclavo manda el dato al Maestro escribiéndolo en el registro SSPBUF y haciendo CKP ← 1 para liberar la línea SCL. El Esclavo debe escribir en el buffer el dato solicitado por el Maestro. S=1 R/W = 1 D/A = 0 BF = 0 La última secuencia detectada fue un START El Maestro va a leer datos del Esclavo El último byte recibido fue una dirección El buffer está vacío El bit CKP se pone a 0 para que la línea SCL pase a estado bajo. Último byte fue una dirección El Maestro ha comenzado una operación de lectura con el inicio de una secuencia START o RESTART en el bus. dando así tiempo al Esclavo para preparar el dato a enviar. dando así tiempo al Esclavo para preparar el dato a enviar. Último byte fue un dato El Maestro ya ha leído un dato del Esclavo y quiere leer otro. Bits del registro SSPSTAT. Comunicación Serie Síncrona I2C Maestro solicita lectura. seguida del envío de la dirección del Esclavo. S=1 R/W = 1 D/A = 1 BF = 0 La última secuencia detectada fue un START El Maestro lee datos del Esclavo El último byte recibido fue un dato El buffer está vacío El bit CKP se pone a 0 para que la línea SCL pase a estado bajo.Comunicación Serie Síncrona I2C Maestro solicita lectura. .

De este modo indica que ya no quiere recibir más datos. Si ha ocurrido un overflow. La lógica del Esclavo le enviará un NACK al Maestro. En la práctica. Típicamente el Maestro intentará volver a enviar el dato hasta que reciba un ACK. Indican que se ha recibido un dato del Maestro pero que el buffer está vacío.Comunicación Serie Síncrona I2C Maestro envía NACK El Maestro ha enviado un NACK como respuesta al dato que ha recibido desde el Esclavo. Debido a que la recepción de un NACK da lugar a un reset de la lógica I2C del Esclavo. Tras escribir un dato en SSPBUF. Comprobando el estado del bit SSPOV. Comunicación Serie Síncrona I2C Control de errores en modo Esclavo Cada vez que se lee el SSPBUF. . el usuario debe asegurarse de que no han ocurrido overflows. S=1 R/W = 0 D/A = 1 BF = 0 La última secuencia detectada fue un START La lógica del Esclavo queda reseteada El último byte recibido fue un dato El buffer está vacío El envío de un NACK queda identificado porque R/W ← 0. Bits del registro SSPSTAT. el usuario debe comprobar el valor de WCOL para asegurar que no se ha producido una colisión. Esta situación da lugar a que los bits del registro SSPSTAT reflejen una situación incoherente. no habrá colisiones si únicamente se escribe en SSPBUF cuando BF=0 y el Esclavo está transmitiendo al Maestro. será necesario hacer SSPOV ← 0 y leer SSPBUF para permitir nuevas recepciones. Los sucesos que tienen lugar tras un overflow dependen de cada caso.

1.Configurar el modo I2C. f) Al final del 9º flanco en SCL. Leer (recibir datos) 6. Se supone que la dirección es de 7 bits . . j) Al final del 9º flanco en SCL se pone SSPIF a 1 (hay que ponerlo a 0). g) Se cargan en SSPBUF los 8 bits del dato a enviar. d) Los bits de la dirección salen por SDA hasta completar los 8 bits. h) Los bits del dato salen por SDA hasta completar la transmisión. RESTART * ACK 3. Sólo se usan los bits 0 a 6 TRISC ← xxx11xxx SSPCON1 ← 00101000 100kHz 400kHz 1MHz .Definir líneas SDA y SCL como entradas. Escribir (transmitir datos) Comunicación Serie Síncrona I2C Funcionamiento del Maestro Secuencia típica de transmisión de un byte por parte del Maestro a) Se genera una condición de START poniendo a 1 el bit de habilitación de START (SEN) del registro SSPCON2. b) Se esperará el tiempo necesario para detectar START. cuando se haya dado la condición. se pone SSPIF=1 (hay que resetearlo). i) Se lee el bit de reconocimiento (ACK) y se graba su valor en SSPCON<6>.Comunicación Serie Síncrona I2C Funcionamiento en modo Maestro Configurar el MSSP para funcionar en modo Maestro I 2C. Reconocer (tras una lectura) 2. e) Se lee el bit de reconocimiento (ACK) recibido del esclavo y se introduce ese bit en SSPCON2<6>. k) Se genera una condición de STOP poniendo a 1 el bit de habilitación de STOP (PEN) de SSPCON2. STOP * NACK 4. START 5. c) Se carga SSPBUF con la dirección a enviar por el bus y el bit R/W=0. se pone a 1 el flag SSPIF. . l) Una vez detectada la condición de STOP.Configurar interrupciones (si se necesitan) SSPIE / SSPIF BCLIE / BCLIF SSPADD ← [(f osc/Bd) / 4] – 1 Control del slew rate (SSPSTAT<7>) Implementar alguno de los 6 eventos I 2C. SSPIF=1 (se debe poner a 0 por software). .Seleccionar los baudios de la comunicación.

Esto da lugar a que se ejecuten secuencias de START sin ser precedidas de la correspondiente secuencia de STOP. el Maestro no cede el control del bus en ningún momento. A continuación se puede enviar un ACK. Esto da lugar a que la línea SDA pase a “0” mientras SCL está a “1”. De este modo. Bit SSPCON2<0>. Comunicación Serie Síncrona I2C Generación de una secuencia STOP Hacer PEN ← 1 para habilitar la generación de STOP. SSPIF ← 1. Bit SSPCON2<3>. que da lugar a: S←1 SEN ← 0 SSPIF ← 1 (SSPSTAT<3>) (SSPCON2<0>) (PIR1<3>) Generación de una secuencia de START repetido Hacer RSEN ← 1 para habilitar la generación de RESTART. . Entran bits cada pulso de SCL en SSPSR.Comunicación Serie Síncrona I2C Generación de una secuencia START Hacer SEN ← 1 para habilitar la generación de START. En ese momento SCL=0 y hay que leer el buffer para hacer BF ← 0. Bit SSPCON2<1>. SSPSR ← SSPBUF. Se indica así que ha finalizado la recepción/transmisión. BF ← 1. Así se define una secuencia START. Bit SSPCON2<2>. El bus I2C queda libre y se tiene: P←1 PEN ← 0 SSPIF ← 1 (SSPSTAT<4>) (SSPCON2<2>) (PIR1<3>) Generación de una lectura (recepción) Hacer RCEN ← 1 para habilitar una lectura. Tras el 8º bit. RCEN ← 0. Esto da lugar a que la línea SDA pase a “1” mientras SCL está a “1”.

El Maestro libera entonces SDA para recibir ACK. un STOP o un STOP/START. . No tiene asociada ninguna interrupción. Bit SSPCON2<4>.Tras el 9º pulso de reloj. . Esto libera la línea de datos (SDA ← 1).Comunicación Serie Síncrona I2C Generación de un ACK Indicar en ACKDT si se va a generar un ACK (“0”) o un NACK (“1”). Bit SSPCON2<5>. El Maestro puede recibir un NACK si hay un error en el Esclavo o si éste está desbordado. . ACKEN ← 0 automáticamente. Se produce colisión de bus cuando el dato cambia mientras SCL=1 o si se detecta SDA=0 cuando SDA debería ser 1 (estar libre). el dato en SDA debe ser estable. ¡¡IMPORTANTE!! Antes de iniciar un evento es necesario que el evento anterior haya finalizado. Las colisiones de bus sí tienen asociada una interrupción: BCLIF. Hacer ACKEN ← 1 para habilitar la generación de ACK. En ese caso se hace BCLIF ← 0 y se pone la lógica I 2C en reposo. . La siguiente secuencia deberá ser un START.Cuando se ha enviado el 8º bit. Conviene desarrollar rutinas que comprueben si el módulo está inactivo antes de lanzar un nuevo evento Generación de una escritura (transmisión) Basta con escribir el dato a enviar en SSPBUF. Según la situación. Un NACK puede indicar error o simplemente un estado de funcionamiento que debe ser detectado y procesado. SSPIF ← 1. BF ← 0. Comunicación Serie Síncrona I2C Control de errores en modo Maestro Las colisiones por escritura deben controlarse mediante observación del bit WCOL (SSPCON<7>). . Tras este pulso de reloj.BF ← 1 mientras se está enviando el dato. Cuando SCL=1. el Maestro deberá generar un RESTART. para que el receptor la ponga a “0” durante un pulso de reloj. Una colisión de escritura sucede cuando se intenta escribir un dato en el buffer antes de que haya terminado el evento anterior. Es obligatorio mandar un ACK/NACK al final de cada transferencia.

Si el PIC está en modo Maestro.Comunicación Serie Síncrona I2C Bus I2C en el compilador C de CCS Configuración del módulo I 2C #use i2c (opciones) opciones: MASTER SLAVE SCL = pin SDA = pin ADDRESS = nn FAST SLOW NOFORCE_SW RESTART_WDT Selecciona modo Maestro Selecciona modo Esclavo Especifica el pin SCL (PIN_C3) Especifica el pin SCL (PIN_C4) Especifica la dirección del Esclavo Selecciona la especificación I2C rápida Selecciona la especificación I2C lenta Utiliza funciones I2C hardware. El modo Esclavo . --El modo Esclavo . . sin embargo. i2c_stop (). . Resetea el WDT mientras espera a hacer una lectura de bus 2C por software. deberá usarse con el MSSP. esta instrucción genera una secuencia START. Si se lanza otra secuencia START antes de que se produzca una secuencia STOP. tras la cual la línea SCL se pone a “0” hasta que se escribe en el bus. MSSP.implementará Sino nose seindica indica NOFORCE_SW NOFORCE_SW implementaráel elprotocolo protocoloI I2 C por software. Si el PIC está en modo Maestro. sin embargo. deberá usarse con el MSSP. --Pensado Pensadopara paraaquellos aquellosmicrocontroladores microcontroladoresPIC PICque queno nodisponen disponende deMSSP. Si . Comunicación Serie Síncrona I2C Secuencias de START y STOP i2c_start (). esta instrucción genera una secuencia STOP. se habrá ejecutado una secuencia RESTART.

Bit opcional → 0 indica no enviar ACK 1 indica enviar ACK (valor por defecto) Lee el dato presente en el bus I2C.Comunicación Serie Síncrona I2C Escritura en el bus I 2C i2c_write (dato). valor1 = i2_poll(). Entero de 8 bits a sacar por el bus. dato: ack: Entero de 8 bits. Se usa junto con i2c_poll() para evitar que el programa se ‘cuelgue’. Esta función puede devolver el bit ACK que envía el receptor cuando la transmisión ha terminado. El LSb del primer dato transmitido tras una secuencia de START indica el sentido en que se pretende establecer la comunicación (si dicho LSb es “0”. dato: valor1 : valor1 = i2c_write (dato). se incluye la opción RESTART_WDT en la directiva #use i2c(). esta función generará además la señal de reloj que marca la velocidad de transmisión del dato. Comunicación Serie Síncrona I2C Lectura del bus I 2C dato = i2c_read([ack] ). En modo Maestro. Bit que recoge el valor del ACK enviado por el receptor. la información se transmitirá de Maestro a Esclavo). Sólo se usa en PICs que disponen de MSSP. Manda un byte al bus I2C. se esperará por la señal de reloj que genere el Maestro. en modo Esclavo. 1 (TRUE) si se ha recibido un byte en el buffer. . Para que el watchdog se resetee mientras se espera a poder leer el dato. valor1 : 0 (FALSE) si no se ha recibido un byte en el buffer.