MICROCONTROLADORES Y LENGUAJE C
Fundamentos de Lenguaje Lenguaje C para PICs
Introducción En un programa en C se pueden diferenciar varios elementos. * Directivas de preprocesado /* FORMATO TIPO DE FICHERO - Indican al compilador compilador cómo cómo debe generar el código máquina.
* Funciones
- Bloques funcionales funcionales del programa. - Siempre debe debe incluirse una una función llamada main().
* Sentencias
- Instruccione Instruccioness que definen definen lo que hace el programa y la secuencia de ejecución del mismo.
#include #include
C*/
//Directiva
/* Suma dos enteros */ int suma (int a,b) { return (a+b);
//Devuelve suma
}
/* Función principal */ main() { int dato1,dato2; //Declaración int res; //Declaración
* Comentarios
- Impre Imprescind scindibles ibles como documentación del código fuente.
dato1=5; dato2=3;
//Asignación //Asignación
res=suma(dato1,dato2); }
Fundamentos de Lenguaje Lenguaje C para PICs
Variables Una variable es un nombre asignado a una o varias posiciones de memoria RAM. En C es necesario necesario declarar declarar todas las variables variables antes de poder poder utilizar utilizarlas, las, indic indicando ando el nombre asignado asignado y el tipo de datos que en ella se van a almacenar (opcionalmente (opcionalmente también el valor inicial asignado). asignado).
tipo nombre nombre_variable _variable [=va [=valor]; lor];
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 variables locales locales sólo pueden ser usadas 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 Lenguaje C para PICs
Introducción En un programa en C se pueden diferenciar varios elementos. * Directivas de preprocesado /* FORMATO TIPO DE FICHERO - Indican al compilador compilador cómo cómo debe generar el código máquina.
* Funciones
- Bloques funcionales funcionales del programa. - Siempre debe debe incluirse una una función llamada main().
* Sentencias
- Instruccione Instruccioness que definen definen lo que hace el programa y la secuencia de ejecución del mismo.
#include #include
C*/
//Directiva
/* Suma dos enteros */ int suma (int a,b) { return (a+b);
//Devuelve suma
}
/* Función principal */ main() { int dato1,dato2; //Declaración int res; //Declaración
* Comentarios
- Impre Imprescind scindibles ibles como documentación del código fuente.
dato1=5; dato2=3;
//Asignación //Asignación
res=suma(dato1,dato2); }
Fundamentos de Lenguaje Lenguaje C para PICs
Variables Una variable es un nombre asignado a una o varias posiciones de memoria RAM. En C es necesario necesario declarar declarar todas las variables variables antes de poder poder utilizar utilizarlas, las, indic indicando ando el nombre asignado asignado y el tipo de datos que en ella se van a almacenar (opcionalmente (opcionalmente también el valor inicial asignado). asignado).
tipo nombre nombre_variable _variable [=va [=valor]; lor];
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 variables locales locales sólo pueden ser usadas 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 Lenguaje C para PICs El compilador de CCS acepta los siguiente tipos de variable. C n e s o c i s á b
Especificación
Significado
Tamaño
R an g o
char
carácter
8 bits
0 a 255 (sin signo)
int
entero
8 bits
0 a 255 (sin signo) 6 bits de precisión
float
coma flotante
32 bits
s o p i t
double
float float doble precisión
no soportado
No para PCM
s o L
void
sin valor
nulo
ninguno
int1
entero de de 1 bit
1 bit
0a1
int8
entero de d e 8 bits
8 bits
0 a 255 (sin signo)
int16
entero de 16 bits
16 bits
0 a 65535
int32
entero de 32 bits
32 bits
0 a (2 32-1)
short
entero de d e 1 bit
1 bit
0a1
lo n g
entero de 16 bits
16 bits
0 a 65535
(sin signo)
(sin signo)
Los tipos de variable short short y y long pueden tener detrás la palabra int sin efecto alguno.
Fundamentos de Lenguaje Lenguaje C para PICs Todos los tipos de datos son por defecto sin signo (unsigned ( unsigned)) salvo los de tipo float 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
Significado
Tamaño
R an g o
signed char
carácter carácter con signo
8 bits
-128 a 127
signed int
entero con signo
8 bits
-128 a 127
signed long
coma flotante
16 bits
-32768 a 32767
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
Fundamentos de Lenguaje C para PICs
Funciones Las funciones son los bloques constructivos fundamentales en C. Todas las sentencias deben encontrarse dentro de funciones. Las funciones deben ser definidas antes de ser utilizadas. Formato general de definición de una función
tipo_dato nombre_func (tipo param1 , tipo param2 , … ) { cuerpo de la función (sentencias); } Las funciones pueden devolver un valor a la sentencia que las llama. El tipo de dato devuelto se indica mediante tipo_dato. Si no se indica nada, se entiende que devuelve un entero. Si no devuelve nada, debe incluirse una especificación tipo void.
Fundamentos de Lenguaje C para PICs La manera que tiene una función para devolver un valor es mediante la sentencia return. return (expresión);
return expresión;
La expresión debe proporcionar el mismo tipo de dato que el especificado en la función. Si no debe devolver nada, se finaliza con return;
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, 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.
3
Fundamentos de Lenguaje C para PICs Además de devolver valores, una función también pued e recibir parámetros (denominados argumentos) según se indicó en su definición. Por ejemplo:
int suma (int a , int b) { return (a+b); }
Parámetros formales
main() { int c;
Argumentos de llamada
c = suma (10 , 23); }
Los argumentos se pueden pasar a las funciones por valor o por referencia. La llamada por valor copia el argumento de llamada en el parámetro formal de la función. No modifica su valor en la función de partida. La llamada por referencia usa la dirección de la variable que se pasa a la función. Se consigue usando punteros o arrays.
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).
Operadores aritméticos +
-
*
/
% (resto de división de enteros)
Operadores incremento y decremento x++
ó
++x
x --
Operadores relacionales >
>=
Operadores lógicos &&
||
<
!
<=
==
ó
--x !=
(usados en los condicionales)
Operadores a nivel de bits & AND a&b
| OR a|b
^ ~ >> << XOR Comp1 Dcha Izda a^b ~a a >> n a << n
En lenguaje C “profesional” es muy frecuentes usar abreviaturas.
Así, por ejemplo, es más habitual ver a += b; que a = a + b;
4
Fundamentos de Lenguaje C para PICs
Sentencias de control de programa Sentencia if.
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). Si es cero (falso) continúa sin ejecutar la sentencia o bloque de sentencias. if (expresión) sentencia;
if (expresión) { sentencia 1; sentencia 2; ... }
Sentencia if-else.
Se evalúa una expresión y, si es cierta, se ejecuta el primer bloque de código (o sentencia 1). Si es falsa, se ejecuta el segundo. n a r if (expresión) sentencia 1; else sentencia 2; Abr eviat ura
i c o m b a r a n e p d e p u l s e S e i f - e ú l t i p l e s m v a r i o s l ec e r . b c i s i ó n a e t s d e e d o s c a m i n
(expresión) ? (sentencia 1) : (sentencia 2);
Fundamentos de Lenguaje C para PICs Sentencia switch.
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. Cuando se da una coincidencia, el cuerpo de sentencias asociadas a esa constante se ejecuta hasta que aparezca break. switch (expresión) { case constante 1: grupo 1 de sentencias; break;
break es opcional. Si no aparece se sigue con el case siguiente.
case constante 2: grupo 2 de sentencias; break; b e r d e h a s e u p N o n t e s e o n s t a d o s c e n d o s c a s i g u a l e l a m i s m a c h . d e a s w i t nc i s e n t e
... default: grupo n de sentencias;
default es opcional y el bloque asociado se ejecuta sólo si no hay ninguna coincidencia con las constantes especificadas.
}
5
Fundamentos de Lenguaje C para PICs Sentencia de bucle for.
Se emplea para repetir una sentencia o bloque de sentencias. for (inicialización ; condición ; incremento) { sentencia(s); }
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. La condición se evalúa antes de ejecutar la sentencia. Si es cierta, se ejecuta el bucle. Si no, se sale del mismo. El incremento establece cómo cambia la variable de control cada vez que se repite el bucle.
Es posible anidar bucles for para modificar dos o más variables de control.
Fundamentos de Lenguaje C para PICs Sentencia de bucle while.
La repetición se lleva a cabo mientras sea cierta una expresión. while (expresión) { sentencia(s); }
La expresión se evalúa antes de cualquier iteración. Si es falsa, ya no se ejecuta la sentencia o bloque de sentencias.
Sentencia de bucle do-while. do { sentencia(s); } while (expresión)
Las sentencias se ejecutan antes de que se evalúe la expresión, por lo que el bucle se ejecuta siempre al menos una vez.
6
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. Son ignorado s por el compilador y no afectan a la longitud ni rapidez de ejecución del código final. Un comentario se puede colocan en cualquier lugar del pro grama y pueden tener la longitud y el número de líneas que se quiera. Hay dos formatos posibles para los comentarios. Formato 1. Empiezan por // y finalizan con el final de la línea.
// Esto es un comentario. Formato 2. Empiezan por /* y finalizan por */. No es posible anidar comentarios con este formato. /* 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 ). Al final de esta sección se incluyen sendas listas con las di rectivas y las funciones integradas correspondientes al compilador de CCS.
Directivas de preprocesado más habituales #ASM #ENDASM
Las líneas entre estas dos directivas deben ser instrucciones ensamblador que se insertan tal y como aparecen.
#BIT id=x.y
Se crea una variable tipo bit correspondiente al bit y del byte x en memoria.
#BYTE id=x
Se crea una variable y se sitúa en el byte x en memoria. Si ya existía esa variable, se coloca físicamente en la posición especificada.
7
Fundamentos de Lenguaje C para PICs #DEFINE id texto
El identificador se sustituye por el texto adjunto.
#DEVICE chip
Define el micro para el que se escribe el código.
#FUSES options
Define la palabra de configuración para la grabación del microcontrolador.
#INCLUDE Se incluye el texto del fichero especificado en el #INCLUDE “fichero” directorio o fuera de él. #INLINE
La función que sigue a esta directiva se copia en memoria de programa cada vez que se le llame. Puede servir para mejorar la velocidad.
#SEPARATE
La función que sigue a esta directiva se implementa de manera separada (no INLINE). De esta manera se ahorra ROM
#ORG start
Sitúa el código a partir de una determinada posición de la memoria de programa
Fundamentos de Lenguaje C para PICs #INT_xxxx
Indica que la función que sigue es un programa de tratamiento de la interrupción xxxx.
#INT_GLOBAL
Indica que la función que sigue es un programa genérico de tratamiento de interrupción. No se incluye código de salvaguarda de registros ni de recuperación como cuando se usa #INT_xxxx.
#PRIORITY ints
Establece un orden de prioridad en las interrupciones.
#USE DELAY (clock = frecuencia en Hz) Define la frecuencia del oscilador que se va a utilizar, que se emplea para realizar los cálculos para funciones integradas de retardo. #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.
8
Fundamentos de Lenguaje C para PICs
o d S a C s C e e c o d r s p e e r r o P d a e l d i p s a m v o i t c c a e r r a i p D
Fundamentos de Lenguaje C para PICs
) I ( s S a C d C a e r d g e s t e n r I o s d a e l n i o p i c m n o u C F a r a p
9
Fundamentos de Lenguaje C para PICs
) I I ( s S a C d C a r e g d e t s n e I r o s d e l a n i o i p c m n o u C F a r a p
10
PUERTOS DE E/S
Puertos de E/S
Características generales en el PIC16F877 Presenta cinco puertos E/S configurables.
* PORTA * PORTB * PORTC * PORTD * PORTE
6 pines 8 pines 8 pines 8 pines 3 pines
(0X05) (0X06 y 0x106) (0X07) (0X08) (0X09)
TOTAL 33 pines de E/S Dirección de los datos configurables. Registros de dirección de datos.
* TRISA * TRISB * TRISC * TRISD * TRISE
(0x85) (0x86) (0x87) (0x88) (0x89)
s o l u d ó m s o r t o n o c o d a x e l p i t l u M o t n e i m a n o i c n u F
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.
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.
* Usando las funciones integradas específicas del compilador.
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.
La primera de las dos opciones indicadas constituye la manera má s directa de trabajar con los puertos E/S. Cuando se usan las funciones integradas del compilador de CCS, el código que introduce el compilador puede variar en cuanto a tamaño y tiempo de ejecución.
Dependerá de la activación de ciertas directivas de preprocesado (#USE FAST_IO - #USE FIXED_IO - #USE STANDARD_IO)
1
Puertos de E/S
Opción 1. 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.
Para ello resulta muy adecuada la directiva #BYTE. #BYTE TRISB = 0x86 // Define la variable TRISB y la sitúa en 86h. #BYTE PORTB = 0x06 // Define la variable PORTB y la sitúa en 06h.
A partir de este punto, estas variables permiten controlar los puertos y se pueden utilizar en sentencias de asignación.
TRISB = 0xF0; // 4 bits altos entradas y 4 bajos, salidas. ...... PORTB = 0x0A; // Asignación a los 4 bits de salida. numero = PORTB; // Lectura del puerto B. ...... if (PORTB & 0xF0) PORTB|= 0x0F;
Puertos de E/S
El compilador de CCS incorpora una serie de funciones integradas que permite manejar los bits de una variable previamente definida. bit_clear (var , bit); Pone a 0 el bit especificado de la variable. bit_set (var , bit); Pone a 1 el bit especificado de la variable. bit_test (var , bit); Muestra el bit especificado de la variable. swap (var); Intercambia los nibbles de la variable.
#BYTE PORTB = 0x06 // Declaración previa de PORTB. ...... bit_set (PORTB , 5); ...... if (! bit_test(PORTB , 2)) bit_set (PORTB , 2); También se puede declarar un bit de un registro con una variable mediante la directiva #BIT y trabajar directamente con la variable.
#BIT nombre = posición.bit #BIT RA4 = 0x05.4 ...... RA4 = 0;
2
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_lo output_ low w (pin (pin*) *);; output_ out put_hig high h (pi (pin*) n*);; output_bit (pin* , valor); output_ out put_flo float at (pin (pin*); *);
Pone a 0 el pin espec Pone especific ificado. ado. Pone a 1 el pin especificado. Pone el pin especificado al valor valor indicado. indicado. Define el pin como entrada, quedando a tensión flotante (simula salida en drenad dre nador or abiert abierto) o)
output_a (valor); output_b (valor); output_c (valor); output_d (valor); output_e (valor);
Saca el valor indicado (0-255) en el puerto correspondiente correspondiente..
port_b_pul port_ b_pullu lups ps (val (valor); or);
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 (valor); set_tris_b (valor); set_tris_c (valor); set_tris_d (valor); set_tris_e (valor);
Carga el registro de dirección de datos con el valor indicado.
inpu in putt (pin (pin*) *);;
Devuelve el estado del pin señalado.
input_a ( ); input_b ( ); input_c ( ); input_d ( ); input_e ( );
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 #def #d efin inee #def #d efin inee #def #d efin inee
PIN_A0 PIN IN__A1 PIN_ PI N_A2 A2 PIN_ PI N_A3 A3
40 41 42 43
! ! ! O J O ¡ ¡ ¡ O
L ES IA B VA R N O N O S
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 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 TRIS correspondiente). Si se trata de una función función input...() 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 información ó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 FIXED_IO (B_OUTPUTS = PIN_B2 PIN_B2 , PIN_B3)
El efecto de colocar colocar una u otra directiva se puede puede observar en los ficheros *.lst *.lst que se generan como resultado de la compilación. com pilació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
Interrupciones
Introducción En los 16F877 hay 14 fuentes posibles de interrupción. Cuando se da un evento en un determinado módulo, el flag asociado se pone a 1 y, si las máscaras global (GIE) y particular (y en algunos casos la de periféricos (PEIE)) están habilitadas, se acepta la interrupción. En ese caso, el hardware interno del PIC ejecuta varias acciones. 1. Se pone GEIE a cero para no aceptar otra interrupción. 2. Se almacena la dirección de retorno en la pila. 3. El contador de programa se carga con la dirección 0x0004 (que es la dirección común para todas las interrupci ones).
El programador debe asegurarse de que el código se encarga de identificar la fuente de la interrupción, 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. Estas tareas quedan enormemente simplificadas usando directivas y funciones del lenguaje C del compilador de CCS.
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). En el caso de los PIC 16F877 hay 14 posibles directivas. (T0IF) #INT_RTCC Desbordamiento de TMR0. (RBIF) #INT_RB Cambio en los pines RB<4:7>. (INTF) #INT_EXT Flanco en pin RB0. (ADIF) #INT_AD Fin de conversión A/D. (TXIF) #INT_TBE Buffer de transmisión USART vacío. (RCIF) #INT_RDA Dato recibido en USART. (TMR1IF) #INT_TIMER1 Desbordamiento de TMR1. (TMR2IF) #INT_TIMER2 Desbordamiento de TMR2. #INT_CCP1 Captura / Comparación en módulo CCP1. (CCP1IF) #INT_CCP2 Captura / Comparación en módulo CCP2. (CCP2IF) #INT_SSP Envío / Recepción de dato serie síncrono. (SSPIF) #INT_PSP Dato entrante en puerto esclavo paralelo. (PSPIF) (BCLIF) #INT_BUSCOL Colisión de bus I2C. #INT_EEPROM Escritura completa en EEPROM de datos. (EEIF)
1
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.
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. 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. El programador debe seguir encargándose de habilitar las interrupciones.
Interrupciones
Funciones para gestión de interrupciones El compilador C de CCS incluye algunas funciones integradas destinadas a manejar interrupciones. enable_interrupts (nivel); nivel es una constante definida en 16F877.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. Las otras sólo activan la máscara particular y el PEIE si es necesario. disable_interrupts (nivel); Hace la acción contraria a la función anterior, poniendo a 0 las máscaras relacionadas con la interrupción indicada.
2
Interrupciones Existe también una función adicional destinada a configurar el flanco activo que genera la interrupción externa (en RB0). ext_int_edge (H_TO_L); Selecciona flanco de bajada para activar el flag INTF. ext_int_edge (L_TO_H); Selecciona flanco de subida para activar el flag INTF. #INT_EXT ext_isr() { ......}
enable_interrupts (INT_EXT); // Activa máscara INTE ext_int_edge (H_TO_L); // Flag INTF si flanco de bajada. enable_interrupts (GLOBAL); // Habilita máscara global de int. /* Si entra una interrupción por flanco de bajada en RB0, se irá a la función que aparece tras la directiva #INT_EXT */ disable_interrupts (INT_EXT); // Desactiva interrupciones en RB0. disable_interrupts (GLOBAL); // Desactiva todas las interrupciones.
3
MÓDULOS
TEMPORIZADORES
Módulos Temporizadores
Características generales Temporizador TMR0. Contador / Temporizador de 8 bits que se pueden leer y escribir. Prescaler de 8 bits programable por software. Generación de interrupción al desbordarse de FFh a 00h. Se puede seleccionar el flanco activo si se usa reloj externo.
Temporizador TMR1. Contador / Temporizador de 16 bits que se pueden leer y escribir. Prescaler programable por software. Generación de interrupción al desbordarse de FFFFh a 0000h. Puede activarse o desactivarse.
Temporizador TMR2. Temporizador de 8 bits que se pueden leer y escribir. Prescaler para el reloj y postscaler para la salida. TMR2 se incrementa hasta alcanzar el valor de PR2. Puede activarse o desactivarse.
Módulos Temporizadores
Temporizador TMR0 / WDT Registro OPTION_REG (81h , 181h) RBPU
bit 7 bit 6 bit 5
INTEDG
T0CS
T0SE
PS1
PS0
1: Reloj externo (RA4)
T0SE: Selección del flanco activo del reloj externo 0: Flanco de subida
bit 3
PS2
RBPU INTEDG T0CS: Selección del reloj a utilizar 0: Reloj interno (f CLK/4)
bit 4
PSA
1: Flanco de bajada
PSA: Asignación del prescaler 0: Asignado a TMR0
1: Asignado a WDT
bits 2:0 PS2:PS0: Prescaler 0 00 : 00 1: 0 10: 011 :
1:2 para TMR0 / 1:1 para WDT. 1:4 para TMR0/ 1:2 para WDT. 1:8 p ara TMR0 / 1:4 p ara WDT. 1:16 para TM R0 / 1:8 par a WDT.
1 00: 1 01 : 1 10 : 1 11:
1: 32 p ar a TMR0 / 1:16 p ar a WDT. 1:64 para TMR0 / 1:32 para WDT. 1:128 para TMR0 / 1:64 para WDT. 1:256 para TMR0 / 1:128 para WDT.
1
Módulos Temporizadores
Diagrama de bloques de TMR0 / WDT. CLKOUT (f OS C/4)
Bus de datos 0
RA4 / T0CKl
1 T0SE
M P X
1 0
8
M P X
SYNC 2 ciclos
TMR0
T0CS
Levanta flag T0IF al desbordarse
PSA
0
Watchdog Habilitación de WDT
1
M P X
Prescaler de 8 bits 8
Mpx 8:1
PS2:PS0
PSA 0
1
MPX
PSA
Temporización del WDT
Módulos Temporizadores
TMR0 / WDT en el compilador C de CCS Configuración del módulo TMR0. setup_timer_0 (modo); modo :
RTCC_INTERNAL RTCC_EXT_L_TO_H RTCC_EXT_H_TO_L
(OPTION_REG ← 00h) (OPTION_REG ← 20h) (OPTION_REG ← 30h)
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 (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 |.
2
Módulos Temporizadores
Configuración del módulo WDT. setup_wdt (modo ); 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. #fuses #fuses
[opciones], WDT [opciones] [opciones], NOWDT [opciones]
Watchdog activado Watchdog desactivado
Módulos Temporizadores
Configuración de los módulos TMR0 y WDT (obsoleto). Funciones implementadas en el compilador por compatibilidad con versiones anteriores. No se recomienda su uso. setup_counters (rtcc , prescaler);
rtcc:
RTCC_INTERNAL RTCC_EXT_L_TO_H RTCC_EXT_H_TO_L
(OPTION_REG ← 00h) (OPTION_REG ← 20h) (OPTION_REG ← 30h)
prescaler:
RTCC_DIV_2 ... RTCC_DIV_256
(OPTION_REG ← 00h)
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)
... (OPTION_REG ← 07h)
3
Módulos Temporizadores
Escritura en el módulo TMR0. set_timer0 (valor ); valor:
Entero de 8 bits.
(TMR0 ← valor)
Lectura del módulo TMR0. valor = get_timer0 (); valor:
Puesta a cero del
Entero de 8 bits.
(valor ← TMR0)
.
W at chdog
restart_wdt (); No precisa ningún parámetro.
(equivale a CLRWDT)
Módulos Temporizadores
Ejemplo #fuses RC, WDT,PUT,NOPROTECT,BROWNOUT,NOLVP,NOWRT,NOCPD #int_rtcc rutina() { ... }
setup_timer_0 (RTCC_INTERNAL);
Configurar Configurar elel módulo módulo TMR0 para generar TMR0 para generar una una interrupción cada 100µs. interrupción cada 100µs. Activar Activar elel wat watchdog chdog para para evitar bucles infinitos. evitar bucles infinitos. fosc = 3MHz
Banco 1 W ← OPTION_REG W ← W & 11000000 OPTION_REG ← W Banco 0
setup_wdt (WDT_72MS); W ← OPTION_REG W ← W & 11000000 W ← W | 00001 010
enable_interrupts (INT_RTCC); enable_interrupts (GLOBAL); INTCON ← 11100000
TMR0 = 183 (prescaler 1:1)
set_timer0 (183); 18 3
TMR0 ← 10110111
while (1) restart_wdt();
4
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. Prescaler 1:2.
10: 11:
Prescaler 1:4. Prescaler 1:8.
T1OSCEN: Habilitación del oscilador de TMR1
bit 3
0 : Apagado
1: Habilitado
T1SYNC: Control de la sincronización con el reloj externo
bit 2
Sólo si TMR1CS=1 0: Sincronizar
1: No sincronizar
TMR1CS: Reloj de TMR1
bit 1
1: Reloj externo (↑ en RC0).
0: Reloj interno (fOSC/4).
TMR1ON: Bit de encendido de TMR1
bit 0
0: TMR1 apagado.
1: TMR1 encendido.
Módulos Temporizadores
Diagrama de bloques de TMR1. Levanta flag TMR1IF al desbordarse
TMR1H
0
TMR1L
Entrada de reloj sincronizada
1 TMR1ON On/off
RC0 T1OSO T1CKl
T1SYNC
T1OSC 1
0
RC1 T1OSI CCP2
TMR1CS T1OSCEN Habilita oscilador
Prescaler 1,2,4,8 2
T1CKPS1:T1CKPS0
Detección de sincronización Reloj interno
fOSC/4 Reloj interno
5
Módulos Temporizadores
TMR1 en el compilador C de CCS Configuración del módulo TMR1. setup_timer_1 (modo); modo :
T1_DISABLED T1_INTERNAL T1_EXTERNAL T1_EXTERNAL_SYNC
(T1CON (T1CON (T1CON (T1CON
T1_CLK_OUT
(T1CON ← 08h)
T1_DIV_BY_1 T1_DIV_BY_2 T1_DIV_BY_4 T1_DIV_BY_8
(T1CON ← 00h) (T1CON ← 10h) (T1CON ← 20h) (T1CON ← 30h)
←
00h) 85h) 87h) ← 83h) ← ←
Se pueden agrupar constantes de distintos grupos con |.
Lectura / Escritura en el módulo TMR1. valor = get_timer1 (); valor:
set_timer1 (valor );
Entero de 16 bits.
Módulos Temporizadores
Ejemplo
Configurar Configurar elel módulo módulo TMR1 TMR1 para para generar generar una temporización una temporización de de 1s. 1s.
temp1s() { unsigned cont=0; while (cont<2) { set_timer1 (18661); while (get_timer1()>=18661); cont++; } }
f osc = 3MHz 2 × TMR1 = 18661 (prescaler 1:8)
main () { ... setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8); ... temp1s(); T1CON ← 10110101 ... }
6
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: ..... 1111:
bit 2
Postscaler 1:1 Postscaler 1:2 Postscaler 1:3 Postscaler 1:16
TMR2ON: Bit de encendido de TMR2 0 : Apagado
1: Habilitado
bits 1:0 T2CKPS1:T2CKPS0: Selección del prescaler 00 : 01 : 1 x:
Prescaler 1 Prescaler 4 Prescaler 1 6
Módulos Temporizadores
Diagrama de bloques de TMR2.
Levanta flag TMR2IF al desbordarse
Salida de TMR2 (1)
RESET
Postscaler 1:1 a 1:16 4
=
TMR2
Prescaler 1 , 4 , 16
fOSC/4 Reloj interno
2
Comparador
T2CKPS1:T2CKPS0
PR2
T2OUTPS3:T2OUTPS0
(1)
La salida de TMR2 puede ser usada por el módulo SSP.
7
Módulos Temporizadores
TMR2 en el compilador C de CCS Configuración del módulo TMR2. setup_timer_2 (modo,periodo,postscaler); modo :
T2_DISABLED T2_DIV_BY_1 T2_DIV_BY_4 T2_DIV_BY_16
periodo :
Entero de 8 bits (0-255) que se pasa al registro PR2.
postscaler:
Valor del postscaler (1-16).
Lectura / Escritura en el módulo TMR2. valor = get_timer2 (); valor:
(T2CON ← (T2CON ← (T2CON ← (T2CON ←
00h) 04h) 05h) 06h)
set_timer2 (valor );
Entero de 8 bits.
Módulos Temporizadores
Ejemplo #int_timer2 rutina() { ... }
Configurar Configurar elel módulo módulo TMR2 TMR2 para para generar generar una una interrupción cada 10ms. interrupción cada 10ms. f osc = 3MHz
setup_timer_2 (T2_DIV_BY_16 , 94 , 5); Postscaler 1: 5 Prescaler 1:16 y encendido PR2 = 94
PR2 = 94 (prescaler 1:16) (postscaler 1:5)
W ← 20h W ← W | 00000110 T2CON ← W W ← 1Ch Banco 1 PR2 ← W Banco 0
enable_interrupts (INT_TIMER2); enable_interrupts (GLOBAL); PIE1 ← 00000010 INTCON ← 11000000
while (1);
8
PERIFÉRICOS DE E/S
Periféricos de E/S
Teclados Muy utilizado para introducir información al microcontrolador. Los hay de varios tipos: de lámina flexible, de efecto Hall, de efecto inductivo, de efecto capacitivo. Los más comunes son los de lámina flexible.
El problema de los rebotes. Debido al efecto muelle del pulsador, se producen oscilaciones en la señal tanto al pulsar como al soltar la tecla.
u1
+Vcc
SOLUCIONES SOLUCIONES
IDEAL u1
t
u1
R REAL
t
Hw: Hw: Red Red R-C R-C Biestables Biestables Sw: Sw: Espera Esperade de un tiempo un tiempo suficiente suficiente
Periféricos de E/S
Teclados lineales Muy sencillos, pero no permiten disponer de muchas teclas. +Vcc
E0
De este modo, cuando el microcontrolador detecte un “0” al final de la línea, se sabrá que se ha pulsado una tecla y, además, se sabrá cuál ha sido.
E1 En
Basta con que el programa compruebe periódicamente el estado de las entradas a las que se ha conectado el teclado.
1
Periféricos de E/S
Teclados matriciales Varias teclas controladas con un número reducido de puertos E/S. +Vcc
SF1 SF2 SF3 SF4 E C1 E C2 E C3 E C4
La pulsación de una tecla se pone de manifiesto en las entradas del microcontrolador conectadas al teclado.
0 0 0 0 1 1 01 1
En este ejemplo, se sabe que se ha pulsado una tecla de la tercera columna, pero no se sabe cuál. Se necesita desarrollar algoritmos que permitan determinar cuál es la tecla que se ha pulsada.
Periféricos de E/S
Muestreo secuencial. Una vez que se ha detectado que se ha pulsado una tecla, 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. +Vcc
S F1 S F2 S F3 S F4 EC1 EC2 EC3 EC4
1 0 1 1 1 1 0 1
SF1 0 1 1 1
SF2 1 0 1 1
SF3 1 1 0 1
SF4 1 1 1 0
E C1 1 1 1 1
E C2 1 1 1 1
E C3 1 0 1 1
E C4 1 1 1 1
Es un método sencillo de implementar, pero tardará más o menos en encontrar la tecla pulsada en función de la posición que ocupe ésta.
2
Periféricos de E/S
Inversión de línea. Tras detectar que hay una tecla pulsada, 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. +Vcc
EF1 EF2 EF3 EF4 S C1 S C2 S C3 S C4
1 0 1 1 1 1 01 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. Como todos los bits son entrada en algún momento, se necesita colocar resistencias en los 8 bits. Este método es más rápido que el anterior y tarda lo mismo en identificar cualquier tecla.
Periféricos de E/S
Conexión de teclados matriciales en los PIC. El puerto B de los microcontroladores PIC está especialmente pensado para conectar un teclado matricial de 4 ×4. +Vcc pull-up resistors
RB0 RB1 [S] RB2 RB3 RB4 RB5 [E] RB6 RB7
0 0 0 0 1 1 1 1
F1 F2 F3
* La posibilidad de habilitar resistencias de pull-up reduce el número de componentes externos.
F4
C1 C2 C3
* La existencia de una interrupción asociada a cambios en los bits RB<4:7> avisa de que se ha pulsado una tecla.
C4
3
Periféricos de E/S
Extensión a teclados de más de 16 teclas. Se puede ampliar el tamaño del teclado sin más que utilizar codificadores y decodificadores. +Vcc
SF1 SF2 SF3 SF4 E C1 E C2 E C3 E C4
0 0 0 0 1 1 1 1
Decodif. 4
÷
16
Teclado Matricial 16 16 ×
Codif 16
÷
4
Periféricos de E/S
Pantallas de cristal líquido (LCD) Usado para representar caracteres alfanuméricos. Control bastante complejo. El control directo de los electrodos del LCD casi necesitaría un microcontrolador dedicado exclusivamente a esta tarea. Lo más habitual es utilizar un LCD con un driver específico: el HD44780 de Hitachi o compatible.
4
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. ×
×
Dispone de 240 patrones de caracteres almacenados en ROM, de los cuales 208 de tamaño 5×8 y 32 de tamaño 5 ×10.
HD44780
HD44780
COM1 . .
COM1 . . .
COM8
COM11
Cursor
SEG1 . . . . .
SEG1 . . . . .
SEG40
Cursor
SEG40
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. ×
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).
Visibles 1 ó 2 líneas con 16 caracteres/línea. Ventana de caracteres visibles (16 posiciones) Display r eal
Registro:
1 2
......
11
......
26
......
39 40
Memoria de pantalla para una línea (40 posiciones) Display vi r t ual
5
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. Tiene un tamaño de 2 líneas
×
40 bytes/línea = 80 bytes.
Direcciones no contiguas entre las líneas 1 y 2. 0x00 a 0x27: 40 caracteres de la línea 1. 0x40 a 0x67: 40 caracteres de la línea 2. 00 01 s e n M o A i c R c D e r D i D 40 41
02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
...
25 26 27
42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54
...
65 66 67
Localización en display virtual (x,y).
Display real inicial
x: posición horizontal (de 1 a 40). y: línea (1 ó 2).
Periféricos de E/S
Interface hardware LCD con driver HD44780 Pines externos. 1.- VSS 2.- VDD 3.- VEE 4.- RS 5.- R/W 6.- E 7.- D0 8.- D1 9.- D2 10.- D3 11.- D4 12.- D5 13.- D6 14.- D7
Masa 2,7V a 5,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 (entradas/salidas) Bit de Datos Bit de Datos Bit de Datos Bit de Datos más significativo
6
Periféricos de E/S
DATOS CONTROL
MCU
LCD DATOS
Internos Internos ElEl LCD LCD trabaja trabaja con con 88 bits bits Externos Externos Hay Hay dos dos posibilidades: posibilidades: •• 88 bits bits (D7 (D7 aa D0) D0) (D7 a D4) •• 44 bits bits (D7 a D4)
1º1ºlos los44bits bitsmás másaltos altos 2º los 4 bits más 2º los 4 bits másbajos bajos
BITS BITS DE DE CONTROL CONTROL E: E:
Validación Validación de de datos. datos.
R/W: R/W: Operación Operación de de lectura lectura (1) (1) oo de de escritura escritura (0). (0). RS: RS: Selección Selecciónde de Registro Registro Interno Interno(1: (1:datos datos//0:0:control). control).
Periféricos de E/S
Control del LCD E:
Señal de validación de datos. En las transferencias de información con el LCD (lecturas o escrituras) se debe poner a 1. Si no se usa el LCD, debe permanecer a 0.
R/W: Selecciona lectura (1) o escritura (0) en el LCD. Lo normal es escribir en el LCD, pero es posible leer la RAM y el estado del LCD (ocupado o disponible) y el contador de direcciones. RS:
Se selecciona uno de los dos Registros Internos del LCD. IR (Registro de Instrucciones). Almacena códigos de instrucciones relativas al manejo del display: borrar display, desplazar cursor, definir interface a 4 u 8 bits, etc.
DR (Registro de Datos). Almacena datos a leer o escribir en RAM.
7
Periféricos de E/S
Operaciones de control en el LCD RS=0 (Registro de Control) flag de ocupado (BF) R/W=1 y Leer puntero de direcciones (AC) R/W=0
Envío de comando para funcionamiento interno
BF:
Busy Flag
AC:
A dd r ess Count er
RS=1 (Registro de Datos) Leer contenido de DDRAM o CGRAM Escribir en DDRAM o CGRAM
o Flag de Ocupado. Si está a 1, el LCD está en modo de operación interna y no puede procesar nuevos comandos hasta que se pone a 0. o Contador de Direcciones. 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. El puntero se incrementa o se decrementa (según el modo elegido) de manera automática.
Periféricos de E/S
Secuencias de operación Escritura en un Registro del LCD 1. E 0 2. RS 0 ó 1 y R/W 0 3. E 1 4. Situar dato en el bus 5. E 0 ←
←
←
←
←
Lectura 1. 2. 3. 4. 5.
de un Registro del LCD E←0 RS ← 0 ó 1 y R/W E←1 Leer dato del bus E←0
←
1
8
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. Además sitúa el puntero en la posición 0 de la DDRAM. (1,1)
(1,2)
(16,1) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F1 0 1 1 1 2 1 3 1 4
...
2 52 62 7
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F5 0 5 1 5 2 5 3 5 4
...
6 56 66 7
Cursor a “Casa”:
(16,2)
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. Este comando envía el cursor a la posición (1,1) (puntero en 0x00) y el display real se sitúa en la posición inicial. 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. Si S=1, se desplaza el display real cada vez que se imprime un carácter. El desplazamiento será a la izquierda o a la derecha según el valor de I/D .
Control de Display, Cursor y Parpadeo: 0 0 0 0 1 D C B Si D=0, el LCD no muestra nada pero la DDRAM mantiene su contenido. Se pueden enviar y leer datos normalmente, pero no aparecerá nada en pantalla. Para volver a visualizar normalmente los caracteres de la DDRAM hay que poner D=1. Si C=1, se hace visible el cursor que indica la siguiente posición donde se imprimiría el siguiente carácter que se envíe. Si B=1, el carácter situado en la posición del cursor parpadea con una frecuencia aproximada de 2Hz.
9
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. Si lo que se desplaza es el cursor (S/C=0 ), también se modifica el contador de direcciones. Si se desplaza el display real (S/C=1), no cambia el puntero de direcciones de la DDRAM. Si el display se define de una línea, al llegar a la posición final (carácter 40º) se volvería a la primera con un desplazamiento del cursor. Si el display está definido para 2 líneas, tras el 40º carácter de la primera línea se pasaría al principio de la segunda línea.
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 DL=1, será de 8 bits y si DL=0, será de 4 bits. Si N=1, se gestionan dos líneas; si N=0, se tendrá una única línea activa en el display. Si F=1, se emplean patrones de tamaño 5×10; si puntos.
F=0, son de 5 8 ×
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).
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 .
Leer Contenido de DDRAM Se lee el contenido de la posición DDRAM a la que apunte el contador de direcciones. Tras la lectura, este contador se incrementa o decrementa dependiendo del modo configurado con I/D .
10
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. Para que se ejecute un determinado comando, es necesario que se haya finalizado el anterior. Esto puede asegurare de dos modos: a) Esperar a que el Flag de Ocupado (BF) pase a 0. b) Establecer pausas entre comandos que sean superiores a los tiempos máximos especificados para cada comando.
En el encendido se produce un reset de inicialización con varios efectos preestablecidos. Se produce tras superar los 4,5V y dura unos 10ms.
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.)
F=0 (5 8 puntos) B=0 (sin parpadeo) ×
Durante todo el proceso de inicialización se tiene BF=1.
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 l c d . c que define las funciones indicadas a continuación. lcd_init (); Debe llamarse antes que ninguna otra función del fichero lcd.c. Tal y como aparece en el fichero, además de borrar el display, configura el LCD para trabajar como sigue: a) En formato de 4 bits, con dos líneas y con caracteres de 5 ×8 puntos. b) Con display encendido, cursor apagado y sin parpadeo. c) Con autoincremento del puntero de direcciones y sin desplazamiento del display real.
lcd_gotoxy (x , y ); Establece la posición del LCD a la que se debe acceder. Recuérdese que la primera posición de la primera línea tiene coo rdenadas (1 , 1), y que la primera posición de la segunda línea es la (1 , 2).
11
Periféricos de E/S lcd_putc (dato); Escribe dato en la posición a la que apunta el puntero de direcciones. La variable dato es de tipo char, 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 , y ); Devuelve el carácter que ocupa la posición (x
, y) del LCD.
Por defecto, este driver usa siete bits del puerto B para establecer la comunicación entre el LCD y el microcontrolador. B0 B1 B2 B3
Enable RS R/W -
B4 B5 B6 B7
Bit de datos D4 Bit de datos D5 Bit de datos D6 Bit de datos D7
Periféricos de E/S
También es posible escribir en el LCD usando la siguiente función. printf(lcd_putc,cadena ,vars ); cadena: Cadena de caracteres que puede formarse usando el contenido de una o más variables.
vars:
Variables incluidas en la cadena (separadas por comas).
Para indicar la posición y el tipo de las variables a incluir en la cadena, se usa el formato %wt, donde w es opcional. w:
1-9 Indica el número de caracteres a mostrar (opcional) 01-09 Indica el número de ceros a la izquierda 1.1-9.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
Periféricos de E/S
Algunos ejemplos. printf(lcd_putc , ”Hola”); printf(lcd_putc , ”Tecla %c pulsada %u veces” , key , cont);
Ejemplos de formato. Especificador %03u %u %2u %3u %d %x %X %4X
Valor=18
Valor=254
018 18 18 _ 18 _ 18 12 12 0012
254 254 ??? 254 -2 fe FE 00FE
NOTA: NOTA Sólo se puede visualizar enteros y caracteres en el LCD. 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.c de CCS. 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. ×
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. En concreto hay que cambiar 3 ó 4 valores que se hacen llegar al LCD como comando.
El driver lcd.c está pensado para manejar un LCD usando 4 bits de datos externos al interface. Sería posible adaptarlo para que usara 8 bits. El driver lcd_ATE.c que se facilita con este curso lleva a cabo las modificaciones necesarias.
13
Periféricos de E/S
Para evitar conflicto con la conexión de teclados matriciales, 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. #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, 1=5x10, 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), 0xc, 1, 6}; // These bytes need to be sent to the LCD // to start it up.
0x20
lcd_type << 2
0
0
1
0
0
0
0
0
0
0
1
0
1
0
0
0
0
0
0
0
10
010
01
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
14
Periféricos de E/S
#define lcd_type 2 // 0=5x7, 1=5x10, 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), 0xc, 1, 6}; // These bytes need to be sent to the LCD // to start it up.
0xc
0
0
0
0
1
1
0
0
0
0
0
0
0
1
1
Control del Display y del Cursor 0 0 0 0 1 D C B
Modo de Funcionamiento 0 0 0 0 0 1 I/D S
D → Display on/off C → Cursor on/off B → Parpadeo on/off
I/D → Increm. / Decrem. S → Shift display on/off
0 6
Periféricos de E/S
El driver lcd_ATE.c lleva a cabo una comunicación con el LCD usando 8 bits de datos. 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 lcd_pines_control {{ Bit 0 → boolean nada; boolean nada; Bit 1 → boolean boolean rs; Bit 2 → boolean boolean rw; Bit 3 → boolean boolean enable; Resto bits → int otros : : 4; 4; } lcd_control; lcd_control;
÷
struct lcd_pines_datos lcd_pines_datos {{ int datos:8; datos:8; ã 8 } lcd_datos; lcd_datos;
Como sucede con el driver lcd.c, también en este caso es posible cambiar la asignación de los pines.
bits de datos
#byte lcd_control == 5 #byte trisa = 0x85 #byte lcd_datos = 8 #byte trisd = 0x88
PORTA PORTD
15
Periféricos de E/S
Es posible cambiar los bits de configuración para conseguir que el LCD se comporte como desea el usuario. Lo único que es obligatorio respetar es el bit DL=1 (comunicación a 8 bits) lcd_send_byte(0,0b00111000); lcd_send_byte(0,0b00001100); lcd_send_byte(0,0b00000001); lcd_send_byte(0,0b00000110);
// // // //
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 - 0 1 D C B Display 0 0 1 I/D S
El driver lcd_ATE.c define alguna función que no se recoge en el driver lcd.c suministrado por CCS. // // //
lcd_putc(\t); lcd_putc(\r); lcd_putc(\v);
Avanza el cursor una posición. Retrocede el display real una posición. Avanza el display real una posición.
// //
lcd_clr_line(line);
Borra la línea 'line' y sitúa el cursor en la primera posición de dicha línea.
16
MÓDULOS DE COMPARACIÓN CAPTURA Y PWM
Módulos CCP
Características generales Dos módulos con idéntico funcionamiento. Registro de captura de 16 bits. Registro de comparación de 16 bits. Registro de ciclo de trabajo PWM.
Módulo CCP1. Consta de dos registros de 8 bits: CCPR1H y CCPR1L. Registro de control: CCP1CON. Acción especial: Generada mediante una comparación. Resetea Timer1.
Módulo CCP2. Consta de dos registros de 8 bits: CCPR2H y CCPR2L. Registro de control: CCP2CON. Acción especial: Generada mediante una comparación. Resetea Timer1. Lanza una conversión A/D.
Módulos CCP
Condiciones de funcionamiento Temporizadores necesarios. Modo captura Modo comparación PWM
⇒ ⇒ ⇒
TMR1 TMR1 TMR2
Interacción entre los dos módulos CCP. CCPx
CCPy
Captura
Captura
Interacción
Misma base de tiempos definida en TMR1 Captura Comparación La comparación debe configurarse con la acción especial, que borra TMR1 Comparación Comparación La(s) comparación(es) deben configurarse con la acción especial, que borra TMR1 Las PWMs tendrán la misma frecuencia y tasa de actualización PW M PW M (interrupción TMR2) PW M Captura Ninguna PW M Comparación Ninguna
1
Módulos CCP
Registro CCP1CON / CCP2CON (17h / 1Dh) -
bit 5-4
-
CCPxX
CCPxY
CCPxM3
CCPxM2
CCPxM1
CCPxM0
CCPxX:CCPxY: Bits menos significativos del PWM En modo PWM: Los dos bits menos significativos del ciclo de trabajo. Los ocho bits más significativos están en CCPRxL.
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 de captura, cada flanco descendente Modo de captura, cada flanco ascendente Modo de captura, cada 4º flanco ascendente Modo de captura, cada 16º flanco ascendente
1000 = Modo de comparación, CCPx=1 al igualarse (CCPxIF=1) 1001 = Modo de comparación, CCP x=0 al igualarse (CCPxIF=1) 1010 = Modo de comparación, genera interrupción al igualarse (CCPx invariable, CCPxIF=1) 1011 = Modo de comparación, lanza acción especial (CCPxIF=1, CCPx invariable) CCP1 resetea TMR1 / CCP2 resetea TMR1 y lanza una conversión A/D 11xx = M od o PW M
Módulos CCP
Modo captura Captura en CCPRxH:CCPRxL los 16 bits de TMR1. Cada flanco de bajada en CCPx Cada flanco de subida en CCPx Cada 4º flanco de subida en CCPx Cada 16º flanco de subida en CCPx
r a c a p t u C a d a
F = 1 C C P x I a r a g d a l u
Diagrama de bloques del modo de captura. RCy / CCPx
Prescaler ÷ 1 , 4 , 16
CCPxIF
←
1
CCPRxH CCPRxL
Detección de flanco y
Habilita Captura
TMR1H TMR1L Qs
CCPxCON<3:0>
2
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 funcion e.
Podría generarse una falsa interrupción de captura al cambiar el modo de captura. Se aconseja deshabilitar CCPxIE al cambiar el modo de captura.
También podría generarse una falsa interrupción al cambiar el prescaler. Además, un cambio directo no resetea la cuenta de flancos. 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.
Módulos CCP
Modo comparación Cuando CCPRx coincide con TMR1 (en sus 16 bits): El pin RCy/CCPx se pone a 1 El pin RCy/CCPx se pone a 0 Se genera una interrupción Lanza una acción especial
a l u g a r a d a i d e nc c o i nc i P x I F = 1 C a d a C C
Diagrama de bloques del modo comparación. TMR1 ← 0 (no alza flag TMR1F) GO/DONE ← 1
Lanza acción especial
CCPxIF
←
1
CCPRxH CCPRxL RCy / CCPx
Q
S R
Lógica de salida
Coincidencia
TRISC<2>
Comparador TMR1H TMR1L
CCPxCON<3:0>
3
Módulos CCP
Condiciones de funcionamiento en el modo comparación El pin CCPx debe configurarse como salida. TMR1 debe funcionar en modo temporizador o en modo contador síncrono. En modo contador asíncrono puede que la comparación no funcione.
Cuando se selecciona generar interrupción, el pin CCPx no se ve afectado. Se puede generar una acción especial por hardware.
CCP1: Resetea TMR1. CCP2: Resetea TMR1 y lanza una conversión A/D (si está activado).
E n ningún caso
se pone a 0 el
f lag T MR1I F
Módulos CCP
Modo PWM
T
Genera una salida PWM de 10 bits de resolución
D TMR2 = PR2
Diagrama de bloques del modo PWM.
TMR2 = D TMR2 = 0
Registros de Duty Cycle
CCPRxL CCPxCON<5:4>
CCPRxH (esclavo)
TMR2 (*) TMR2 se concatena con un reloj interno de 2 bits con frecuencia fosc para poder crear una base de tiempos de 10 bits
R
Comparador (* )
Q
RCy / CCPx
S TRISC<2>
Comparador TMR2 0 CCPx 1 (si D 0) CCPRxH CCPRxL ←
PR2
←
≠
←
4
Módulos CCP
Condiciones de funcionamiento en el modo PWM El periodo T se indica en el registro PR2. T = (PR2 + 1) · 4 · T OSC · PRESCALERTMR2
El ciclo de trabajo D se indica en CCPRxL y en CCPxCON<5:4>. D = (CCPRxL:CCPxCON<5:4>) · T OSC · PRESCALER TMR2 CCPRxH es de sólo lectura en PWM. Cuando TMR2 (+ 2 bits) se iguala a CCPxH (+ 2 bits), CCPx ← 0.
Existe una resolución (número de bits) máxima que se puede obtener con el funcionamiento en modo PWM.
log f Res =
f osc
PWM
⋅ PS
2
TMR
log(2)
u e b i t s q n i r e d o i f e r o n ú m s a r p a r a d e . u M á x i m j n a d e a b o s e p u e c ic l o d e t r e l
bits
Módulos CCP f PWM
1,22kHz
4,88kHz 19,53kHz 78,12kHz 156,3kHz 208,3kHz
PRESCALERTMR2
16
4
1
1
1
1
PR2
0xFFh
0xFFh
0xFFh
0x3Fh
0x1Fh
0x17h
Resolución máxima
10 bits
10 bits
10 bits
8 bits
7 bits
5,5 bits
(fosc = 20MHz)
Pasos a seguir para definir una PWM 1. Establecer el periodo T escribiendo en el registro PR2. 2. Establecer el ciclo de trabajo D en CCPRxL y en CCPxCON<5:4>. 3. Configurar el pin CCPx como salida. 4. Fijar el prescaler de TMR2 y activar el temporizador.
(T2CON)
5. Configurar el módulo CCP para funcionar en modo PWM.
5
Módulos CCP
Módulos CCP en el compilador C de CCS Configuración del módulo CCP setup_ccp1 (modo); setup_ccp2 (modo); modo :
CCP_OFF
(CCPxCON ← 00h)
CCP_CAPTURE_FE CCP_CAPTURE_RE CCP_CAPTURE_DIV_4 CCP_CAPTURE_DIV_16
(CCPxCON ← (CCPxCON ← (CCPxCON ← (CCPxCON ←
CCP_COMPARE_SET_ON_MATCH CCP_COMPARE_CLR_ON_MATCH CCP_COMPARE_INT CCP_COMPARE_RESET_TIMER
(CCPxCON ← 08h) (CCPxCON ← 09h) (CCPxCON ← 0Ah) (CCPxCON ← 0Bh)
CCP_PWM CCP_PWM_PLUS_1 CCP_PWM_PLUS_2 CCP_PWM_PLUS_3
(CCPxCON ← 0Ch) (CCPxCON ← 1Ch) (CCPxCON ← 2Ch) (CCPxCON ← 3Ch)
04h) 05h) 06h) 07h)
Módulos CCP
Definición del ciclo de trabajo en modo PWM set_pwm1_ duty (valor ); set_pwm2_ duty (valor ); valor:Dato (8 ó 16 bits) que fija el duty cycle de la PWM. valor XXXXXXXX Y Y Y Y Y Y X X X X X X X X X X
CCPRxL:CCPxCON<5:4> XXXXXXXX0 0 XXXXXXXXXX
Variables definidas en 16F877.h long CCP_1; #byte CCP_1 = 0x15 #byte CCP_1_LOW = 0x15 #byte CCP_1_HIGH = 0x16
long CCP_2; #byte CCP_2 = 0x15 #byte CCP_2_LOW = 0x15 #byte CCP_2_HIGH = 0x16
6
Módulos CCP
Configuración del pin CCPy como entrada/salida set_tris_C (valor ); valor:
Entero de 8 bits, cada uno de los cuales representa la la configuración de un pin del puerto. (“1”⇒E / “0”⇒S)
Configuración del temporizador TMR1 setup_timer_1 (modo); modo :
D e f in p re s e e l ca l e r
T1_DISABLED T1_INTERNAL T1_EXTERNAL T1_EXTERNAL_SYNC
(T1CON (T1CON (T1CON (T1CON
T1_CLK_OUT
(T1CON ← 08h)
T1_DIV_BY_1 T1_DIV_BY_2 T1_DIV_BY_4 T1_DIV_BY_8
(T1CON ← 00h) (T1CON ← 10h) (T1CON ← 20h) (T1CON ← 30h)
← 00h) ← 85h) ← 87h) ← 83h)
Se pueden agrupar constantes de distintos grupos con |.
Módulos CCP
Configuración del temporizador TMR2 setup_timer_2 (modo,periodo,postscaler); modo : D e f in p re e e l sc a l er
T2_DISABLED T2_DIV_BY_1 T2_DIV_BY_4 T2_DIV_BY_16
periodo:
PR2 ← periodo
postscaler:
Número de overflows necesarios para generar una interrupción. Es un valor entre 1 y 16.
(T2CON ← (T2CON ← (T2CON ← (T2CON ←
00h) 04h) 05h) 06h)
CCP, se tomará Para uso con los módulos 1 = aler postsc
7
Módulos CCP
Ejemplo 1 setup_timer_2 (T2_DIV_BY_1 , 224 , 1); 300µs 224 100µs
(fosc = 3MHz)
T = 300µs ⇒ PR2 = 224 D = 100µs ⇒ carga = 301
W ← 00000000 W ← W | 00000100 T2CON ← W W ← E0h Banco 1 PR2 ← W Banco 0
setup_ccp1 (CCP_PWM_PLUS_1); #use standard_io (C )
Carga = 301
W ← 111111011 Banco 1 TRISC ← W Banco 0 RC2 ← 0 CCP1CON ← 0 W ← 00011100 CCP1CON ← W
0100101101
set_pwm1_duty (0x4B); 01 001 01 1
CCPR1L
CCPR1L ← 01001011
01
CCP1CON<5:4>
Módulos CCP
Ejemplo 1 (cont.) setup_timer_2 (T2_DIV_BY_1 , 224 , 1);
224
¡¡ATENCIÓN!! ¡¡ATENCIÓN!! La La instrucción instrucción setup_ccpx setup_ccpx(modo); (modo); siempre borra siempre borra elel registro registro CCPxCON CCPxCON
W ← 00000000 W ← W | 00000100 T2CON ← W W ← E0 h Banco 1 PR2 ← W Banco 0
setup_ccp1 (CCP_PWM); #use fast_io (C)
RC2 ← 0 CCP1CON ← 0 W ← 00001100 CCP1CON ← W
set_pwm1_duty (301); 4Bh
CCPR1L ← 01001011 W ← CCP1CON W ← W & 11 001111 W ← W | 00010000 CCP1CON ← W
8
Módulos CCP
Ejemplo 2 setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1);
Configurar Configurar uno uno de de los módulos CCP los módulos CCP para para lanzar lanzar de manera de manera automática automática una conversión una conversión A/D A/D cada cada 1ms. 1ms. f osc = 3MHz TMR1 = 750 (sin prescaler)
W ← 100001 01 T1CON ← W
set_timer1 (0); TMR1H ← 0 TMR1L ← 0
CCP2 = 750; 750
W ← 02h CCPR2H ← W W ← EE h CCPR2L ← W
setup_ccp2 (CCP_COMPARE_RESET_TIMER); CCP2CON ← 0 W ← 00001011 CCP2CON ← W
9
MÓDULO DE CONVERSIÓN A/D
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.
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. 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. Si una señal continua, S(t), tiene una banda de frecuencia en la que fm es la mayor frecuencia, 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.
1
Circuitos de Conversión A/D y D/A
Circuitos de captura y mantenimiento Denominados S/H: Sample and hold. Muestrean la señal analógica (durante un intervalo de tiempo) y mantienen ese valor, generalmente en un condensador, durante el tiempo que dura la transformación A/D propiamente dicha.
Ve
Vs
C C/M
S&H
Ve
Vs
C/M
Circuitos de Conversión A/D y D/A
Tipos de convertidores A/D Convertidor A/D directo VREF
S/H
Tiempo de conversión igual a la suma de los tiempos de propagación en el comparador y el codificador.
- Útil sólo en casos de baja resolución.
R ue
- Convertidor de alta velocidad.
Para N bits se necesitan 2·N-1 comparadores (complejidad y coste excesivos).
Codif. 4 2
R
÷
E3 E2
R
E1 E0
R
Q1
A1
Q0
A0
2N ⋅ ue E V REF
Vcc
2
Circuitos de Conversión A/D y D/A Convertidor A/D por aproximaciones sucesivas Es el implementado en los microcontroladores PIC. Se van eliminando mitades de tabla hasta quedarse con el valor que más se aproxima a la tensión analógica a convertir. El proceso siempre acaba tras N pasos.
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,2V 1) Prueba con 1000 (⇒2,5V) 2,5 < 3,2 → mitad superior 2) Prueba con 1100 (⇒3,75V) 3,75 > 3,2 → mitad inferior a) Prueba con 1010 (⇒3,125V) 3,125 < 3,2 → mitad superior a) Prueba con 1011 (⇒3,4375V) 3,4375 > 3,2 → valor inferior
Circuitos de Conversión A/D y D/A Otros convertidores A/D indirectos - De simple rampa. - De doble rampa. - Por paso intermedio a frecuencia. Circuitería adicional Mpx analógico
Captad.
Adapt.
Captad.
Adapt.
Fin conversión
S&H
Sistema Captad.
Adapt.
A/D Inicio conversión
µP
Captura
Selección
3
Circuitos de Conversión A/D y D/A
Conversión D/A No incluido en los microcontroladores PIC. Deben generar una tensión de salida según la siguiente expresión: us
=
V REF N
2
⋅ ( A0 + A1 ⋅ 21 + L + AN -1 ⋅ 2N −1 )
Ejemplo: Red 2N·R
VREF
2 N·R Ai = “0” → Int. abierto Ai = “1” → Int. cerrado
2N-1 ·R
21·R
i1
iN-1
i0
A0
A1
R A N-1 i
+ucc
us N -1
us
/ ⋅∑ = −R ⋅ i = − R k =0
V REF N -k
2
⋅ R /
⋅ Ak = −V REF ⋅ ( A0 ⋅ 2 -N + A1 ⋅ 21-N + L + AN -1 ⋅ 2 -1 )
-ucc
Circuitos de Conversión A/D y D/A Circuitería adicional Dmpx analógico Fin conversión
D/A
µP
Inicio conversión
Retenc.
Adapt.
Actuad.
Retenc.
Adapt.
Actuad.
Sistema Retenc.
Adapt.
Actuad.
Selección
4
El Módulo de Conversión A/D de los PIC
Características generales en el PIC16F877 Ocho canales de conversión. 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. Tensión de referencia seleccionable por software. Puede ser VDD o la tensión aplicada en los pines RA2 y/o RA3. Posibilidad de seguir funcionando cuando el PIC está en modo
.
SLEEP
Hay 11 registros asociados a este periférico. Definición de pines de entrada TRISA - PORTA - TRISE - PORTE
Manejo de interrupciones INTCON - PIE1 - PIR1
Control del conversor A/D ADCON0 - ADCON1 - ADRESH - ADRESL
El Módulo de Conversión A/D de los PIC
Estructura interna CHS2:CHS0
RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA5/AN4 RE0/AN5 RE1/AN6 RE2/AN7
Convertidor A/D
000 001 010 011
VAIN (Input Voltage)
100 101 110 111
VDD
PCFG3:PCFG0
VREF+
PCFG3:PCFG0
VREF-
VSS
1
El Módulo de Conversión A/D de los PIC
Registro ADCON0 (1Fh) ADCS1
bit 7-6
ADCS0
CHS2
01 = fOSC / 8
GO/DONE
-
ADON
10 = fOSC / 32
11 = fRC
CHS2:CHS0: Selección del canal de conversión 000 = Canal 0 100 = Canal 4
bit 2
CHS0
ADCS1:ADCS0: Selección del reloj para la conversión A/D 00 = fOSC / 2
bit 5-3
CHS1
001 = Canal 1 101 = Canal 5
010 = Canal 2 110 = Canal 6
011 = Canal 3 111 = Canal 7
GO/DONE: Estado de la conversión Si ADON=1: 1 = Conversión en progreso
bit 0
0 = Conversión finalizada
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
bit 7
-
-
-
PCFG3
PCFG1
PCFG0
ADFM: Selección de formato del resultado 1 = Ajuste a la derecha
bit 3-0
PCFG2
0 = Ajuste a la izquierda
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
AN5 RE0
AN4 RA5
AN3 RA3
AN2 RA2
AN1 RA1
AN0 RA0
A A D D D D D A D D D D D D D
A A D D D D D A A A A D D D D
A A A A D D D A A A A A D D D
A V REF+ A VREF+ A VREF+ D VREF+ A VREF+ VREF+ VREF+ VREF+ D VREF+
A A A A D D D
A A A A A A D A A A A A A D D
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
El Módulo de Conversión A/D de los PIC
Registro INTCON (0Bh , 8Bh , 10Bh , 18Bh) GIE
PEIE
T0IE
INTE
RBIE
T0IF
bit 7
GIE: Habilitación global de interrupciones
bit 6
PEIE: Habilitación de interrupciones de periféricos
INTF
RBIF
TMR2IE
TMR1IE
Registro PIE1 (8Ch) PSPIE
bit 6
ADIE
RCIE
TXIE
SSPIE
CCP1IE
ADIE: Habilitación de la interrupción del convertidor A/D
Registro PIR1 (0Ch) PSPIF
bit 6
ADIF
RCIF
TXIF
SSPIF
CCP1IF
TMR2IF
TMR1IF
ADIF: Flag de la interrupción del convertidor A/D 1 = Conversión A/D completada.
0 = Conversión A/D aún no completada.
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. - Definir entradas analógicas y tensión de referencia. - Seleccionar el canal de la conversión. (ADCON0) - Seleccionar el reloj de la conversión. (ADCON0) - Encender el módulo A/D. (ADCON0) 2. Configurar la interrupción por conversión A/D. - Bajar el flag ADIF. (PIR1) - Habilitar la interrupción del convertidor A/D. - Habilitar las interrupciones de los periféricos. - Habilitar la máscara global de interrupciones.
(ADCON1)
(PIE1) (INTCON) (INTCON)
3. Esperar a que transcurra el tiempo de adquisición. - Tiempo necesario para capturar el valor analógico a convertir. - Los valores típicos del tiempo de adquisición son del orden de 20µs.
3
El Módulo de Conversión A/D de los PIC
4. Comenzar la conversión. - Poner a “1” el bit GO/DONE.
(ADCON0) No activar este bit a la vez que se enciende el convertidor A/D
5. Esperar a que se complete la conversión A/D. a) Controlando cuándo el bit GO/DONE se pone a “0”. b) Esperando a que llegue la interrupción del convertidor.
6. Leer el resultado de la conversión. - Disponible en los registros ADRESH:ADRESL. - Bajar el flag ADIF si se están usando interrupciones.
7. Llevar a cabo la siguiente conversión. - Volver al paso 1 ó 2, según convenga. - Espera mínima antes de empezar la siguiente adquisición: 2·T AD. T AD: Tiempo necesario para la conversión de un bit.
El Módulo de Conversión A/D de los PIC
Tiempo de adquisición Tiempo necesario para cargar el condensador de mantenimiento (CHOLD ). VDD
RS
ANX
R IC ≤ 1K
SS
RSS
VA CPIN 5pF
IFUGAS ±500nA
CHOLD 120pF VSS
Máxima impedancia recomendada para la fuente: 10K. En estas condiciones, T ACQ ≈ 20µs.
Mientras no se complete la conversión, no empieza otra adquis ición. Esperar T ACQ : a) tras una conversión; b) tras seleccionar un nuevo canal; c) tras encender el módulo A/D.
4
El Módulo de Conversión A/D de los PIC
Tiempo de conversión La conversión de 10 bits dura 12·T AD. T ciclo ÷ T AD
T AD
T AD
T AD
T AD
T AD
T AD
T AD
T AD
T AD
T AD
T AD
b9
b8
b7
b6
b5
b4
b3
b2
b1
b0
Comienza la conversión Se abre SS (típ. GO/DONE
←
Se carga ADRES Se pone GO/DONE a “0” Se levanta el flag ADIF CHOLD conectado a entrada analógica
100ns)
1
T AD configurable en ADCON0 (reloj de la conversión). T AD=2·T OSC - T AD=8·T OSC - T AD=32·T OSC - T AD=2µs÷6µs (típ. 4µs) Para un funcionamiento correcto se necesita un valor mínimo de T AD=1,6µs.
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 V REF- + (VREF+ - VREF-)/1024 1LSb. ≡
FFh FEh FDh FCh
04h 03h 02h 01h 00h
(VREF- )
(VREF+ ) b b b b S S S S L L L L 1 2 3 4
b b b b S S S S L L L L 1 2 3 4 2 2 2 2 0 0 0 0 1 1 1 1
5
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); modo :
ADC_OFF ADC_CLOCK_DIV_2 ADC_CLOCK_DIV_8 ADC_CLOCK_DIV_32 ADC_CLOCK_INTERNAL
(ADCON0 ← 00h) (ADCON0 ← 01h) (ADCON0 ← 41h) (ADCON0 ← 81h) (ADCON0 ← C1h)
Definición de entradas analógicas
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 ← 86h) (ADCON1 ← 80h) (ADCON1 ← 81h) (ADCON1 ← 82h) (ADCON1 ← 83h) (ADCON1 ← 84h) (ADCON1 ← 85h)
El Módulo de Conversión A/D de los PIC
Definición de entradas analógicas (cont.)
setup_adc_ports (valor ); 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 ← 88h) (ADCON1 ← 89h) (ADCON1 ← 8Ah) (ADCON1 ← 8Bh) (ADCON1 ← 8Ch) (ADCON1 ← 8Dh) (ADCON1 ← 8Eh) (ADCON1 ← 8Fh)
Selección del canal analógico
set_adc_channel (canal); 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
Lectura del resultado
valor = read_adc (); valor:
Entero de 16 bits según la directiva #device adc= empleada.
La influencia de dicha directiva se recoge en la siguiente tabla #device
8 bits
10 bits
11 bits
16 bits
adc=8
00-FF
00-FF
00-FF
00-FF
adc=10
x
0-3FF
x
x
adc=11
x
x
0-7FF
x
adc=16
0-FF00
0-FFC0
0-FFE0
0-FFFF
El fichero 16f877.h incluye como primera directiva #device PIC16F877 . Es necesario incluir información del tipo de conversor A/D. Por ello los ficheros C que usen este módulo deberán comenzar por #include “16f877.h” #device adc=10
El Módulo de Conversión A/D de los PIC
Ejemplo
setup_adc_ports (A_ANALOG); setup_adc (ADC_CLOCK_INTERNAL);
W ← 10000010 Banco 1 ADCON1 ← W Banco 0 W ← ADCON0 W ← W & 00111000 W ← W | 11000001 ADCON0 ← W
set_adc_channel (3); delay_us (20);
W ← ADCON0 W ← W & 11000111 W ← W | 00011000 ADCON0 ← W
valor = read_adc (); setup_adc (ADC_OFF);
W
←
ADCON0
W
←
W & 00111000
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
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 tie mpo fijo. La velocidad de transmisión se indica en baudios (número de bits enviados por segundo). La transferencia puede ser síncrona o asíncrona. Síncrona: Se envía la señal de reloj para sincronizar cada bit. Asíncrona: Se necesitan “relojes” en el emisor y el receptor de la misma frecuencia y en fase Datos Datos EMISOR
¿Reloj?
Bit i RECEPTOR
Bit i+1
Reloj
Referencia de tensión
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. Se puede llevar a cabo varios tipos de sincronización. De los sucesivos bits. 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í se consiguen menores retardos en las transiciones y mejores flancos en la señal de reloj recibida. Posibles codificaciones de cada bit. / NRZ: Nivel alto: 1 NRZI: Cambio de nivel: 1 / Impulso: 1 / RZ: ...
Nivel bajo: 0 Sin cambio de nivel: 0 Sin impulso: 0
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). 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”. Si se desea enviar un dato se manda un bit de arranque, que sitúa a “0” la línea durante el tiempo correspondiente a un bit (START). Al finalizar el envío de un dato, la línea se sitúa a “1” al menos durante el tiempo de un bit: bit de parada (STOP). Reg. desplazamiento Reloj
Datos Referencia
Reg. desplazamiento Sincr.
Reloj
Comunicación serie asíncrona
Comunicación serie asíncrona en microcontroladores PIC Se va a implementar haciendo uso del módulo USART U niversal S ynchronous A synchronous R eceiver T ransmitter . También se conoce como S erial C ommunications I nterface (SCI).
Es uno de los dos módulos de E/S serie del PIC.
El módulo USART puede actuar como sistema asíncrono f ull duplex . Permite comunicarse con periféricos como CRTs y PCs. También puede configurarse como sistema síncrono half duplex.
Para comunicación con circuitos A/D o D/A, memorias serie EEPROM, etc.
Terminales asociados: RC6/TX/CK y RC7/RX/DT. Deben configurarse adecuadamente. El módulo USART también permite localizar direcciones de 9 bits.
2
Comunicación serie asíncrona
Registro TXSTA (98h) CSRC
bit 6
TX9
TXEN
SYNC
1: Transmisión síncrona
BRGH: Bit de selección de alto valor de baudios
N o se u sa en t r ansm i si ó n
1: Alta velocidad
sí ncr ona
TRMT: Bit de estado del registro TSR 0: TSR lleno
bit 0
1: Transmisión habilitada
SYNC: Bit de selección del modo de funcionamiento
0: Baja velocidad
bit 1
TX9D
TXEN: Bit de habilitación de la transmisión
0: Transmisión asíncrona
bit 2
TRMT
1: Transmisión de 9 bits
0: Transmisión deshabilitada
bit 4
BRGH
TX9: Bit de habilitación de la transmisión de 9 bits 0: Transmisión de 8 bits
bit 5
-
1: TSR vacío
TX9D: 9 bit de datos transmitido. Puede ser el bit de paridad, por ejemplo
Comunicación serie asíncrona
Registro RCSTA (18h) SPEN
bit 7
RX9
SREN
CREN
SPEN: Bit de habilitación del puerto serie 0: Deshabilitado
bit 6
1: Habilitada
No se usa en transmisión síncrona
1: Habilitada
Sólo si RX9=1
1: Sí hubo error
Se actualiza al leer RCREG
1: Sí hubo error
Se pone a 0 si CREN ← 0
OERR: Bit de error de overrun 0: No hubo error
bit 0
1: Recepción de 9 bits
FERR: Bit de error de framing 0: No hubo error
bit 1
RX9D
ADDEN: Bit de habilitación de detección de dirección 0: Deshabilitada
bit 2
OERR
o pines del Configura RC <6: 7> com ie ser puerto
CREN: Bit de habilitación de recepción continua 0: Deshabilitada
bit 3
1: Habilitado
FERR
RX9: Bit de habilitación de la recepción de 9 bits 0: Recepción de 8 bits
bit 4
ADDEN
RX9D: 9 bit de datos transmitido.
3
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). La expresión matemática que determina los baudios de la comunicación serie asíncrona es la siguiente:
Baudios
f osc 64 ⋅ (SPBRG + 1) = f osc 16 ⋅ (SPBRG + 1)
si BRGH
=0 s g 1 b i t/ = o i d 1 b a u
si BRGH
=1
En muchos casos resulta ventajoso usar BRGH=1 incluso para generar comunicaciones lent as . Puede dar lugar a menores errores relativos. Si se desea 9600Bd con fosc=20MHz:
BRGH=0 , SPBRG=31 ⇒ 9766Bd (error=1,73%) BRGH=1 , SPBRG=129 ⇒ 9615Bd (error=0,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. El emisor y el receptor son funcionalmente independientes. Aunque comparten el mismo formato de datos y la misma velocidad de la comunicación (baudios). 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. Así se eliminan posibles errores debidos a las diferencias en los relojes del emisor y el receptor. No se genera paridad mediante hardware. Si se quiere enviar como 9º bit el bit de paridad, el usuario debe calcularlo e interpretarlo en el software. La comunicación asíncrona, que se selecciona haciendo SYNC funciona en modo SLEEP.
←
0, no
4
Comunicación serie asíncrona
Emisor asíncrono en el SCI Diagrama de bloques. Bus de datos
TXIE
TXIF
TXREG 8 (8) 7 6 5 4 3 2 1 0
TSR
RC6 TX CK
Control
Interrupción
TRMT
TXEN
SPEN
SPBRG TX9
CLK TX9D
Comunicación serie asíncrona
Funcionamiento Desde el programa se carga el buffer de transmisión TXREG. En cuanto se haya enviado un bit de STOP, el contenido de TXREG pasa a TSR para ser enviado. - El paso del contenido de TXREG a TSR se realiza en un ciclo de instrucción. - Cuando TXREG queda vacío, TXIF ← 1 (si TXEN=1).
TXIF sólo se borra escribiendo en TXREG.
- Del mismo modo, cuando TSR queda vacío, TRMT ← 1. TRMT no está ligado a ninguna interrupción.
La transmisión no empieza hasta que TXREG haya sido cargado con un dato y se genere un reloj de los baudios deseados. - Además debe estar habilitada la transmisión (TXEN=1).
Si se usa una transmisión de 9 bits (TX9=1), el 9º bit debe escribirse antes de escribir los otros 8 bits en TXREG.
- Si TSR está vacío, al escribir en TXREG podría comenzar la transferencia de inmediato, con lo que el 9º bit sería erróneo.
5
Comunicación serie asíncrona
Transmisión serie asíncrona de un dato Escritura en TXREG
Dato 1
Salida BRG Pin RC6/TX/CK
START Bit 0
Bit 1
Bit 2
Bit 3
Bit 7/8 STOP
Dato 1
Bit TXIF Bit TRMT
Dato 1 en el TSR
Comunicación serie asíncrona
Transmisión serie asíncrona back t o bac k Se escribe un dato en TXREG antes de que se haya terminado de enviar el anterior. Dato 1
Dato 2
Escritura en TXREG Salida BRG Pin RC6/TX/CK
START Bit 0
Bit 1
Dato 1
Bit 7/8 STOP START Bit 0
Bit 1
Bit 2
Dato 2
Bit TXIF Bit TRMT
Dato 1 en el TSR
Dato 2en el TSR
6
Comunicación serie asíncrona
Pasos a seguir para transmitir datos 1. Seleccionar los baudios de la comunicación.
Usando el registro SPBRG y el bit BRGH (TXSTA<2>).
2. Habilitar el puerto serie asíncrono. SYNC ← 0 ; SPEN ← 1
3. Si se van a usar interrupciones, hacer TXIE ← 1.
(PIE1<4>)
4. Si se van a transmitir datos de 9 bits, hacer TX9 ← 1.
(TXSTA<6>)
5. Habilitar la transmisión serie.
TXEN ← 1 ; esto hará que TXIF ← 1 también.
6. Si se ha seleccionado una transmisión de 9 bits, cargar el noveno bit en TX9D. (TXSTA<0>) 7. Cargar el dato a transmitir en el registro TXREG. 8. Si se van a usar interrupciones, asegurarse de que los bits GIE y PEIE están a “1”. (INTCON<7:6>)
Comunicación serie asíncrona
Receptor asíncrono en el SCI Diagrama de bloques.
fosc
OERR
CREN
CLK
SPBRG MSb (8) 7 6 5 4 3 2 1 0
STOP RC7 RX DT
FERR
Control
Recuperación de datos
START
RX9
RX9D
SPEN RCIF Interrupción
RSR
LSb
RCIE
RCREG
FIFO
8 Bus de datos
7
Comunicación serie asíncrona
Funcionamiento La recepción de datos queda habilitada haciendo CREN ← 1. En cuanto RSR haya recibido un bit de STOP, su contenido pasa a RCREG (si está vacío). - Cuando se haya completado esta transferencia, RCIF ← 1.
RCIF sólo se borra cuando se ha leído RCREG (y queda vacío).
El registro RCREG es una cola FIFO de dos posiciones.
- 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, OERR ← 1. - El tercer dato se pierde. Habría que leer RCREG dos veces.
OERR se borra reseteando la lógica de recepción (CREN←0 y CREN←1).
Si RSR recibe un “0” cuando espera el bit de STOP, FERR ← 1. - El bit FERR se gestiona del mismo modo que el 9º bit del dato.
Hay que leer el 9º dato (y el bit FERR) antes que RCREG.
- Al leer RCREG, se carga un nuevo dato de RSR. Puede variar RX9D y FERR.
Comunicación serie asíncrona
Recepción serie asíncrona de un dato Pin RC7/RX/DT Recibido en RSR
STT
b0
b7/8 STP
STT
b0
Dato 1 pasa a RCREG
b7/8 STP
STT b0
b7/8 STP
Dato 2 pasa a RCREG
Leído de RCREG Bit RCIF Bit OERR Bit CREN
8
Comunicación serie asíncrona
Pasos a seguir para recibir datos 1. Seleccionar los baudios de la comunicación. 2. Habilitar el puerto serie asíncrono. SYNC ← 0 ; SPEN ← 1
3. Si se van a usar interrupciones, hacer RCIE ← 1.
(PIE1<5>)
4. Si se van a recibir datos de 9 bits, hacer RX9 ← 1. 5. Habilitar la recepción serie.
(RCSTA<6>)
CREN ← 1
6. Cuando se complete una recepción, se tendrá RCIF
←
1.
(PIR1<5>)
7. Leer RX9D y determinar si se ha producido algún error. 8. Leer los 8 bits recibidos en el registro RCREG. 9. Si ha habido algún error, resetearlo haciendo CREN ← 0. 10. Si se van a usar interrupciones, asegurarse de que GIE=1 y PEIE=1.
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 ...
¡¡IMPORTANTE!! Es imprescindible que aparezca una directiva #use delay antes de que se pueda utilizar una directiva #use rs232.
#use delay (clock=3000000); #use rs232 (BAUD=9600 , XMIT=PIN_C6 , RCV=PIN_C7 , BITS=8) 0 0 1 0 0 0 1 0
TXSTA
1 0 0 1 0 0 0 0
RCSTA
SPBRG = 4 set_uart_speed (baud); baud:
Constante entre 100 y 115.200
la biar duran te Perm ite cam rama los baudios el prog ejecución d con # use rs232 de finidos
9
Comunicación serie asíncrona
Transmisión serie putc (dato); dato:
putchar (dato); Carácter de 8 bits.
puts (string); string:
Cadena de caracteres constante o array de caracteres terminado con un 0.
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. Detrás de la cadena envía un RETURN (13) y un retorno de carro (10).
Muy a menudo estas funciones se ven remplazadas por la función printf, más versátil que cualquiera de ellas.
Comunicación serie asíncrona
Transmisión serie (cont.) printf ([función,] string [, valores...]); string:
Cadena de caracteres (constante) o array de caracteres terminado con un 0.
función: Función a utilizar para escribir la cadena indicada.
Por defecto es putc, que permite escribir en el bus RS-232.
valores: Variables a incluir en la cadena
Cuando se usan variables, en la cadena se indicará como %wt, donde Nº de caracteres. w: 1-9 01-09 Nº de posiciones a completar con 0s. 1.1-9.9 Nº de decimales. 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. Flotante Long en hexadecimal Ídem en mayúsculas Long sin signo (en decimal) Long con signo (en decimal) Simplemente un %
10
Comunicación serie asíncrona
Recepción serie valor = getc(); valor:
valor = getch();
valor = getchar();
Carácter de 8 bits.
Espera que llegue un carácter por la línea RS-232 y da su valor. En los PIC con USART, se pueden almacenar hasta tres caracteres. Para no estar continuamente esperando, se puede usar kbhit(). valor = kbhit(); 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.
gets(string); string:
Puntero a un array de caracteres.
Almacena caracteres (leídos con getc) en el array hasta que recibe un RETURN (13). Termina la cadena con un 0.
Comunicación serie asíncrona
Funciones estándar CCS para cadenas de caracteres Funciones que facilitan el trabajo con cadenas de caracteres. Copia cad en s1. strcpy (s1,cad); e d o h r . e g n h i c r i t f l s e n n ó i a s t u i l s c e i n c e N
s1, s2 cad n c
ptr=strcat(s1,s2); ptr=strchr(s1,c); ptr=strrchr(s1,c); res=strcmp(s1,s2); res=strncmp(s1,s2,n); res=stricmp(s1,s2); ptr=strncpy(s1,s2,n); res=strcspn(s1,s2); res=strspn(s1,s2); res=strlen(s1); ptr=strlwr(s1); ptr=strpbrk(s1,s2);
Encadena s2 a s1. Localiza c en s1 y devuelve su dirección: &s1[i]. Como anterior pero empieza búsqueda desde final. Compara s1 y s2 y devuelve TRUE si coinciden. 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
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
ptr res
Copia del puntero s1 Entero de 8 bits
11
Comunicación serie asíncrona
La Norma RS232 Nace con la idea de comunicar un computador o equipo terminal de datos (DTE o Dat a T er minal Equipment ) y un módem o equipo de comunicación de datos (DCE o Da t a Communicat ions 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,… Se emplea, por ejemplo, para comunicar equipos que son ambos DTE, como dos PCs o un PC y un microcontrolador. Los equipos pueden utilizar distintos conectores. Conector SUB-D de 25 pins. Conector SUB-D de 9 pins. Conector SUB-D de 15 pins de alta densidad.
(El menos habitual)
El conector de 25 pines es el único que dispone de todas las señales definidas en la norma original.
Comunicación serie asíncrona
Ejemplo: Los puertos serie de un PC (COMn). 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
Pin1 Pin2 Pin3 Pin4 Pin5 Pin6 Pin7 Pin8 Pin9
6
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
Comunicación serie asíncrona
Para realizar la conexión entre un microcontrolador y un PC, 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
“1” -> -3V a -15V “0” -> +3V a +15V
Escritura RS232
Lectura RS232
Existen varios circuitos integrados comerciales que realizan esta adaptación con muy pocos componentes (p.e. la familia MAX220 a 249)
La conexión puede realizarse utilizando las líneas que se consideren oportunas. 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. El truco pasa por “puentear” las líneas de petición de envío y las respuestas.
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.
13
Comunicación serie asíncrona
Conexión serie según norma RS232: Comunicación PIC - PC Niveles escritura RS232 “1” -> -5V a -15V “0” -> +5V a +15V
“1” -> 5V “0” -> 0V RX TX GND EJEMPLO DE CONEXIÓN A 3 HILOS FULL DÚPLEX
Driver RS232 (MAX232)
TX
Pin3 Pin2
RX
Pin5
Puentes Pins 4 y 8 Pins 6 y 7
GND Niveles lectura RS232 “1” -> -3V a -15V “0” -> +3V a +15V
14
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 tie mpo fijo. La velocidad de transmisión se indica en baudios (número de bits enviados por segundo). La transferencia puede ser síncrona o asíncrona. Síncrona: Se envía la señal de reloj para sincronizar cada bit. Asíncrona: Se necesitan “relojes” en el emisor y el receptor de la
misma frecuencia y en fase Datos
Datos EMISOR
¿Reloj?
Bit i RECEPTOR
Bit i+1
Reloj
Referencia de tensión
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. Se puede llevar a cabo varios tipos de sincronización.
De los sucesivos bits. 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í se consiguen menores retardos en las transiciones y mejores flancos en la señal de reloj recibida.
Posibles codificaciones de cada bit. / NRZ: Nivel alto: 1 NRZI: Cambio de nivel: 1 / Impulso: 1 / RZ: ...
t
Nivel bajo: 0 Sin cambio de nivel: 0 Sin impulso: 0
Comunicaci Comun icación ón Serie Serie Síncrona I2C
Transferencia síncrona La comunicación síncrona entre dos dos dispositivos requiere que uno de ellos actúe como maestro y el otro, como esclavo. Dispos Dispositi itivo vo Maestr Maestro: o: Es el que genera genera la seña señall de reloj reloj y el que que tien tienee capacidad capacidad de iniciar iniciar o finalizar finalizar una transfer transferencia. encia. Dispos Dispositi itivo vo Escl Esclavo avo:: Reci Recibe be la seña señall de reloj reloj y no tien tienee capaci capacidad dad para para iniciar una transferencia de información. Es posible posible efectuar una transmisión transmisión continua de bits de información información.. Dato
Ma e s t r o
Clk
Dato
Esclavo
M a e s tr o
Ref.
Clk
Esclavo
Ref.
Maestro Emitiendo
Maestro Recibiendo
Comunicaci Comun icación ón Serie Serie Síncrona I2C
Comunicació Comuni caciónn serie síncrona síncrona en microcontrola microcontroladores dores PIC Se implement implementaa mediante mediante el módulo módulo SSP ynchronous us S erial erial P ort : Interfaz de comunicación serie síncrona. S ynchrono Está pensado para poder comunicarse comunicarse con otros microcontroladores microcontroladores o periféricos mediante transmisión serie síncrona.
EEPROM serie Registros de Desplazamiento Driverss de Displays Driver Conversores A/D ....
Almacenamiento Almacenami ento de datos no volátiles Expansión de entradas entradas y/o salidas Reducción de conexiones Digitalización externa de señales señales
El módulo SSP tiene dos posibles modos de funcionamiento. funcionamiento. nterface: e: Interface Interface de Periféricos Periféricos Serie) Serie) SPI (Serial Peripheral Interfac
SPI: Es una Marca Registrad Registradaa de Motorola Corporation Corporation
I 2C (Inter-I ntegrated Circuit: Entre Circuitos Integrados)
I2C: Es una una Marca Registrada Registrada de Philips
Comunicaci Comun icación ón Serie Serie Síncrona I2C
Caracte Cara cteríst rística icass general generales es del bus I2C El bus Inter-Integrated-C Inter-Integrated-Cir ircu cuit it (I2C) fue creado por Philips.
Para transferencia transferencia de datos entre entre CIs de una PCB. 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, configuraciones, el dispositivo Maestro es el único que tiene capacidad capacidad de iniciar la transferencia, tran sferencia, decidir con con quién se realiza, el sen sentido tido de la misma (envío o recepción 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 reloj (pin (pin RC3) RC3).. SDA para los datos datos (pin (pin RC4) RC4)..
La comunicación es, por tanto, half-duplex.
Comuni Com unicac cación ión Serie Síncr Síncrona ona 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 transferencia de 8 bits, el Maestro envía envía un 9º pulso de reloj. - En ese instante, el dispositivo dispositivo “transmisor” “transmisor” suelta la línea SDA y el “receptor” reconoce el dato enviado mediante un ACK (SDA←0). - Se envía envía un NACK (deja SDA=1) SDA=1) para finalizar la transmisión.
Todos los cambios en SDA deben ocurrir mientras SCL=0.
Así se permite 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 Comun icación ón Serie Serie Síncrona I2C
Fácil inclusión de nuevos dispositivos I 2C en el bus.
Una vez disponib disponible le el microc microcontrol ontrolador ador con con sus sus funciones funciones de 2 interface inter face co conn bus bus I C, la inclusión de un dispositivo I 2C adicional sólo precisa su conexión conexión a las dos dos líneas del del bus (SDA (SDA y SCL), SCL) , que son las mismas mism as para todos todos,, y asig asignarl narlee una dirección dirección..
Conexiones en el bus I 2C. VDD
R p Periférico Rp
≥
V DD − V OL i OL
Rp Rs
Número Número máx. de dispositivos definidos por la capacidad en el bus: Cmax=400pF
Rs
SDA SCLL SC
Cbus=10 – 400p 400pFF
Comunicaci Comun icación ón Serie Serie Síncrona I2C
Direccionamiento Direccionamiento de dispositivos en el bus I 2C
Reconocimiento (lo debe debe poner el Escl Esclav avo) o)
Formato de 7 bits bits:: (A7-A (A7-A6-...-A1) 6-...-A1)
Lo “pone” el Maes Maestro tro
En la líneaSDA: Start
S A7 A6 A5 A4 A3 A2 A1 R/ R/W ACK Dirección de 7 bits del esclavo
Lectura (1) o Escritura (0)
Formato de 10 bit bits: s: (A9-A8-A7 (A9-A8-A7-...-...-A0 A0)) Primer byte del Maestro
2º byte del Maest Maestro ro
En la líneaSDA: S 1 1 1 1 0 A9 A8 R ACK A7A6A5A4A3 A2A1A0 ACK W ACK S Start
Lectura (1) o Escritura (0)
Reconocimientos del Esclavo despué des puéss de cad cadaa by byte te del Maestro
Comunicación Serie Síncrona I2C
Reconocimiento de transferencia (ACK)
Los datos se transmiten en paquetes de 8 bits (bytes). Tras cada byte el receptor debe intercalar un bit de reconocimiento (ACK). Si el receptor es el Esclavo y no genera el bit de reconocimiento después de cada byte, el Maestro debe abortar la transferencia generando un bit de fin (STOP).
En este caso, y dado que las etapas de salida son de drenador abierto, los niveles lógicos “0” son dominantes en las líneas, 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, permitiendo al Esclavo que continúe enviando bytes. Si el Maestro decide finalizar la transferencia, genera un bit de STOP tras colocar un bit de no-reconocimiento (NACK). El Esclavo puede retardar el envío del siguiente byte (porque no lo tiene todavía disponible, p.e.) situando la línea SCL en estado bajo, forzando así al Maestro a situarse en un estado de “Espera” puesto que no podrá generar flancos en SCL.
Comunicación Serie Síncrona I2C
Secuencia de transmisión I 2C desde el Maestro.
SDA:
S Dirección del Esclavo De Maestro a Esclavo De Esclavo a Maestro
R/W
A Dato
“0” porque el Maestro quiere escribir (enviar)
A Dato
A/A
P
Reconocimiento (A) o no reconocimiento (A)
Secuencia de recepción I2C por parte del Maestro.
SDA:
S Dirección del Esclavo R/W
A Dato
“1” porque el Maestro quiere leer (recibir)
A Dato
A P
No reconocimiento por Maestro y Parada
Comunicación Serie Síncrona I2C
Típica transmisión I 2C para lectura desde el Esclavo. Recibe la dirección
Recibe el dato
ACK
A7 A6 A5 A4 A3 A2 A1
Puesto por el Esclavo
Recibe el dato
NACK
ACK D7 D6 D5 D43 D3 D2 D1 D0
D7 D6 D5 D4 D3 D2 D1 D0
R/W
1
S
2
3
4
5
6
7
8
9
1
2
Pulso ACK
3
4
5
6
7
8
9
1
2
3
4
5
6
7
Pulso ACK
8
9
P
Pulso ACK
Típica transmisión I 2C por parte del Esclavo.
Puesto por el Maestro
Recibe la dirección
Envía el dato
ACK
A7 A6 A5 A4 A3 A2 A1
NACK D7 D6 D5 D4 D3 D2 D1 D0
R/W S
1
2
3
4
5
6
7
8
9
Pulso ACK
1
2
3
4
5
El Esclavo pone SCL a 0 para darse tiempo de preparar el dato
6
7
8
9
P
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, en lugar de generar un bit de STOP y volver a generar el nuevo START, puede generar una Repetición de START (Sr). 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.
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). BSSP (Basic S ynchronous S erial P ort )
Modo Esclavo: Completo por hardware. Modo Maestro: Detección de bits START y STOP por hardware. 16C64, 16C65, 16C73, 16C74, ...
MSSP (Master S ynchronous S erial P ort )
Modo Esclavo: Completo por hardware. Modo Maestro: Completo por hardware. 16F87x
Ambos módulos son idénticos en lo que se refiere al interface SPI. 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. Esclavo I2C con dirección de 7 bits. Esclavo I2C con dirección de 10 bits. Maestro I2C con reloj SCL de frecuencia fSCL = fOSC /[4·(SSPADD+1)]
- Seis registros asociados al funcionamiento de este módulo. SSPCON SSPADD
SSPCON2 SSPBUF
SSPSTAT SSPSR
Comunicación Serie Síncrona I2C
Diagrama de bloques del bus I2C en modo
Esclavo
Bus de datos Leer
RC3 / SCL
Escribir
SSPBUF
Reloj
Registro Registro E/S E/S
No Noaccesible accesible directamente directamente
SSPSR
RC4 / SDA
MSb
Buffer Buffer para para envío y envío y recepción recepción
LSb
Detector de dirección
Detecta coincidencia en la dirección o llamada general
SSPADD Detección de START/STOP
Control de los bits S y P del registro SSPSTAT
Dirección Dirección asignada asignada alal Esclavo Esclavo
Comunicación Serie Síncrona I2C
Diagrama de bloques del bus I2C en modo
Maest r o
Bus de datos Leer
SSPM3:SSPM0 SSPADD<6:0>
Escribir
SSPBUF SDA In
RC4 SDA
SSPSR MSb n a ó t i i l c i p b e a c H e r
RC3 SCL
Generador de baudios
Reloj LSb
Generación de START/STOP ACK
) K L C e d K e L t C n l e r u t f C e n e i t e d (
K L C l r t C
Detección de START/STOP Colisión de bus
SCL In Detección de colisión
Control de CLK
S , P , WCOL (SSPSTAT) SSPIF , BCLIF ACKSTAT , PEN (SSPCON2)
Comunicación Serie Síncrona I2C
Registro SSPSTAT (94h) SMP
bit 7
CKE
D/A
P
S
R/W
UA
BF
bit 4
SMP: Bit de control de slew rate Maestro 0 : Velocidad estándar 1 : Alta velocidad (400kHz) CKE: Bit de selección de niveles umbral en los pines 0: Especificaciones I2C 1: Especificaciones SMBus D/A: Información del último byte transmitido 0: Dirección 1: Dato Se pone a 1 si la última secuencia detectada es un bit de STOP P: Bit de STOP
bit 3
S: Bit de START Se pone a 1 si la última secuencia detectada es un bit de START
bit 2
R/W: Información de lectura/escritura 0: Escritura 1: Lectura (Esclavo ) 0 : No hay transmisión 1 : Transmisión en progreso (Maestro ) UA: Actualización del byte de dirección 0: No hace falta 1 : Es necesario actualizar la dirección BF: Bit de estado del buffer 0: SSPBUF está vacío 1 : SSPBUF está lleno
bit 6 bit 5
bit 1 bit 0
Comunicación Serie Síncrona I2C
Registro SSPCON (14h) WCOL
SSPOV
SSPEN
CKP
SSPM3
SSPM2
bit 7
WCOL: Bit de detección de colisión 0 : No ha habido colisión 1 : Ha habido colisión
bit 6
SSPOV: Bit indicador de overflow en la recepción 0: No ha habido overflow 1: Ha habido overflow
bit 5
SSPEN: Habilitación del puerto serie síncrono 0: Desabilitado 1: Habilitado (usa SCL y SDA)
bit 4
CKP: Control de SCL 0: Mantiene SCL a “0”
SSPM1
SSPM0
1 : Reloj habilitado
bits 3:0 SSPM3:SSPM0: Modo de funcionamiento 0110: 0111: 1000: 1011 : 1110: 1111:
Esclavo con direcciones de 7 bits. Esclavo con direcciones de 10 bits. Maestro con CLK=Fosc / [4·(SSPADD+1)]. Modo Maestro controlado por firmware (Esclavo inactivo). Maestro controlado por F w (dir. de 7 bits, interrup. por bits de START y STOP). Maestro controlado por Fw (dir. de 10 bits, interrup. por bits de START y STOP).
Comunicación Serie Síncrona I2C
Registro SSPCON2 (91h) GCEN
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
ACKSTAT
ACKDT
ACKEN
RCEN
PEN
RSEN
SEN
GCEN: Habilita Llamada General 0: Deshabilitada 1: Habilita interrupciones por Llamada General Esclavo ACKSTAT: Bit de reconocimiento ( Maestro / Recepción) 0: Recibido ACK del Esclavo 1: No se ha recibido ACK del Esclavo ACKDT: Valor a transmitir tras una recepción (Maestro / Recepción) 0: ACK 1: NACK ACKEN: Habilitación de secuencia ACK (Maestro / Recepción) 0: Desactivada 1 : Inicia secuencia de reconocimiento en SDA y SCL RCEN: Bit de habilitación de recepción (Maestro ) 0: Recepción desactivada 1: Activa modo recepción PEN: Habilitación de una secuencia STOP (Maestro ) 0: Desactivada 1: Inicia situación de STOP en SDA y SCL RSEN: Habilitación de START repetido (Maestro ) 0: Desactivado 1 : Inicia repetidas situaciones de START SEN: Habilitación de una secuencia START (Maestro ) 0: Desactivada 1: Inicia situación de START en SDA y SCL
Comunicación Serie Síncrona I2C
Otros registros relacionados con el módulo MSSP TRISC
(87h)
Para definir RC3 y RC4 como entradas.
SSPBUF
(13h)
Buffer de transmisión/recepción serie.
SSPSR
Registro de desplazamiento SSP (no accesible directamente).
SSPADD
(93h)
Define la dirección del Esclavo o los baudios de la comunicación (Maestro).
PIR1 – PIE1
(0Ch – 8Ch)
PIR2 – PIE2
(0Dh – 8Dh)
Interrupciones del módulo SSP (SSPIF – SSPIE). Interrupción por colisión del bus (BCLIF – BCLIE).
INTCON
(0Bh , 8Bh , 10Bh , 18Bh)
Habilita interrupciones de periféricos.
Comunicación Serie Síncrona I2C
Funcionamiento en modo
Esclavo
Antes de activar el módulo hay que configurar RC<3:4> como entradas. Configurar el MSSP en el registro SSPCON. Esclavo I2C con direcciones de 7 bits o con direcciones de 10 bits. Esclavo I2C con o sin interrupciones por bits de START y STOP. Lo más habitual es que no se usen interrupciones por START/STOP
Establecer la dirección del esclavo.
Escribirla en el registro SSPADD.
La dirección viene indicada por SSPADD<7:1> - SSPADD<0>=0 LSb se usa para determinar la operación solicitada por el Maestro
Esperar por un suceso I 2C.
Se puede determinar con la ayuda del bit SSPIF. La interrupción puede estar activada o no
Identificar el suceso y actuar en consecuencia. Los sucesos I2C que percibe el Esclavo pueden ser de 5 tipos.
Comunicación Serie Síncrona I2C
Maestro solicita escritura. Último byte fue una dirección El M aest r o ha comenzado una operación de escritura con el inicio de una secuencia START o RESTART en el bus, seguida del envío de la dirección del Esclavo . La dirección que hay en el bus pasa al registro SSPSR del Esclavo . Si coincide con la suya, la dirección recibida pasa a SSPBUF. Bits del registro SSPSTAT. -S=1 La última secuencia detectada fue un START El Maestro va a escribir datos en el Esclavo - R/W = 0 - D/A = 0 El último byte recibido fue una dirección El buffer está lleno - BF = 1 Debe leerse el registro SSPBUF aunque no se vaya a usar la información que contiene. Esta acción borra el bit BF y evita posteriores overflows.
Comunicación Serie Síncrona I2C
Maestro solicita escritura. Último byte fue un dato Tras el byte de dirección, el bytes de datos al Esclavo .
M aest r o puede
enviar uno o más
Bits del registro SSPSTAT. La última secuencia detectada fue un START -S=1 - R/W = 0 El Maestro escribe datos en el Esclavo El último byte recibido fue un dato - D/A = 1 - BF = 1 El buffer está lleno Debe leerse el registro SSPBUF. Si SSPBUF no estaba lleno antes de la escritura, el un reconocimiento ACK en el 9º pulso de reloj.
Lo hace el MSSP automáticamente. Si ya estaba lleno, SSPOV ← 1 y se envía un NACK.
Esclavo envía
Comunicación Serie Síncrona I2C
Maestro solicita lectura. Último byte fue una dirección El M aest r o ha comenzado una operación de lectura con el inicio de una secuencia START o RESTART en el bus, seguida del envío de la dirección del Esclavo . Bits del registro SSPSTAT. La última secuencia detectada fue un START -S=1 - R/W = 1 El Maestro va a leer datos del Esclavo El último byte recibido fue una dirección - D/A = 0 - BF = 0 El buffer está vacío El bit CKP se pone a 0 para que la línea SCL pase a estado bajo, dando así tiempo al Esclavo para preparar el dato a enviar. El Esclavo debe M aest r o .
escribir en el buffer el dato solicitado por el
Y debe hacer CKP ← 1 para liberar la línea SCL.
Comunicación Serie Síncrona I2C
Maestro solicita lectura. Último byte fue un dato El
M aest r o ya
ha leído un dato del
Esclavo y
quiere leer otro.
Bits del registro SSPSTAT. La última secuencia detectada fue un START -S=1 - R/W = 1 El Maestro lee datos del Esclavo El último byte recibido fue un dato - D/A = 1 - BF = 0 El buffer está vacío El bit CKP se pone a 0 para que la línea SCL pase a estado bajo, dando así tiempo al Esclavo para preparar el dato a enviar. El Esclavo manda el dato al Maestro escribiéndolo en el regis tro SSPBUF y haciendo CKP ← 1 para liberar la línea SCL.
Comunicación Serie Síncrona I2C
Maestro envía NACK El M aest r o ha enviado un NACK como respuesta al dato que ha recibido desde el Esclavo .
De este modo indica que ya no quiere recibir más datos. Bits del registro SSPSTAT. -S=1 La última secuencia detectada fue un START La lógica del Esclavo queda reseteada - R/W = 0 - D/A = 1 El último byte recibido fue un dato El buffer está vacío - BF = 0 El envío de un NACK queda identificado porque R/W
←
0.
Debido a que la recepción de un NACK da lugar a un reset de la lógica I2C del Esclavo. Esta situación da lugar a que los bits del registro SSPSTAT reflejen una situación incoherente. Indican que se ha recibido un dato del Maestro pero que el buffer está vacío.
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.
Comprobando el estado del bit SSPOV. Si ha ocurrido un overflow, será necesario hacer SSPOV ← 0 y leer SSPBUF para permitir nuevas recepciones. Los sucesos que tienen lugar tras un overflow dependen de cada caso. La lógica del Esclavo le enviará un NACK al Maestro. Típicamente el Maestro intentará volver a enviar el dato hasta que
reciba un ACK.
Tras escribir un dato en SSPBUF, el usuario debe comprobar el valor de WCOL para asegurar que no se ha producido una colisión.
En la práctica, no habrá colisiones si únicamente se escribe en SSPBUF cuando BF=0 y el Esclavo está transmitiendo al Maestro.
Comunicación Serie Síncrona I2C
Funcionamiento en modo
M a e st r o
Configurar el MSSP para funcionar en modo
M aest r o I2C.
- Definir líneas SDA y SCL como entradas. TRISC ← xxx11xxx
- Configurar el modo I2C.
SSPCON1 ← 00101000
- Seleccionar los baudios de la comunicación. Sólo se usan los bits 0 a 6
SSPADD ← [(fosc/Bd) / 4] – 1 Control del slew rate (SSPSTAT<7>)
100kHz 400kHz 1MHz
- Configurar interrupciones (si se necesitan) SSPIE / SSPIF -
BCLIE / BCLIF
Implementar alguno de los 6 eventos I 2C.
1. START 2. RESTART 3. STOP 4. Leer (recibir datos)
5. Reconocer (tras una lectura) * ACK * NACK
6. 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, SSPIF=1 (se debe poner a 0 por software). Se carga SSPBUF con la dirección a enviar por el bus y el bit R/W=0. c) a l e d e d) Los bits de la dirección salen por SDA hasta completar los 8 bits. u s q e s e) Se lee el bit de reconocimiento (ACK) recibido del esclavo y se e n i t n ó i b introduce ese bit en SSPCON2<6>. o p c 7 c u f) Al final del 9º flanco en SCL, se pone SSPIF=1 (hay que resetearlo). s e r i e g) Se cargan en SSPBUF los 8 bits del dato a enviar. d S h) Los bits del dato salen por SDA hasta completar la transmisión. i) Se lee el bit de reconocimiento (ACK) y se graba su valor en SSPCON<6>. j) Al final del 9º flanco en SCL se pone SSPIF a 1 (hay que ponerlo a 0). k) Se genera una condición de STOP poniendo a 1 el bit de habilitación de STOP (PEN) de SSPCON2. l) Una vez detectada la condición de STOP, se pone a 1 el flag SSPIF.
Comunicación Serie Síncrona I2C
Generación de una secuencia START Hacer SEN
←
1 para habilitar la generación de START.
Bit SSPCON2<0>.
Esto da lugar a que la línea SDA pase a “0” mientras SCL está a “1”.
Así se define una secuencia START, 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.
Bit SSPCON2<1>.
Esto da lugar a que se ejecuten secuencias de START sin ser precedidas de la correspondiente secuencia de STOP. De este modo, el Maestro no cede el control del bus en ningún momento.
Comunicación Serie Síncrona I2C
Generación de una secuencia STOP Hacer PEN
←
1 para habilitar la generación de STOP.
Bit SSPCON2<2>.
Esto da lugar a que la línea SDA pase a “1” mientras SCL está a “1”.
Se indica así que ha finalizado la recepción/transmisión. 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.
Bit SSPCON2<3>.
Entran bits cada pulso de SCL en SSPSR.
Tras el 8º bit, RCEN ← 0, SSPSR ← SSPBUF, BF ← 1, SSPIF ← 1. En ese momento SCL=0 y hay que leer el buffer para hacer BF ← 0. A continuación se puede enviar un ACK.
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>.
Hacer ACKEN
←
1 para habilitar la generación de ACK.
Bit SSPCON2<4>.
Esto libera la línea de datos (SDA ← 1), para que el receptor la ponga a “0” durante un pulso de reloj.
Tras este pulso de reloj, ACKEN ← 0 automáticamente. Es obligatorio mandar un ACK/NACK al final de cada transferencia. ¡¡IMPORTANTE!!
Generación de una escritura (transmisión) Basta con escribir el dato a enviar en SSPBUF.
- BF ← 1 mientras se está enviando el dato. - Cuando se ha enviado el 8º bit, BF ← 0. - El Maestro libera entonces SDA para recibir ACK. - Tras el 9º pulso de reloj, SSPIF ← 1.
Antes de iniciar un evento es necesario que el evento anterior haya finalizado. Conviene desarrollar rutinas que comprueben si el módulo está inactivo antes de lanzar un nuevo evento
Comunicación Serie Síncrona I2C
Control de errores en modo
M a e st r o
Las colisiones por escritura deben controlarse mediante observación del bit WCOL (SSPCON<7>).
Una colisión de escritura sucede cuando se intenta escribir un dato en el buffer antes de que haya terminado el evento anterior. No tiene asociada ninguna interrupción. Las colisiones de bus sí tienen asociada una interrupción: BCLIF.
Cuando SCL=1, el dato en SDA debe ser estable. 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). En ese caso se hace BCLIF ← 0 y se pone la lógica I 2C en reposo. La siguiente secuencia deberá ser un START. Un NACK puede indicar error o simplemente un estado de funcionamiento que debe ser detectado y procesado. El Maestro puede recibir un NACK si hay un error en el Esclavo o si
éste está desbordado. Según la situación, el Maestro deberá generar un RESTART, un STOP o un STOP/START.
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 (PIN_C3) Especifica el pin SCL (PIN_C4) Especifica el pin SCL Especifica la dirección del Esclavo Selecciona la especificación I2C rápida Selecciona la especificación I2C lenta Utiliza funciones I2C hardware. Resetea el WDT mientras espera a hacer una lectura de bus
SiSino se indica elelprotocolo II22CCpor NOFORCE_SW no se indica implementará protocolo porsoftware. software. NOFORCE_SW, ,implementará - Pensado para aquellos microcontroladores PIC que no disponen de MSSP. - Pensado para aquellos microcontroladores PIC que no disponen de MSSP. --ElElmodo modoEsclavo sinembargo, embargo,deberá deberáusarse usarsecon conelelMSSP. MSSP. Esclavo, ,sin
Comunicación Serie Síncrona I2C
Secuencias de START y STOP
i2c_start (); Si el PIC está en modo Maestro, esta instrucción genera una secuencia START, tras la cual la línea SCL se pone a “0” hasta que se escribe en el bus. Si se lanza otra secuencia START antes de que se produzca una secuencia STOP, se habrá ejecutado una secuencia RESTART.
i2c_stop (); Si el PIC está en modo Maestro, esta instrucción genera una secuencia STOP.