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 cómo cómo debe generar el código máquina.
* Funciones - Bloque Bloquess funcionales funcionales del programa. - Siempr Siempree debe incluirse una una función llamada main() .
#includ #include e stdio.h>
C*/
//Directiva //Directiva
/* Suma dos enteros */ i nt nt s um um a (i nt nt a ,b ,b ) { return return (a+b); (a+b);
//Devuel //Devuelve ve suma
}
* Sentencias
- Instr Instruccion ucciones es que definen lo que hace el programa y la secuencia de ejecución del mismo.
/* Función principal */ main() { int dato1,dat dato1,dato2; o2; //Declaració //Declaración n int res; //Declar //Declaració ación n
* Comentarios
- Imprescindib Imprescindibles les 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 declarar declarar todas las variables variables antes de poder utilizarlas utilizarlas,, indicando indicando el nombre asignado y el tipo de datos que en ella ella se van a almacenar (opcionalmente (opcionalmente también el valor inicial inicial asignado).
tipo no nombre_variable [= [=valor] ;
p.e.: int i;
Los tipos de datos aceptados en C estándar son cinco: char (carácter) intt in (entero) float (coma flotante en 32 bits) double (coma flotante en 64 bits) void (sin valor)
Las variables pueden ser locales o globales. Las variables locales locales sólo pueden ser usadas en la función 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).
Fundamentos de Lenguaje Lenguaje C para PICs El compilador de CCS acepta los siguiente tipos de variable. Especificación
Significado
Tamaño
Rango
char
carácter
8 bits
(sin signo) signo) 0 a 255 (sin
int
entero
8 bits
(sin signo) signo) 0 a 255 (sin
float
coma fl f lotante
32 bits
double
floa floatt doble precisió precisiónn
no soportado
No para PCM
void
sin valor
nulo
ninguno
int1
entero de de 1 bit
1 bit
0a1
int8
entero de d e 8 bits
8 bits
(sin in sig signo) no) 0 a 255 (s
int16
entero de 16 bits
16 bits
int32
entero de 32 bits
32 bits
0 a (2 32-1)
short
entero de de 1 bit
1 bit
0a1
long
entero de 16 bits
16 bits
6 bits de precisión
0 a 65535
0 a 65535
(sin signo) gno)
(sin si sign gno) o)
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 signed delante del tipo. tipo. El efecto que se consigue es el recogido en la siguiente tabla. Especificación
Significado
Tamaño
Rango
signed char
carác carácter ter con signo signo
8 bits
-128 a 127
sign si gned ed in intt
entero co con si signo
8 bits
-128 a 127
signed long
coma fl f lotante
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.
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.
Fundamentos de Lenguaje C para PICs Además de devolver valores, una función también puede recibir parámetros (denominados argumentos) según se indicó en su definición. Por ejemplo:
int suma (int a , int b) { return (a+b); } main() { int c; 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. La llamada por referencia usa la dirección de la variable que se pasa a la función.
Fundamentos de Lenguaje C para PICs
Operadores El lenguaje C define numerosos operadores mediante los cuales se construyen las expresiones (combinación de operadores y operandos).
Operadores aritméticos +
-
*
/
% (resto de división de enteros)
Operadores incremento y decremento x++
ó
++x
x--
ó
--x
Operadores relacionales >
>=
<
<=
==
>>
!=
Operadores lógicos &&
||
!
Operadores a nivel de bits &
|
^
~
a&b
a|b
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;
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. if (expresión) sentencia 1; else sentencia 2; (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; ... 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.
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.
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 ignorados 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 programa 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.
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.
#PRIO RITY 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.
Fundamentos de Lenguaje C para PICs
Fundamentos de Lenguaje C para PICs
Fundamentos de Lenguaje C para PICs
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)
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)
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. Intercambia los nibbles de la variable. swap (var);
#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;
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_ outp ut_hi high gh (pi (pin*); n*); output_bit (pin* , valor); output_ outp ut_flo float at (pin (pin*); *);
Pone a 0 el pin especificado. Ponee a 1 el pin espec Pon especificad ificado. o. Pone el pin especificado al valor valor indicado. indicado. Define el pin como entrada, entrada, quedando 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.
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 set_tris_b set_tris_c set_tris_d set_tris_e
(valor); (valor); (valor); (valor); (valor);
Carga el registro de dirección de datos con el valor indicado.
inpu in putt (pin pin*) *);;
Devuelve el estado del pin señalad señalado. o.
input_a ( input_b ( input_c ( input_d ( input_e in put_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 #de defi fine ne #def #d efin inee #def #d efin inee
P IN IN_A0 PIN PI N_A1 PIN_ PI N_A2 A2 PIN_ PI N_A3 A3
40 41 42 43
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 * _IO que esté activa. #USE FAST_IO FAST _IO (PUERTO) (PUERT O)
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 STAN DARD_IO (PUERTO) (PUER TO)
PUERTO: A ... E
Cada vez que se emplea una función output...() se inserta código previo para forzar a que el bit particular o el puerto completo sean de salida (mediante la carga del TRIS correspondiente). Si se trata de una función input...() se carga código para definir bit o puerto completo como de entrada. Ésta es la opción activa por defecto. Ej. #USE STANDARD_IO (C)
Puertos de E/S
#USE FIXED_IO (PUERTO_OUTPUTS=pin* (PUERTO_OUTP UTS=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 input……( ) ó output…( ), pero los pines se configuran de acuerdo con la información que acompaña a la directiva (sólo se indican los pines de salida) y no dependiendo de que la operación sea de entrada o de salida como sucede con #USE STANDARD_IO(PUERTO) Ej. USE FIXED_IO (B_OUTPUTS (B_OUTPUTS = PIN_B2 , PIN_B3)
El efecto de colocar una u otra directiva directiva se puede observar en los ficheros ficheros *.lst que se generan como resu resultado ltado de la compilación. compilación.
En general se puede decir que resulta más cómodo gestionar los pines de E/S de modo STANDARD, pero haciéndolo de modo FAST se adquiere más control de lo que se le está mandando al PIC y se optimiza código.
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 (fCLK/4)
bit 4
PSA
1 : Flanco de bajada
PSA: Asignación del prescaler 0: A signado a TMR0
1 : A signado a WDT
bits 2:0 PS2:PS0: Prescaler 0 00 : 0 01: 0 10: 0 11 :
1:2 para TM R0 / 1:1 para WDT. 1 :4 para TMR0/ 1:2 par a WD T. 1:8 para TM R0 / 1:4 pa ra WDT. 1: 16 pa ra TM R0 / 1 :8 par a W DT.
1 00: 1 01 : 1 10 : 1 11:
1 :32 p ar a TM R0 / 1 :1 6 p ara WDT. 1: 64 para TMR0 / 1 :32 para WDT. 1: 12 8 p ara TMR0 / 1: 64 p ara W DT. 1: 25 6 p ara TMR 0 / 1: 128 pa ra WD T.
Módulos Temporizadores Diagrama de bloques de TMR0 / WDT. CLKOUT (f OSC /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 ← 00h) (OPTION_REG ← 01h) (OPTION_REG ← 02h) (OPTION_REG ← 03h) (OPTION_REG ← 04h) (OPTION_REG ← 05h) (OPTION_REG ← 06h) (OPTION_REG ← 07h)
Se pueden agrupar constantes de distintos grupos con| .
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 pueda llevar a cabo su misión es necesario indicarlo así con la directiva #fuses . #fuses #fuses
[opciones], WDT [opciones] [opciones], NOWDT [opciones]
activado 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)
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:
Entero de 8 bits.
Puesta a cero del
(valor ← TMR0)
.
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 para Activar elel para evitar bucles infinitos. evitar bucles infinitos. f osc = 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 ← 1 1100000
TMR0= 183 (prescaler 1:1)
set_timer0 (183); 18 3
while (1) restart_wdt();
TMR0 ← 10110111
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 R C0).
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
fOSC/4 Reloj interno
Prescaler 1,2,4,8 2
T1CKPS1:T1CKPS0
Detección de sincronización Reloj interno
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 ← 00h) (T1CON ← 85h) (T1CON ← 87h) (T1CON ← 83h)
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)
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 una temporización 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 ... }
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: 0 0 01 : 0 010 : ..... 11 11:
bit 2
Postscaler 1:1 P ostsc al er 1 : 2 P ostsc al er 1 : 3 Postsc aler 1 :1 6
TMR2ON: Bit de encendido de TMR2 0 : Apagado
1 : Habilitado
bits 1:0 T2CKPS1:T2CKPS0: Selección del prescaler 0 0: 0 1: 1 x:
Pres caler 1 Pres caler 4 Pres caler 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 2
Comparador
T2CKPS1:T2CKPS0
PR2
T2OUTPS3:T2OUTPS0
(1)
La salida de TMR2 puede ser usada por el módulo SSP.
fOSC/4 Reloj interno
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).
(T2CON ← 00h) (T2CON ← 04h) (T2CON ← 05h) (T2CON ← 06h)
Lectura / Escritura en el módulo TMR2. valor = get_timer2 (); valor:
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 encendi do PR2 = 94
P R2 = 9 4 (prescaler 1:16) (postscaler 1:5)
W ← 20 h 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);
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. #INT_RTCC Desbordamiento de TMR0. (T0IF) #INT_RB Cambio en los pines RB<4:7>. (RBIF) (INTF) #INT_EXT Flanco en pin RB0. (ADIF) #INT_AD Fin de conversión A/D. #INT_TBE Buffer de transmisión USART vacío. (TXIF) Dato recibido en USART. (RCIF) #INT_RDA (TMR1IF) #INT_TIMER1 Desbordamiento de TMR1. (TMR2IF) #INT_TIMER2 Desbordamiento de TMR2. (CCP1IF) #INT_CCP1 Captura / Comparación en módulo CCP1. #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) #INT_BUSCOL Colisión de bus I2C. (BCLIF) #INT_EEPROM Escritura completa en EEPROM de datos. (EEIF)
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.
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.
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 Espera de de un un tiempo 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.
Periféricos de E/S
Teclados matriciales Varias teclas controladas con un número reducido de puertos E/S. +Vcc
SF1 SF2 SF3 SF4 EC1 EC2 EC3 EC4
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
SF1 SF2 SF3 SF4 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
EC2 1 1 1 1
EC3 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.
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 SC1 SC2 SC3 SC4
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
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 reduce el número de componentes externos.
F4
C1 C2 C3 C4
* La existencia de una interrupción asociada a cambios en los bits RB<4:7> avisa de que se ha pulsado una tecla.
Periféricos de E/S
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.
Teclado Matricial
4 16
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.
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 58 ó 510. 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)
Registro:
1 2
......
11
......
26
......
Memoria de pantalla para una línea (40 posiciones)
39 40
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 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
...
25 26 27
40 41 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 Máximo contraste a VSS Ajuste de Contraste 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
Periféricos de E/S
DATOS Internos Internos ElEl LCD LCD trabaja trabaja con con 88 bits bits
CONTROL
MCU
LCD DATOS
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 bajos 2º los 4 bits más bajos
BITS BITS DE DE CONTROL CONTROL E: E:
Validación Validación de dedatos. datos.
R/W: R/W: Operación Operacióndedelectura lectura(1) (1)oode deescritura escritura(0). (0). RS: RS: Selección Selecciónde de Registro RegistroInterno 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.
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
RS=1 (Registro de Datos) Leer contenido de DDRAM o CGRAM Escribir en DDRAM o CGRAM
BF:
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.
AC:
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
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 0 2 03 04 0 5 06 07 0 8 09 0A 0B 0C 0D 0E 0F 1 0 1 1 1 2 1 3 1 4
...
2 52 62 7
40 41 4 2 43 44 4 5 46 47 4 8 49 4A 4B 4C 4D 4E 4F 5 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.
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 .
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 que define las funciones indicadas a continuación. lcd_init (); Debe llamarse antes que ninguna otra función del fichero
.
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 coordenadas (1 , 1), y que la primera posición de la segunda línea es la (1 , 2).
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 , 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 Bit de datos Bit de datos Bit de datos
D4 D5 D6 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
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
Valor=18
Valor=254
%03u %u %2u %3u %d %x %X %4X
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 44.
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.
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 // 0=5x7, 1=5x10, 2=2 lines #define lcd_type 2 #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
0
Transferencia y Representación 0 0 1 DL N F x x DL
Nº bits de datos N → Nº líneas F → Nº ptos/carácter →
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 boolean nada; nada; Bit 1 boolean boolean rs; r s; Bit 2 boolean boolean rw; r w; Bit 3 boolean boolean enable; Resto bits int otros : 4; } lcd_control;
struct lcd _pines_datos _pines_datos { { int datos:8; 8 } 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 lcd_control = 5 #byte trisa = = 0x85 #byte lcd_datos = 8 #byte trisd = 0x88
PORTA PORTD
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.
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, , tiene una banda de frecuencia en la que 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 bits se necesitan 2· -1 comparadores (complejidad y coste excesivos).
Codif. 42
R
E3 E2
R
E1 E0
R
Q1
A1
⎡ 2 N ⋅ u e ⎤ ⎥ ⎣ V REF ⎦
E⎢ Q0
A0
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
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
pasos. 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: u s
=
V REF N
2
⋅
A0
+ A1 ⋅ 21 + L + AN -1 ⋅ 2N −1
Ejemplo: Red 2 N ·R
VREF
2 N·R Ai = “0” → Int. abierto Ai = “1” → Int. cerrado
2 N-1 ·R
21 ·R
i1
iN-1
i0
A0
A1
R A N-1 i
+ucc
us N -1
u s
/ ⋅∑ = −R ⋅ i = − R k =0
V REF N - k
2
⋅ R /
⋅ Ak = −V REF ⋅
A0 ⋅ 2
- N
1- N
+ A1 ⋅ 2
+ L + AN - 1 ⋅ 2
- 1
-ucc
Circuitos de Conversión A/D y D/A Circuitería adicional Dmpx analógico Fin conversión
Retenc.
Adapt.
Actuad.
Retenc.
Adapt.
Actuad.
D/A
µP
Inicio conversión
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
.
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
PCFG3:PCFG0 VDD 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
AN6 RE1
AN5 RE0
AN4 RA5
AN3 RA3
AN2 RA2
AN1 RA1
AN0 RA0
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
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 VREF+ A V REF+ A V REF+ D V REF+ A V REF+ V REF+ V REF+ V REF+ D V REF+
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
A A D D D D D A D D D D D D D
VREFA A VREFVREFVREFD VREF-
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
ADIF:
RCIF
TXIF
SSPIF
CCP1IF
TMR2IF
TMR1IF
de la interrupción del convertidor A/D
1 = Conversió n A/D c ompletada.
0 = C onversió n A/D aún no com plet ada.
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 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 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
AN X
R IC ≤ 1K
SS
R SS
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 adquisició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. 100ns) GO/DONE
←
1
Se carga ADRES Se pone GO/DONE a “0” Se levanta el flag ADIF CHOLD conectado a entrada analógica
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+)
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
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
0-FF00
0-FFC0
0-FFE0
0-FFFF
adc=16
El fichero 16f877.h incluye como primera directiva
.
Es necesario incluir información del tipo de conversor A/D. Por ello los ficheros C que usen este módulo deberán c omenzar por
El Módulo de Conversión A/D de los PIC Ejemplo
setup_adc_ports (A_ANALOG); setup_adc (ADC_CLOCK_INTERNAL); set_adc_channel (3); delay_us (20); valor = read_adc (); setup_adc (ADC_OFF);
W
←
ADCON0
W
←
W & 00111000
ADCON0 ← W
W ← 10000010 Banco 1 ADCON1 ← W Banco 0 W ← ADCON0 W ← W & 00111000 W ← W | 11000001 ADCON0 ← W W ← ADCON0 W ← W & 11000111 W ← W | 00011000 ADCON0 ← W GO/DONE ← 1 Espera a GO/DONE=0 W ← ADRESH TEMP ← W Banco 1 W ← ADRESL Banco 0 REGL ← W W ← TEMP REGH ← W
7
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 La(s) comparación(es) deben configurarse con la acción Comparación Comparació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
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 Modo de Modo de Modo de
captura, cada flanco descendente captura, cada flanco ascendente captura, cada 4º flanco ascendente captura, cada 16º flanco ascendente
1000 = Modo de comparación, CCPx=1 al igualarse (CCPxIF=1) 1001 = Modo de comparación, CCPx=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 odo P WM
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
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>
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 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 m odo 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
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 / CC Px
Q
S R
Lógica de salida
Coincidencia
TRISC<2>
Comparador TMR1H TMR1L
CCPxCON<3:0>
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 fun cione.
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. CCP 2: Resetea TMR1 y lanza una conversión A/D (si está activado).
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
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 / C CPx
S TRISC<2>
Comparador PR2
TMR2 0 CCPx 1 (si D 0) CCPRxH CCPRxL
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. ⎛
⎞ ⎟⎟ ⎝ f PWM ⋅ PS TMR 2 ⎠ f osc
log⎜⎜ Res =
log 2
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. 5. Configurar el módulo CCP para funcionar en modo PWM.
(T2CON)
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 ← 04h) (CCPxCON ← 05h) (CCPxCON ← 06h) (CCPxCON ← 07h)
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)
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 valor XXXXXXXX Y Y Y Y Y Y X X X X X X X X X X
de la PWM.
CCPRxL:CCPxCON<5:4> XXXXXXXX 0 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
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 :
T1_DISABLED T1_INTERNAL T1_EXTERNAL T1_EXTERNAL_SYNC
(T1CON ← 00h) (T1CON ← 85h) (T1CON ← 87h) (T1CON ← 83h)
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)
Se pueden agrupar constantes de distintos grupos con| .
Módulos CCP
Configuración del temporizador TMR2 setup_timer_2 (modo,periodo,postscaler ); modo :
T2_DISABLED T2_DIV_BY_1 T2_DIV_BY_4 T2_DIV_BY_16
periodo:
PR2 ← periodo
postscaler:
Número de necesarios para generar una interrupción. Es un valor entre 1 y 16.
(T2CON (T2CON (T2CON (T2CON
← ← ← ←
00h) 04h) 05h) 06h)
Módulos CCP
Ejemplo 1 setup_timer_2 (T2_DIV_BY_1 , 224 , 1); 300µs 22 4 100µs
(f osc = 3MHz)
W ← 00000000 W ← W | 00000100 T2CON ← W W ← E0 h Banco 1 PR2 ← W Banco 0
setup_ccp1 (CCP_PWM_PLUS_1); #use standard_io (C)
T = 300µs ⇒ PR2 = 224 D = 100µs ⇒ carga = 301 Carga = 301
W ← 111111011 Banco 1 TRISC ← W Banco 0 RC2 ← 0 CCP1CON ← 0 W ← 00011100 CCP1CON ← W
0 1 0 0 1 0 1 1 0 1
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);
22 4
¡¡ATENCIÓN!! ¡¡ATENCIÓN!! La Lainstrucció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); 4B h
CCPR1L ← 01001011 W ← CCP1CON W ← W & 11 001111 W ← W | 00010000 CCP1CON ← W
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 de manera manera automática automática una conversión una conversión A/D A/D cada 1ms. cada 1ms. f osc = 3MHz TMR1 = 750 (sin prescaler)
W ← 100001 01 T1CON ← W
set_timer1 (0); TMR1H ← 0 TMR1L ← 0
CCP2 = 750; 75 0
W ← 02 h CCPR2H ← W W ← EEh CCPR2L ← W
setup_ccp2 (CCP_COMPARE_RESET_TIMER); CCP2CON ← 0 W ← 00001011 CCP2CON ← W
MÓDULOS DE COMUNICACIÓN SERIE
Comunicación serie asíncrona
Características generales de la comunicación serie Los datos se envían bit a bit por una misma línea durante un tiempo fijo. 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 / RZ: Impulso: 1 / ...
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
También se conoce como Es uno de los dos módulos de E/S serie del PIC.
. (SCI).
El módulo USART puede actuar como sistema asíncrono . 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
OERR
RX9D
1: Transmisión síncrona
BRGH: Bit de selección de alto valor de baudios 1: Alta velocidad
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
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
OERR: Bit de error de 0: No hubo error
bit 0
1: Habilitada
FERR: Bit de error de 0: No hubo error
bit 1
1: Recepción de 9 bits
ADDEN: Bit de habilitación de detección de dirección 0: Deshabilitada
bit 2
1: Habilitado
CREN: Bit de habilitación de recepción continua 0: Deshabilitada
bit 3
FERR
RX9: Bit de habilitación de la recepción de 9 bits 0: Recepción de 8 bits
bit 4
ADDEN
SPEN: Bit de habilitación del puerto serie 0: Deshabilitado
bit 6
CREN
←
0
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
si BRGH = 1
En muchos casos resulta ventajoso usar BRGH=1 incluso para generar comunicaciones . 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 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.
4. Si se van a transmitir datos de 9 bits, hacer TX9
(PIE1<4>) ←
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
Control
FERR
Recuperación de datos
START
RX9
RX9D
SPEN
Interrupción
RSR
LSb
RCIF 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
←
- El tercer dato se pierde. Habría que leer RCREG dos veces.
1.
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
←
- El bit FERR se gestiona del mismo modo que el 9º bit del dato.
1.
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
←
4. Si se van a recibir datos de 9 bits, hacer RX9 5. Habilitar la recepción serie.
1. ←
(PIE1<5>)
1.
(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
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); 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); s1, s2 cad n c
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 ) y un módem o equipo de comunicación de datos (DCE o ). 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
Pin 1 Pin 2 Pin 3 Pin 4 Pin 5 Pin 6 Pin 7 Pin 8 Pin 9
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 MASA COMÚN DSR (E) PC puede enviar datos RTS (S) PC solicita envíar datos CTS (E) Le preguntan si PC listo para recibir RI (E) Indicador de llamada
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 tiempo 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ón Serie Síncrona I2C
Transferencia Transfere ncia síncrona La comunicación comunicación síncrona entre dos dispositivos dispositivos requiere que uno de ellos actúe como maestro y el otro, como esclavo. Dispositi Dispositivo vo Maestr Maestro: o: Es el que que gener generaa la señal señal de reloj reloj y el que tiene tiene capacidad de iniciar iniciar o finalizar finalizar una transferenci transferenciaa . Disposit Dispositivo ivo Escla Esclavo: vo: Recibe Recibe la seña señall de reloj reloj y no tiene tiene capacid capacidad ad para para iniciar una transferencia de información. Es posib posible le efec efectuar tuar una transmis transmisión ión continu continua a de bits de informació informaciónn. Dato
M ae s t r o
Clk
Dato
Esclavo
Maestro
Clk
Esclavo
Ref.
Ref.
Maestro Maestro Emitiendo Emitiendo
Maestro Maestro Recibiendo Recibiendo
Comunicación Serie Síncrona I2C
Comunicación Comunic ación serie síncrona síncrona en micro microcontrol controlador adores es PIC Se imple implement mentaa mediant mediantee el módulo módulo SSP
: Interfaz de comunicación serie síncrona. Está pensado para poder poder comunicarse con otros otros microcontrolado microcontroladores res o periféricos mediante transmisión serie síncrona.
EEPROM serie Registros de Desplazamiento Drive Dr ivers rs de Dis Displa plays ys Conversores A/D ....
Almacenamiento de datos no volátiles Almacenamiento Expansión de entradas entradas y/o salidas Reducción de conexiones Digitalización externa de señales
El módulo SSP tiene dos posibles modos de funcionamiento. nterface: ace: Inter Interface face de Periférico Periféricoss Serie Serie)) SPI (Serial Peripheral Interf
SPI: Es una Marca Marca Registrada de Motorola Corporation
I 2C (Inter-I ntegrated Circuit: Entre Circuitos Integrados)
I2C: Es una Marca Registrada Registrada de Philips
Comunicación Serie Síncrona I2C
Característica Carac terísticass general generales es del bus bus I2C El bus Inter-Integrated-C Inter-Integrated-Circ ircuit uit (I2C) fue creado por Philips.
Para 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 y varios . Configuración . En cualquiera de estas configuraciones, el dispos dispositivo itivo es el único que tiene capacidad de iniciar la transferencia, decidir con quiénn se realiza, quié realiza, el sentido sentido de la misma misma (envío o recepció recepciónn desde el punto de vista del ) y cuándo se finaliza.
El bus I 2C consiste físicamente en dos líneas de colector abierto.
SCL para el reloj (pin (pin RC3) RC3).. SDA para los datos (pin (pin RC4) RC4)..
La comunicación es, por tanto,
.
Comunicación Serie Síncrona I2C
Las líneas necesitan resistencias externas de
.
Para poder implementar un (Y cablea cableado). do). 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 quiere leer o escribir.
El protocolo I 2C incluye un mecanismo de comprobación (
).
- Cada transferencia de de 8 bits, el Maestro envía un un 9º pulso de reloj. - En ese instante, el dispositivo “transmisor” suelta la línea SDA y el “receptor” reconoce el dato enviado mediante un ACK (SDA ←0). - Se envía un NACK (deja SDA=1) SDA=1) para finalizar la transmisión.
Todos los cambios en SDA deben ocurrir mientras SCL=0.
Así se permit permitee diferen diferencia ciarr dos condiciones condiciones únicas: únicas: Secuencia START (S). El Maestro hace SDA←0 mientras SCL=1. Secuencia STOP (P). El Maestro hace SDA←1 mientras SCL=1.
Comunicación Serie Síncrona I2C
Fácil inclusión de nuevos dispositivos I 2C en el bus.
Una vez disponibl disponiblee el microcontr microcontrolado oladorr con sus funciones funciones de interface con bus interface bus I2C, la inclusión de un dispositivo I 2C adicional sólo precisaa su conexión precis conexión a las dos dos líneas líneas del bus (SDA (SDA y SCL), SCL) , que son las mismas para todos, todos, y asign asignarle arle una direcci dirección. ón.
Conexiones en el bus I 2C. VDD
R p ≥ Periférico Rp
V DD − V OL i OL
Rp Rs
Número máx. máx. de dispositivos dispositivos definidos por la capacida capacidadd en el bus: C max=400pF
Rs
SDA SCLL SC
C bus=10 – 400p 400pFF
Comunicación Serie Síncrona I2C
Direccionamiento de dispositivos en el bus I 2C
Formato de 7 bits: (A7-A6 (A7-A6-...-A1) -...-A1)
Reconocimiento (lo de debe be pone ponerr el Es Escl clav avo) o)
Lo “pone” “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 bits del esclavo esclavo
Lectura Lectura (1) o Escri Escritur turaa (0)
Formato de 10 10 bits: (A9-A8-A7-...-A0) Primer byte del Maestro
2º byte del del Maestro Maestro
En la R ACK A7A6A5A4A3 A2A1A0 ACK líneaSDA: S 1 1 1 1 0 A9 A9 A8 W ACK S Start
Lectura Lectura (1) o Escri Escritur turaa (0)
Reconocimientos del Escl Esclavo avo despu de spués és 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 Esclavoa 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 I 2C 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.
ACK
A7 A6 A5 A4 A3 A2 A1
Puesto por el Esclavo 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
ACK
5
6
7
Pulso ACK
8
9
P
Pulso ACK
Típica transmisión I 2C por parte del Esclavo.
A7 A6 A5 A4 A3 A2 A1
4
Puesto por el Maestro 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 (s egún el tipo de PIC). BSSP (Basic )
Modo Esclavo: Completo por hardware. Modo Maestro: Detección de bits START y STOP por hardware. 16C64, 16C65, 16C73, 16C74, ...
MSSP (Master
)
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 I2 C con dirección de 7 bits. Esclavo I2 C 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
Comunicación Serie Síncrona I2C
Diagrama de bloques del bus I 2C en modo 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 envío yy 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 I 2C en modo Bus de datos Leer
SSPM3:SSPM0 SSPADD<6:0>
Escribir
SSPBUF SDA In
RC4 SDA
SSPSR MSb
Generador de baudios
Reloj LSb
Generación de START/STOP ACK
RC3 SCL
Detección de START/STOP SCL In Colisión de bus
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 0 : V el oci dad estándar 1 : Alta velocidad (400k Hz) CKE: Bit de selección de niveles umbral en los pines 0: Especificaciones I 2C 1: Especificaciones SMBus D/A: Información del último byte transmitido 0: Dirección 1: Dato P: Bit de STOP Se pone a 1 si la última secuencia detectada es un 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 ( 0 : N o hay transmi sión 1 : Transmisión en pr ogreso ( 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 : N o ha habido coli sión 1 : Ha habid o 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: con direcciones de 7 bits. 0111 : con direcciones de 10 bits. 1000 : con CLK=Fosc / [4·(SSPADD+1)]. 1011 : Modo controlado por firmware ( inactivo). 1110: controlado por Fw(dir. de 7 bits, interrup. por bits de START y STOP). 1111: controlado porFw (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 0: Deshabilitada 1 : Habilita interrupciones por / Recepción) ACKSTAT: Bit de reconocimiento ( 0: Recibido ACK del 1: No se ha recibido ACK del ACKDT: Valor a transmitir tras una recepción ( / Recepción) 0: ACK 1: NACK ACKEN: Habilitación de secuencia ACK ( / Recepción) 0 : Desactivada 1 : Inicia secuencia de reconocimiento en SDA y SCL RCEN: Bit de habilitación de recepción ( ) 0: Recepción desactivada 1: Activa modo recepción PEN: Habilitación de una secuencia STOP ( ) 0: Desactivada 1 : Inicia situación de STOP en SDA y SCL RSEN: Habilitación de START repetido ( ) 0: Desactivado 1 : Inicia repetidas situaciones de START SEN: Habilitación de una secuencia START ( ) 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
PIR1 – PIE1
(0Ch – 8Ch)
PIR2 – PIE2
(0Dh – 8Dh)
o los baudios de la comunicación (
).
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 Antes de activar el módulo hay que configurar RC<3:4> como entradas. Configurar el MSSP en el registro SSPCON.
I 2C con direcciones de 7 bits o con direcciones de 10 bits. I 2C con o sin interrupciones por bits de START y STOP. Lo más habitual es que no se usen interrupciones por ST ART/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
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
pueden ser de 5 tipos.
Comunicación Serie Síncrona I2C
solicita escritura. Último byte fue una dirección El ha comenzado una operac ión de escritura con el inicio de una secuencia START o RESTART en el bus, seguida del envío de la dirección del . La dirección que hay en el bus pasa al registro SSPSR del 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 - R/W = 0 El va a escribir datos en el - D/A = 0 El último byte recibido fue una dirección - BF = 1 El buffer está lleno 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 .
Comunicación Serie Síncrona I2C
solicita escritura. Último byte fue un dato Tras el byte de dirección, el bytes de datos al .
puede enviar uno o más
Bits del registro SSPSTAT. -S=1 La última secuencia detectada fue un START - R/W = 0 El escribe datos en el - D/A = 1 El último byte recibido fue un dato - 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.
envía
Comunicación Serie Síncrona I2C
solicita lectura. Último byte fue una dirección El ha comenzado una operación de lec tura con el inicio de una secuencia START o RESTART en el bus, seguida del envío de la dirección del . Bits del registro SSPSTAT. -S=1 La última secuencia detectada fue un START - R/W = 1 El va a leer datos del - D/A = 0 El último byte recibido fue una dirección - 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 para preparar el dato a enviar. El
debe 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
solicita lectura. Último byte fue un dato El
ya ha leído un dato del
y quiere leer otro.
Bits del registro SSPSTAT. -S=1 La última secuencia detectada fue un START - R/W = 1 El lee datos del - D/A = 1 El último byte recibido fue un dato - 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 para preparar el dato a enviar. El Esclavo manda el dato al Maestro escribiéndolo en el registro SSPBUF y haciendo CKP 1 para liberar la línea SCL.
Comunicación Serie Síncrona I2C
envía NACK El ha enviado un NACK como respuesta al dato que ha recibido desde el .
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 - R/W = 0 La lógica del queda reseteada - D/A = 1 El último byte recibido fue un dato - BF = 0 El buffer está vacío 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 I 2C del . 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 está vacío.
pero que el buffer
Comunicación Serie Síncrona I2C
Control de errores en modo 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 SSPBUF para permitir nuevas recepciones.
←
0 y leer
Los sucesos que tienen lugar tras un overflow dependen de cada caso.
La lógica del Típicamente el reciba un ACK.
le enviará un NACK al . intentará volver a enviar el dato hasta que
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 está transmitiendo al .
Comunicación Serie Síncrona I2C
Funcionamiento en modo Configurar el MSSP para funcionar en modo
- Definir líneas SDA y SCL como entradas.
I 2C.
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 ← [(f osc/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).
c) Se carga SSPBUF con la dirección a enviar por el bus y el bit R/W=0. d) Los bits de la dirección salen por SDA hasta completar los 8 bits. e) Se el bit de reconocimiento (ACK) recibido del esclavo y se
introduce ese bit en SSPCON2<6>.
f) Al final del 9º flanco en SCL, se pone SSPIF=1 (hay que resetearlo). g) Se cargan en SSPBUF los 8 bits del dato a enviar. h) Los bits del dato salen por SDA hasta completar la transmisión. el bit de reconocimiento (ACK) y se graba su valor en i) Se
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
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 ponga a “0” durante un pulso de reloj.
1), para que el receptor la
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.
Comunicación Serie Síncrona I2C
Control de errores en modo 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 puede recibir un NACK si hay un error en el 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 Selecciona modo Especifica el pin SCL (PIN_C3) Especifica el pinSCL (PIN_C4) Especifica la dirección del Selecciona la especificación I2C rápida Selecciona la especificación I2C lenta Utiliza funciones I 2C hardware. Resetea el WDT mientras espera a hacer una lectura de bus
2 SiSino nose seindica indica NOFORCE_SW implementaráelelprotocolo protocoloII2CCpor 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 , ,sin modo sinembargo, embargo,deberá deberáusarse usarsecon conelelMSSP. MSSP.
Comunicación Serie Síncrona I2C
Secuencias de ST ART y STOP
i2c_start (); Si el PIC está en modo , 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 secuencia STOP.
, esta instrucción genera una