ccs manual basic
TRANSCRIPT
-
8/22/2019 Ccs Manual Basic
1/65
INTRODUCCION
El micro controlador PIC16F877A de Microchip pertenece a una gran familia de microcontroladores de 8 bits (bus
de datos) que tienen las siguientes caractersticas generales que los distinguen de otras familias:
- Arquitectura Harvard
- Tecnologa RISC
- Tecnologa CMOS
Estas caractersticas se conjugan para lograr un dispositivo altamente eficiente en el uso de la memoria de datos y
programa y por lo tanto en la velocidad de ejecucin.
CARACTERISTICAS MICROCONTROLADOR PIC 16F877A
CPU RISC
Slo 35 instrucciones que aprender Todas las instrucciones se ejecutan en un ciclo de reloj, excepto los saltos que requieren dos
Frecuencia de operacin de 0 a 20 MHz (DC a 200 nseg de ciclo de instruccin)
Hasta 8k x 14 bits de memoria Flash de programa
Hasta 368 bytes de memoria de datos (RAM)
Hasta 256 bytes de memoria de datos EEPROM
Hasta 4 fuentes de interrupcin
Stack de hardware de 8 niveles
Reset de encendido (POR)
Timer de encendido (PWRT) Timer de arranque del oscilador (OST)
Sistema de vigilancia Watchdog timer.
Proteccin programable de cdigo
Modo SEP de bajo consumo de energa
Opciones de seleccin del oscilador
Programacin y depuracin serie In-Circuit (ICSP) a travs de dos patitas
Lectura/escritura de la CPU a la memoria flash de programa
Rango de voltaje de operacin de 2.0 a 5.5 volts
Alta disipacin de corriente de la fuente: 25mA
Rangos de temperatura: Comercial, Industrial y Extendido
33 pines de Entrada/Salida
Encapsulado: 40 pines DIP, 44 pines PLCC y 44 pines TQFP
Bajo consumo de potencia:
- Menos de 0.6mA a 3V, 4MHz
- 20 A a 3V, 32 Khz
- Menos de 1A corriente de standby
-
8/22/2019 Ccs Manual Basic
2/65
PERIFERICOS
Timer0: Contador/Temporizador de 8 bits con pre-escalador de 8 bits
Timer1: Contador/Temporizador de 16 bits con pre-escalador
Timer0: Contador/Temporizador de 8 bits con pre-escalador y post-escalador de 8 bits y registro de periodo.
Dos mdulos de Captura, Comparacin y PWM
Convertidor Analgico/Digital: de 10 bits, hasta 8 canales
Puerto Serie Sncrono (SSP)
Puerto Serie Universal (USART/SCI)
Puerto Paralelo Esclavo (PSP): de 8 bits con lneas de protocolo
-
8/22/2019 Ccs Manual Basic
3/65
Podra existir la interrogante de el porqu se utiliza este micro y no otro, pues la razn es sencilla ya que son los
micros que mas tengo por el momento y que fcilmente satisfacen las cosas que pienso plantear.
Bueno considerando que ya hayan ledo el Manual en Castellano pues ahora si podemos continuar con seguridad.
Para empezar vamos a dar algunos conceptos sobre el Lenguaje a utilizar y algunas cosas que servirn en los
futuros programas que realicemos.
ESTRUCTURA DE UN PROGRAMA EN CCS
En la estructura de un programa en C pues existen ciertos bloques fundamentales que hacen un programa entre
estos podemos mencionar:
# Directivas del Preprocesador
// Declaracin del Prototipo de Funciones
// Declaracin de Variables Globales
// Definicin de Constantes
// Programa Principal (main)main(){
Varibles Locales;
Bloque de sentencias;
-
8/22/2019 Ccs Manual Basic
4/65
Llamadas a funciones;
..
.
}
// Definicin de Funciones
Funcin () {
Variables Locales Funcin;
Bloque de Sentencias;
..
.
}
En lneas generales esta es la estructura bsica de un programa en C, podemos decir que CCS difiere un poco del
clsico ANSI C notaran eso aquellos que programan en C.
Bueno para continuar vamos a dar algunos conceptos de la estructura de un programa en C.
Directivas del Preprocesador
Todas las directivas del preprocesador comienzan con el carcter # seguido por un comando especfico. Algunas de
estas directivas son extensiones del C estndar. El C proporciona una directiva del preprocesador, que loscompiladores aceptan, y que permite ignorar o actuar sobre los datos que siguen. El compilador de CCS admite
cualquier directiva del preprocesador que comience con PRAGMA, lo que asegura la compatibilidad con otros
compiladores.
A continuacin se describen algunas directivas del compilador que se emplearn para programar los
microcontroladores PIC en estas prcticas.
#include
#include archivo
Directiva que permite cargar un archivo con las definiciones del microcontrolador a utilizar, donde pueden
encontrarse informacin referente a: funciones, argumentos, disposicin de pines y otros.
Ejm: #include
#FUSES opciones
Esta directiva define qu fusibles deben activarse en el dispositivo cuando se programe. Esta directiva no afecta a
la compilacin; sin embargo, esta informacin es necesaria para algunos programadores de dispositivos. Las
opciones que existen para el PIC16F877A son:
-
8/22/2019 Ccs Manual Basic
5/65
Tipo de Oscilador:
LP Low power osc < 200 khz
XT Crystal osc 4mhz for PCM/PCH) (>10mhz for PCD)
RC Resistor/Capacitor Osc with CLKOUT
Wach Dog Timer (WDT):
NOWDT No Watch Dog Timer
WDT Watch Dog Timer
Power Up Timer (Retardo de encendido):
NOPUT No Power Up Timer
PUT Power Up Timer
Proteccin de Cdigo:
PROTECT Code protected from reads
NOPROTECT Code not protected from reading
Brown Out Reset:
NOBROWNOUT No brownout reset
BROWNOUT Reset when brownout detected
Programacin por Vajo Voltaje:
NOLVP No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/OLVP Low Voltage Programming on B3(PIC16) or B5(PIC18)
Proteccin de Cdigo EEPROM:
NOCPD No EE protection
CPD Data EEPROM Code Protected
Proteccin de Memoria de Programa:
WRT_5% Lower 255 bytes of Program Memory is Write Protected
WRT_25% Lower quarter of Program Memory is Write ProtectedWRT_50% Lower half of Program Memory is Write Protected
NOWRT Program memory not write protected
Modo de Depurador utilizando ICD:
NODEBUG No Debug mode for ICD
DEBUG Debug mode for use with ICD
Ejm: #FUSES XT,NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP
-
8/22/2019 Ccs Manual Basic
6/65
#USE DELAY (CLOCK=frecuencia)
Esta directiva indica al compilador la frecuencia del procesador, en ciclos por segundo, a la vez que habilita el uso
de las funciones DELAY_MS() y DELAY_US().
Ejm:
#USE DELAY (CLOCK=4000000) // Definimos un cristal de 4MHz
#USE FAST_IO (puerto)
Esta directiva afecta al cdigo que el compilador generar para las instrucciones de entrada y salida. Este mtodo
rpido de hacer I/O ocasiona que el compilador realice I/O sin programar el registro de direccin TRIS por lo tanto
consume menos memoria de programa. El usuario debe asegurarse de que los registros TRIS estn configurados
adecuadamente antes de operar con los puertos. El puerto puede ser A-G.
Ejm: #use fast_io(A)
#USE FIXED_IO (puerto_OUTPUTS=pin_x#, pin_x#...)
Se genera cdigo relativo a la direccin de los datos de manera previa cada vez que aparece una funcin integrada
del tipo input( ) output( ), pero los pines se configuran de acuerdo con la informacin que acompaa a la
directiva (slo se indican los pines de salida) y no dependiendo de que la operacin sea de entrada o de salida. Usamas memoria que el fast_io. USE FIXED_IO (B_OUTPUTS = PIN_B2 , PIN_B3)
Ejm: #use fixed_io(a_outputs=PIN_A2, PIN_A3)
#USE STANDARD_IO (puerto)
Cada vez que se emplea una funcin output...() se inserta cdigo 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 funcin input...()
se carga cdigo para definir bit o puerto completo como de entrada. sta es la opcin activa por defecto y usa mas
memoria que el fast_io. El puerto puede ser A-G.
Ejm: #use standard_io(A)
Estas son algunas de la muchas directivas del preprocesador, ojo no son todas pero considero que por ahora son
las importantes a futuro estudiaremos algunas ms que sern de utilidad.
En lnea
-
8/22/2019 Ccs Manual Basic
7/65
RE: CURSILLO DE CCS PARA PIC'S
DEFINICION DE CONSTANTES
La directiva #DEFINE viene del ANSI C y est presente en el CCS, es muy til ya que podemos predefinir algunosvalores que sean necesarios en nuestro programa, permitiendo tener un programa mejor estructurado.
Ejm:
#define pi 3.1415
#define BITS 8
a=a+BITS; //Lo mismo que a=a+8;
#define hi(x) (x
-
8/22/2019 Ccs Manual Basic
8/65
VARIABLES LOCALES: Las variables de tipo local son las que se definen dentro de una funcin especfica y su
caracterstica es que solo pueden ser utilizadas dentro de esa funcin, lo que permite que puedan existir variables
en distintas funciones con el mismo nombre.
A continuacin conoceremos algunos tipos de variables:
unsigned define un nmero de 8 bits sin signo
unsigned int define un nmero de 8 bits sin signo
int define un nmero de 8 bits sin signo
char define un nmero de 8 bits sin signo
long define un nmero de 16 bits sin signo
long int define un nmero de 16 bits sin signo
signed define un nmero de 8 bits con signo
signed int define un nmero de 8 bits con signo
signed long define un nmero de 16 bits con signofloat define un nmero de 32 bits en punto flotante
short define un bit
short int define un bit
int1 define una variable de 1 bit
int8 define una variable de 8 bits
int16 define una variable de 16 bits
int32 define una variable de 32 bits
void sin valor
Ejm:
int aux;
char nombre;
float contador;
PROGRAMA PRINCIPAL (main)
La funcin main es la contiene las instrucciones o ordenes se ejecutaran a fututo en nuestro programa, encargada
de gestionar el llamado a las interrupciones y funciones que se tengan.
Como esta funcin no retorna ningn valor alguno posee el tipo de variable void y al no poseer argumentos es de
tipo void, la declaracin de esta funcin es la siguiente:
void main (void) {
// Variables locales;
// Bloque de sentencias;
// Llamada a funciones
}Siempre el cuerpo de cualquier funcin est entre llaves {}.
-
8/22/2019 Ccs Manual Basic
9/65
OPERADORES Y EXPRESIONES
Una expresin de asignacin tradicional es de la forma expr1 = expr1 operador expr2, pero tambin puede ser
representada por otra ms corta expr1 operador = expr2. En la siguiente tabla se resumen los operadores de
asignacin compuesta y su significado:
Operador Descripcin
+= Asignacin de suma
-= Asignacin de resta
*= Asignacin de multiplicacin
/= Asignacin de divisin
%= Asignacin de resto de divisin
= Asignacin de desplazamiento a la derecha
&= Asignacin de AND de bits
|= Asignacin de OR de bits^= Asignacin de OR exclusivo de bits
~= Asignacin de negacin de bits
++ Incremento
-- Decremento
Los operadores aritmticos para realizar operaciones matemticas son:
Operador Descripcin Ejemplo
+ Suma (enteros o reales) resul = var1 + var2
- Resta (enteros o reales) resul = var1 - var2
* Multiplicacin (enteros o reales) resul = var1 * var2
/ Divisin (enteros o reales) resul = var1 / var2
- Cambio de signo en enteros o reales -var1
% Mdulo; rango = n [A1]% 256
Los operadores relaciones tienen como objetivo comparar dos operandos y dar un resultado entero, 1 si es
verdadero y 0 si es falso.
Operador Descripcin
< Menor que
> Mayor que
= Mayor o igual que
== Igual a
!= Distinto de
Los operadores lgicos, al igual que los operadores relacionales, devuelve 1 o 0 tras la evaluacin de sus
operandos.
-
8/22/2019 Ccs Manual Basic
10/65
Operador Descripcin
! No lgico (NOT)
&& Y lgico (AND)
|| O lgico (OR)
Existen tambin los llamados operadores de manejo de bits que permiten actuar sobre los operandos a nivel de
bits y solo pueden ser de tipo entero incluyendo el tipo char.
Operador Descripcin
~ Negacin de bits (complemento a 1)
& Y de bits (AND)
^ O exclusivo de bits (EXOR)
| O de bits (OR)
>> Desplazamiento a la derecha
-
8/22/2019 Ccs Manual Basic
11/65
Sentencia if-else
Se evala una expresin y, si es cierta, se ejecuta el primer bloque de cdigo (o sentencia 1). Si es falsa, se
ejecuta el segundo.
if (expresin)
sentencia 1;
else
sentencia 2;
Sentencia switch
Substituye a if-else cuando se realiza una seleccin mltiple que compara una expresin con una lista de
constantes enteras o caracteres. Cuando se da una coincidencia, el cuerpo de sentencias asociadas a esaconstante se ejecuta hasta que aparezca break.
switch (expresin){
case constante 1:
grupo 1 de sentencias;
break;
case constante 2:
grupo 2 de sentencias;break;
...
default:
grupo n de sentencias;
}
default es opcional y el bloque asociado se ejecuta slo si no hay ninguna coincidencia con las constantes
especificadas.
Sentencia de bucle for
Se emplea para repetir una sentencia o bloque de sentencias.
for (inicializacin ; condicin ; incremento){
sentencia(s);
}
En la inicializacin se le asigna un valor inicial a una variable que se emplea para el control de la repeticin del
bucle.
-
8/22/2019 Ccs Manual Basic
12/65
La condicin se evala antes de ejecutar la sentencia. Si es cierta, se ejecuta el bucle. Si no, se sale del mismo.
El incremento establece cmo cambia la variable de control cada vez que se repite el bucle.
Es posible anidar bucles for para modificar dos o ms variables de control.
Sentencia de bucle while
La repeticin se lleva a cabo mientras sea cierta una expresin.
while (expresin){
sentencia(s);
}
La expresin se evala antes de cualquier iteracin. Si es falsa, ya no se ejecuta la sentencia o bloque de
sentencias.
Sentencia de bucle do-while
do{
sentencia(s);
}while (expresin);
Las sentencias se ejecutan antes de que se evale la expresin, por lo que el bucle se ejecuta siempre al menos
una vez.
COMENTARIOS
Los comentarios se incluyen en el cdigo fuente para explicar el sentido y la intencin del cdigo al que
acompaan. Son ignorados por el compilador y no afectan a la longitud ni rapidez de ejecucin del cdigo final.
Hay dos formatos posibles para los comentarios.
Formato 1. Empiezan por // y finalizan con el final de la lnea.
// Esto es un comentario.
Formato 2. Empiezan por /* y finalizan por */. No es posible anidar comentarios con este formato.
/* Esto tambin es un comentario */
Un comentario se puede colocan en cualquier lugar del programa y pueden tener la longitud y el nmero de lneas
que se quiera.
-
8/22/2019 Ccs Manual Basic
13/65
E/S DISCRETA
Las funciones que manejan un bit son:
input(pin) Retorna el valor 0 1 del pin indicado.
output_bit(pin,valor) Colocar el pin indicado a 0 1.
output_high(pin) Colocar el pin a estado alto 1.
output_low(pin) Colocar el pin a estado bajo 0.
Las que manejan un byte son:
input_x() Donde x es el nombre del puerto (A, B,...). int de 8 bits.
output_x(valor) Sacar el valor por el puerto X (A, B,....).
Nota: Estas funciones aparecen en el manual pero no son reconocidas por el compilador, si queremos leer o
escribir bytes deberemos utilizar la directiva #byte PUERTO = dir. Puerto
Ejm: #BYTE PORTB = 0x06
Las que configuran los pines:
port_b_pullups(value) Activamos o desactivamos las Rpull-up del puerto B.
set_tris_x(valor) Permite configurar los puertos X (A, B,...) para que sus pines sean entradas o salidas.
Un 1 indica entrada y un 0 salida.
MANIPULACIN DE BIT
Para manipular un bit podemos encontrarnos con:
bit_clear(var,bit) Borra el dgito especificado de la variable.
bit_set(var,bit) Pone a uno el digito especificado de la variable.
bit_test(var,bit) Retorna el valor del bit de la variable indicada.
MANIPULACIN DE BYTE
rotate_left (address,byte) Rotar a la izquierda un bit de un array o una estructura. El bit MSB pasa a ser el LSB.
rotate_right (address,byte) Rotar a la derecha un bit de un array o una estructura. El bit LSB pasa a ser el MSB.
shift_left (addres,byte,value) Desplaza hacia la izquierda un bit de un array o una estructura. A diferencia de
rotate aqu debemos especificar el valor (value) con el que queremos que rellene los huecos desplazados y byte
indica el nmero de bytes implicados.
shift_right (addres,byte,value) Desplaza hacia la derecha un bit de un array o una estructura.
-
8/22/2019 Ccs Manual Basic
14/65
swap (value) Intercambia el nible bajo con el nible alto del byte dado. No retorna el resultado, lo deja en value.
RETARDOS
delay_cycles (count) Realiza retardos de ciclos de instruccin segn el valor indicado en count (1..255). Un ciclo de
instruccin es igual a cuatro perodos de reloj.
delay_us (time) Realiza retardos del valor especificado en microsegundos (1..65535). Esta funcin no utiliza los
timers internos pero es preciso utilizar la directiva #use delay especificando la frecuencia del reloj.
delay_ms (time) Realiza retardos especificando el valor en milisegundos (1..65535). Esta funcin no utiliza los
timers internos pero es preciso utilizar la directiva #use delay especificando la frecuencia del reloj.
Creando proyectos con el Compilador
Ahora si con todo lo avanzado creo solo queda comenzar, a utilizar el compilador CCS.
Para eso vamos a explicar cmo crear un nuevo proyecto en CCS, aqu van los pasos a seguir:
1.- Paso:
Abrir compilador CCS, seguidamente seleccionamos la pestaa Project luego hacemos click en PIC Wizard y
guardamos el proyecto con el nombre que se quiere.
-
8/22/2019 Ccs Manual Basic
15/65
2.- Paso: A continuacin seleccionamos el microcontrolador a utilizar y seleccionar los parmetros que se
requieran.
3.-
Paso: Luego de pulsar OK, se tendr la siguiente ventana con los valores seleccionados.
-
8/22/2019 Ccs Manual Basic
16/65
4.- Podemos ver en la 1ra lnea de cdigo una directiva donde se llama a un archivo en este caso Ejemplo 1.hdicho archivo contiene los siguientes datos:
Cdigo:[Seleccionar]#include
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc
-
8/22/2019 Ccs Manual Basic
17/65
es indistinto que estos parmetros estn fuera o dentro del archivo fuente, entonces para comodidad tal vez,
podramos copiar todo el contenido del archivo.
Con eso el archivo quedara de la siguiente manera:
Ahora podemos hacer algunos ejemplos algo sencillos.......
-
8/22/2019 Ccs Manual Basic
18/65
Ejemplo 1:
Comencemos con algo bsico y sencillo que ser el primer ejemplo a realizar, y paso a explicar el problema y en lo
que consistir el programa.
Problema: Encender y apagar un Led con un periodo de 500ms de manera cclica.
Recursos a Utilizar: Salida de Led Puerto B, Pin RBO.
Primero definimos las directivas de control:
Cdigo: (c)[Seleccionar]#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
19/65
#FUSES NOCPD // No EE protection
#FUSES NOWRT // Program memory not write protected
#use delay(clock=4000000) // Oscilador a 4MHz
En este caso optamos por etiquetar la direccin del puerto B y tambin el Bit RB0 con los nombres de PORTB y Led
respectivamente como sigue a continuacin:
Cdigo: (c)[Seleccionar]#byte PORTB=0x06 // Direccin del PortB
#bit Led = PORTB.0 // Bit asignada a identificador Led
Luego iniciamos con la funcin principal (main), y seguidamente es aqu donde definimos el puerto a utilizar y
declarar sus estados ya sean salida o entrada, como en el ejemplo solo se requiere una salida y las pueden ser
entradas o salidas se opto por que todo el puerto trabaje como salidas, eso depender de las necesidades que se
tengan.
SET_TRIS_X(value) // Donde X puede tomar los valores de A,B,C,D,E
Estas funciones permiten escribir directamente los registros tri-estado para la configuracin de los puertos. Cada
bit de value representa una patilla. Un '1' indica que la patilla es de entrada y un '0' que es de salida.
Ejm:
set_tris_b(0x00); // Notacin en Hex
set_tris_b(0b00000000); // Notacin Binaria
set_tris_b(0); // Notacin Decimal
Cdigo: (c)[Seleccionar]// FUNCION PRINCIPAL
void main(void){
set_tris_b(0x00); // Definimos el Puerto B como salida
portb = 0x00; // Limpiamos Puerto B
while(TRUE){ // Bucle infinito
Led = 0; // Apago el LED
delay_ms(500); // Espero 500ms.
Led = 1; // Enciendo el LED
delay_ms(500); // Espero 500ms.
}
}
Como podemos ver en el resto del cdigo luego de definir el puerto a utilizar limpiamos dicho puerto con la nica
finalidad de que no haya ningn dato indeseable a la salida del puerto B.
Luego ingresamos al bucle infinito, en cual introducimos el cdigo para la tarea a realizar, como ya etiquetamos el
bit RB0 pues solo basta con llamar al nombre y asignarle el estado que deseamos a su salida.
Algunas consideraciones que se deben tomar a la hora de programar en C son:
http://mikropic.delphiaccess.com/forum/index.php?topic=49.0http://mikropic.delphiaccess.com/forum/index.php?topic=49.0http://mikropic.delphiaccess.com/forum/index.php?topic=49.0http://mikropic.delphiaccess.com/forum/index.php?topic=49.0http://mikropic.delphiaccess.com/forum/index.php?topic=49.0http://mikropic.delphiaccess.com/forum/index.php?topic=49.0http://mikropic.delphiaccess.com/forum/index.php?topic=49.0http://mikropic.delphiaccess.com/forum/index.php?topic=49.0 -
8/22/2019 Ccs Manual Basic
20/65
- Siempre el finalizar una instruccin o llamada a funcin acabar con el ;.
- En la funcin principal no olvidar abrir y cerrar llaves ({}).
- Lo mismo para el bucle While deben abrir y cerrar llaves ({}).
- Considerar que en el C se distinguen maysculas de minsculas sea no es lo mismo Led = 0; que LED = 0;
en el primer caso no habr problemas pero el segundo si ya que es una variable que no est definida el programa.
Perdn por ser tan extenso en las explicaciones pero creo cuando uno comienza es necesario despejar dudas, ya
que se entiende que esta es una gua bsica de programacin y no un curso avanzado, a futuro vamos a reducir
las explicaciones y proponer mas cdigo que sea de utilidad.
Este primer programa se puede hacer de diversas formas utilizando otras funciones, entonces hagamos un par de
ellas y luego pasamos a otro ejemplo.
Ejemplo 1v1: Ac utilizamos la funcin output_bit(pin,valor)
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
21/65
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
22/65
#use delay(clock=4000000) // Oscilador a 4MHz
#byte PORTB=0x06 // Direccin del PortB
#bit Led = PORTB.0 // Bit asignada a identificador Led
// FUNCION PRINCIPAL
void main(void){
set_tris_b(0x00); // Definimos el Puerto B como salida
PORTB = 0x00; // Limpiamos Puerto B
while(TRUE){ // Bucle infinito
Led = ~ Led; // Apago y Encendido del LED
delay_ms(500); // Espero 500ms.
}
}
Viendo los ejemplos anteriores podemos decir hay mil un maneras de llegar a la solucin y eso solo depender decada programador y la visin que tenga sobre la posible solucin.
Ejemplo 2:
-
8/22/2019 Ccs Manual Basic
23/65
Problema: Realizar un programa para generar 8 salidas secuenciales, por los menos que tengan tres secuencias
con un periodo de 750ms de manera cclica.
Recursos a Utilizar: Salida del Puerto B.
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
24/65
PORTB = 0b00000000; // Limpiamos Secuencia anterior
delay_ms(3000); // Retardo 3s.
// Secuencia #2
PORTB = 0b11100111;
delay_ms(750);
PORTB = 0b11000011;
delay_ms(750);
PORTB = 0b10000001;
delay_ms(750);
PORTB = 0b10000001;
delay_ms(750);
PORTB = 0b11000011;
delay_ms(750);
PORTB = 0b11100111;
delay_ms(750);
PORTB = 0b00000000; // Limpiamos Secuencia anterior
delay_ms(3000); // Retardo 3s.
// Secuencia #3
PORTB = 0b10000001;
delay_ms(750);
PORTB = 0b01000010;delay_ms(750);
PORTB = 0b00100100;
delay_ms(750);
PORTB = 0b00011000;
delay_ms(750);
PORTB = 0b00011000;
delay_ms(750);
PORTB = 0b00100100;
delay_ms(750);
PORTB = 0b01000010;
delay_ms(750);
PORTB = 0b10000001;
delay_ms(750);
PORTB = 0b00000000; // Limpiamos Secuencia anterior
delay_ms(3000); // Retardo 3s.
}
}
Esta es una posible solucin al problema planteado, podra ser una mejor opcin el utilizar vectores o arrays, yo
los conozco como vectores unidimensionales, ac un ejemplo como seria utilizando vectores.
-
8/22/2019 Ccs Manual Basic
25/65
Ejemplo 2v1: En este ejemplo utilizamos vectores unidimensionales.
Cdigo: (c) [#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
26/65
delay_ms(3000); // Retardo 3s.
// Secuencia #3
for(i=0;i
-
8/22/2019 Ccs Manual Basic
27/65
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
28/65
#FUSES NOLVP // No low voltage prgming, B3(PIC16) or B5(PIC18) used for
I/O
#FUSES NOCPD // No EE protection
#FUSES NOWRT // Program memory not write protected
#use delay(clock=4000000) // Oscilador a 4MHz
#byte PORTB=0x06 // Direccin del PortB
// FUNCION PRINCIPAL
void main(void){
set_tris_b(0b00000010); // Definimos Bit RB1 como entrada y el resto como
salida
portb = 0x00; // Limpiamos Puerto B
while(TRUE){ // Bucle infinito
if(input(PIN_B1)){ // Opcion cuando pulsador Boton ON
output_bit(PIN_B0,1); // Enciendo el LED
}
if(input(PIN_B2)){ // Opcion cuando pulsador Boton OFF
output_bit(PIN_B0,0); // Apago el LED
}
}
}
-
8/22/2019 Ccs Manual Basic
29/65
Ejemplo 4:
Manejo de Visualizador de 7 Segmentos
En realidad estn formados por ocho LED (siete segmentos y un punto decimal), puede mostrar cualquier nmero
desde 0 hasta 9.
Existen dos tipos de configuraciones en estos visualizadores de LED de 7 segmentos, uno nodo Comn y otro
Ctodo Comn como a continuacin se muestra:
Tabla con los nmeros a utilizar en configuracin Ctodo Comn:
-
8/22/2019 Ccs Manual Basic
30/65
Problema: Realizar un contador decimal que se exhiba en un dispar de 7 segmentos, cada nmero deber estar
exhibido durante un segundo.
Recursos a Utilizar: RB0 (Salida Display 7 Segmentos).
Cdigo: (c)[Seleccionar]#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
31/65
set_tris_b(0x00); // Definimos el Puerto B como salida
portb = 0x00; // Limpiamos Puerto B
while(TRUE){ // Bucle infinito
// Utilizando valores DEC(63,6,91,79,102,109,125,7,127,111)
portb = 63; // Digito 0
delay_ms(1000); // Espero 1s.
portb = 6; // Digito 1
delay_ms(1000); // Espero 1s.
portb = 91; // Digito 2
delay_ms(1000); // Espero 1s.
portb = 79; // Digito 3
delay_ms(1000); // Espero 1s.
portb = 102; // Digito 4
delay_ms(1000); // Espero 1s.
portb = 109; // Digito 5
delay_ms(1000); // Espero 1s.
portb = 125; // Digito 6
delay_ms(1000); // Espero 1s.
portb = 7; // Digito 7
delay_ms(1000); // Espero 1s.
portb = 127; // Digito 8
delay_ms(1000); // Espero 1s.
portb = 111; // Digito 9
delay_ms(1000); // Espero 1s.
// Utilizando valores HEX(3F,06,5B,4F,66,6D,7D,07,7F,6F)
portb = 0x3F; // Digito 0
delay_ms(1000); // Espero 1s.
portb = 0x06; // Digito 1
delay_ms(1000); // Espero 1s.
portb = 0x5B; // Digito 2
delay_ms(1000); // Espero 1s.
portb = 0x4F; // Digito 3
delay_ms(1000); // Espero 1s.
portb = 0x66; // Digito 4
delay_ms(1000); // Espero 1s.
portb = 0x6D; // Digito 5
delay_ms(1000); // Espero 1s.
portb = 0x7D; // Digito 6
delay_ms(1000); // Espero 1s.
portb = 0x07; // Digito 7
delay_ms(1000); // Espero 1s.
portb = 0x7F; // Digito 8
delay_ms(1000); // Espero 1s.
portb = 0x6F; // Digito 9
-
8/22/2019 Ccs Manual Basic
32/65
delay_ms(1000); // Espero 1s.
}
}
Ejemplo 4v1: Otra forma cmo podramos hacerlo, utilizando vectores.
Cdigo: (c)[Seleccionar]#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
33/65
Problema: Realizar un programa que visualice en el Display el valor introducido por el puerto A, por ejemplo si
tenemos un en el puerto A de 0110 en el Display se cera 5.
Recursos a Utilizar: RB0 (Salida Display 7 Segmentos), RC0~RC3 (Entradas digitales).
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
34/65
// FUNCION PRINCIPAL
void main(void){
int dato;
set_tris_b(0x00); // Definimos el Puerto B como salida
set_tris_c(0xFF); // Definimos el Puerto C como entrada
portb = 0x00; // Limpiamos Puerto B
while(TRUE){ // Bucle infinito
dato = PORTC; // Guardamos el valor del PORTA en la variable
dato
switch(dato){
case 0: PORTB = Tab7Seg[0]; // Digito en variable 7Seg
break;
case 1: PORTB = Tab7Seg[1]; // Digito en variable 7Seg
break;
case 2: PORTB = Tab7Seg[2]; // Digito en variable 7Seg
break;
case 3: PORTB = Tab7Seg[3]; // Digito en variable 7Seg
break;
case 4: PORTB = Tab7Seg[4]; // Digito en variable 7Seg
break;
case 5: PORTB = Tab7Seg[5]; // Digito en variable 7Seg
break;
case 6: PORTB = Tab7Seg[6]; // Digito en variable 7Seg
break;
case 7: PORTB = Tab7Seg[7]; // Digito en variable 7Segbreak;
case 8: PORTB = Tab7Seg[8]; // Digito en variable 7Seg
break;
case 9: PORTB = Tab7Seg[9]; // Digito en variable 7Seg
break;
default:PORTB = 0x00; // Opcion cuando el dato no esta en el rango
de 0~9
break;
}
}
}
En programa realizado utilizamos la sentencia Switch-Case como se puede ver es muy sencillo de implementarlo.
Ejemplo 6:
Contador de 0~99 con un Visualizador de 7 Segmentos
-
8/22/2019 Ccs Manual Basic
35/65
Problema: Realizar un programa que visualice en el Display un contador del 0 al 99.
Recursos a Utilizar: RB0 (Salida Display 7 Segmentos), RC0~RC1 (Salida Bit control de Display).
El hecho de visualizar datos en display de 7 segmentos de la forma en que se muestra en el esquema anterior,
obliga a interconectar entre si los pines correspondientes a los segmentos del dgito 1 con los pines de los
segmentos del dgito 2, de esta manera se ahorran lneas de conexin.
El mtodo utilizado para la visualizacin dnamica consiste en visualizar cada dgito durante un instante de tiempoy a una velocidad tal que gracias a la persistencia del ojo el efecto final es que todos los dgitos estn encendidos
al mismo tiempo.
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
36/65
#FUSES NOBROWNOUT // No brownout reset
#FUSES NOLVP // No low voltage prgming, B3(PIC16) or B5(PIC18) used for
I/O
#FUSES NOCPD // No EE protection
#FUSES NOWRT // Program memory not write protected
#use delay(clock=4000000) // Oscilador a 4MHz
#byte PORTB=0x06 // Direccin del PortB
#byte PORTC=0x07 // Direccin del PortC
#bit Unidad = PORTC.0 // Bit asignada a identificador Unidad
#bit Decena = PORTC.1 // Bit asignada a identificador Decena
int Tab7Seg[10]={63,6,91,79,102,109,125,7,127,111};
// FUNCION PRINCIPAL
void main(void){
int uni=0,dec=0;
set_tris_b(0x00); // Definimos el Puerto B como salida
set_tris_c(0x00); // Definimos el Puerto C como Salida
portb = 0x00; // Limpiamos Puerto B
portc = 0x00; // Limpiamos Puerto B
while(TRUE){ // Bucle infinito
PORTB = Tab7Seg[dec]; // Enva decenasUnidad = 0; // Habilita el display de decenas
delay_ms(60);
Unidad = 1;
PORTB = Tab7Seg[uni]; // Enva unidades
Decena = 0; // Habilita el display de unidades
delay_ms(60);
Decena = 1;
uni++; // Incrementa unidades
if ( uni > 9 ){
uni = 0; // Reinicia unidades
dec++; // Incrementa decenas
if ( dec > 9 ){
dec = 0; // Reinicie decenas
}
}
}
}
A futuro cuando toquemos el tema de Interrupciones, sera bueno realizar el mismo ejemplo pero utilizando un
Timer (Temporizador).
-
8/22/2019 Ccs Manual Basic
37/65
Ejemplo 7:
Contador ascendente-descendente de dos dgitos con un Visualizador de 7 Segmentos
Problema: Realizar un programa que visualice en el Display un contador ascendente-descendente de dos dgitos
con un Visualizador de 7 Segmentos.
Recursos a Utilizar: RB0 (Salida Display 7 Segmentos), RC0~RC1 (Salida Bit control de Display), RA0(Bit quedetermina modo contador).
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
38/65
I/O
#FUSES NOCPD // No EE protection
#FUSES NOWRT // Program memory not write protected
#use delay(clock=4000000) // Oscilador a 4MHz
#byte PORTB=0x06 // Direccin del PortB
#byte PORTC=0x07 // Direccin del PortC
#bit Unidad = PORTC.0 // Bit asignada a identificador Unidad
#bit Decena = PORTC.1 // Bit asignada a identificador Decena
#bit Opcion = PORTC.2 // Bit asignada a identificador Opcin
int Tab7Sega[10]={63,6,91,79,102,109,125,7,127,111};
int Tab7Segd[10]={111,127,7,125,109,102,79,91,6,63};
// FUNCION PRINCIPAL
void main(void){
int uni=0,dec=0;
set_tris_b(0x00); // Definimos el Puerto B como salida
set_tris_c(0xFC); // Definimos el Puerto C Bits 0,1 como Salida y el
resto Entrada
portb = 0x00; // Limpiamos Puerto B
portc = 0x00; // Limpiamos Puerto B
while(TRUE){ // Bucle infinitoif(Opcion == 1){ // Conteo Ascendente
PORTB = Tab7Sega[dec]; // Enva decenas
Unidad = 0; // Habilita el display de decenas
delay_ms(50);
Unidad = 1;
PORTB = Tab7Sega[uni]; // Enva unidades
Decena = 0; // Habilita el display de unidades
delay_ms(50);
Decena = 1;
uni++; // Incrementa unidades
if ( uni > 9 ){
uni = 0; // Reinicia unidades
dec++; // Incrementa decenas
if ( dec > 9 ){
dec = 0; // Reinicie decenas
}
}
}
if(Opcion == 0){ // Conteo Ascendente
PORTB = Tab7Segd[dec]; // Enva decenas
-
8/22/2019 Ccs Manual Basic
39/65
Unidad = 0; // Habilita el display de decenas
delay_ms(50);
Unidad = 1;
PORTB = Tab7Segd[uni]; // Enva unidades
Decena = 0; // Habilita el display de unidades
delay_ms(50);
Decena = 1;
uni++; // Incrementa unidades
if ( uni > 9 ){
uni = 0; // Reinicia unidades
dec++; // Incrementa decenas
if ( dec > 9 ){
dec = 0; // Reinicie decenas
}
}
}
}
}
-
8/22/2019 Ccs Manual Basic
40/65
Ejemplo 8:
Mostrando texto en Visualizador de 7 Segmentos
Problema: Ahora utilizamos 4 Display multiplexados para generar un texto en este caso HOLA.
Recursos a Utilizar: RB0 (Salida Display 7 Segmentos), RC0~RC3 (Salida Bit control de Display).
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
41/65
I/O
#FUSES NOCPD // No EE protection
#FUSES NOWRT // Program memory not write protected
#use delay(clock=4000000) // Oscilador a 4MHz
#byte PORTB=0x06 // Direccin del PortB
#byte PORTC=0x07 // Direccin del PortC
void tiempo(){
delay_ms(1);
PORTB=0;
PORTC=0;
delay_ms(1);
}
// FUNCION PRINCIPAL
void main(void){
set_tris_b(0x00); // Definimos el Puerto B como salida
set_tris_c(0x00); // Definimos el Puerto C como Salida
portb = 0x00; // Limpiamos Puerto B
portc = 0x00; // Limpiamos Puerto B
while(TRUE){ // Bucle infinito
PORTB=0b11110110; // Caracter H
PORTC=0b00001110; // Habilitamos 1 Displaytiempo();
PORTB=0b10111111; // Caracter O
PORTC=0b00001101; // Habilitamos 2 Display
tiempo();
PORTB=0b10111000; // Caracter L
PORTC=0b00001011; // Habilitamos 3 Display
tiempo();
PORTB=0b11110111; // Caracter A
PORTC=0b00000111; // Habilitamos 4 Display
tiempo();
}
}
-
8/22/2019 Ccs Manual Basic
42/65
Ejemplo 9:
Pantallas de Cristal Lquido (LCD)
Es comn cuando se comienza el manejo de LCD desplegar el mensaje HOLA, pues este ejemplo no va ser la
excepcin.
Una LCD estndar es una pantalla de cristal lquido con una matriz de 16, 32, 40 u 80 caracteres de 5x7
pixeles, contando adems con un microcontrolador (generalmente el Hitachi 44780) que lo gobierna el cual posee
una interfaz de 8 o 4 bits, con 3 seales de control. Normalmente cada lnea contiene entre 8 y 80 caracteres, y
suelen ser capaces de mostrar caracteres ASCII, japoneses, griegos...; o smbolos matemticos. Su bus de
conexin puede ser de 4 u 8 bits.
El consumo de este tipo de mdulos es muy bajo (75mW), y, gracias a su sencillo manejo, son ideales para
dispositivos que requieren una visualizacin pequea o media.
En este caso utilizaremos un LCD 2 x 16, eso significa de dos filas y 16 columnas, para esto se requiere asignar
un puerto del PIC como bus de datos entre el LCD y el PIC, adems un bus de control con el cual se realiza la
-
8/22/2019 Ccs Manual Basic
43/65
gestin del LCD.
En el circuito utilizado, se empleara el puerto D para enviar los datos de 4 bits al modulo LCD, adems se utiliza
tres lneas del puerto D como bus de control. El potencimetro adicional nos sirve para aumentar o disminuir el
contraste del LCD.
Para realizar el control desde el PIC, primeramente se debe llamar a la librera LCD.c en el cual se encuentran
todas las rutinas para el trabajo del LCD.
En dicho archivo podemos encontrar las siguientes funciones para el manejo de LCD:
lcd_init ();
-
8/22/2019 Ccs Manual Basic
44/65
Debe llamarse antes que ninguna otra funcin del fichero lcd.c.
Tal y como aparece en el fichero, adems de borrar el display, configura el LCD para trabajar como sigue:
a) En formato de 4 bits, con dos lneas y con caracteres de 58 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 posicin del LCD a la que se debe acceder.
Recurdese que la primera posicin de la primera lnea tiene coordenadas
(1 , 1), y que la primera posicin de la segunda lnea es la (1 , 2).
lcd_putc (dato);
Escribe dato en la posicin a la que apunta el puntero de direcciones.
La variable dato es de tipo char, y se definen algunos caracteres especiales:
\f Borra el display
\n Se posiciona en el inicio de la segunda lnea
\b Retrocede una posicin
lcd_getc (x , y);
Devuelve el carcter que ocupa la posicin (x , y) del LCD.
Por defecto, este driver usa siete bits del puerto D para establecer a comunicacin entre el LCD y el
microcontrolador.
D0 Enable
D1 RSD2 R/W
D3 -
D4 Bit de datos D4
D5 Bit de datos D5
D6 Bit de datos D6
D7 Bit de datos D7
Para utilizar el puerto D es necesario colocar una lnea de cdigo antes del llamado a la librera LCd.c, dicho cdigo
indica en la misma librera LCD.c.
#define use_portd_lcd TRUE // Puerto a utilizar para el LCD
-
8/22/2019 Ccs Manual Basic
45/65
#include // Libreria para el manejo del LCD a utilizar
Para el puerto B sigue de la siguiente manera:
#define use_portb_lcd TRUE // Puerto a utilizar para el LCD
#include // Libreria para el manejo del LCD a utilizar
NOTA.- Ojo solo est permitido utilizar los puertos B y D.
Bueno con todo lo visto ahora podemos realizar el primer programa para el manejo del LCD.
Problema: Desplegar un mansaje en la pantalla de cristal liquido (LCD).
Recursos a Utilizar: RD (Puerto a utilizar).
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
46/65
Ejemplo 9v1: El mismo ejemplo pero utilizando el carcter especial (\n) Salto al comienzo de la segunda lnea.
Cdigo: (c)[Seleccionar]#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
47/65
#use delay(clock=4000000) // Oscilador a 4MHz
#define use_portd_lcd TRUE // Puerto a utilizar para el LCD
#include // Libreria para el manejo del LCD a utilizar
// FUNCION PRINCIPAL
void main(void){
char Linea1[4]={'H','o','l','a'};
char Linea2[13]={'F','o','r','o',' ','M','i','k','r','o','p','i','c'};
int i;
lcd_init(); // Iniciamos LCD
lcd_putc('\f'); // Limpiamos LCD
while(TRUE){ // Bucle infinito
lcd_gotoxy(6,1); // Linea 1 y Columna 6
for(i=0;i
-
8/22/2019 Ccs Manual Basic
48/65
Ejemplo 9v3: Ahora utilizando vectores.
Cdigo: (c)#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
49/65
Ejemplo 10:
Teclados Matriciales
Los teclados matriciales son muy utilizados pues permiten mayor cantidad de teclas con menos lneas de control,
pero requiere un proceso de bsqueda y traduccin de tecla. El arreglo matricial permite T teclas segn T = L x C
donde L es el nmero de lneas y C el nmero de columnas, la cantidad de pines utilizados son L + C.
-
8/22/2019 Ccs Manual Basic
50/65
El valor generado por una tecla presionada, se obtiene de la combinacin de la lectura de las filas y las columnas.
El compilador posee dentro de sus libreras una dedicada al manejo de Teclados matriciales, dicho archivo lleva el
nombre de KBD.c alguna de sus caractersticas son:
- Permite manejar un teclado de 3x3
- Puede trabajar con los puertos B y D.
Dado que el circuito propuesto se tiene un teclado de 4x4, se tuvo que realizar ciertas modificaciones al archivooriginal KBD.c para su correcto funcionamiento.
El archivo nuevo posee el nombre de Tec4x4.c esto para evitar posibles confusiones o reemplazos con el original.
En dicho archivo podemos encontrar las siguientes funciones para el manejo del Teclado matricial:
kbd_init ();
Debe llamarse antes que ninguna otra funcin del fichero Tec4x4.c.
kbd_getc();
-
8/22/2019 Ccs Manual Basic
51/65
Funcin que retorna el valor presionado en el Teclado, este puede guardado en una variable de tipo char.
Ejm: Tecla=kbd_getc();
Por defecto, este driver usa el puerto D para establecer a comunicacin entre el Teclado y el microcontrolador.
Pines utilizados para el Teclado:
B0 D0 -> Columna 1
B1 D1 -> Columna 2
B2 D2 -> Columna 3
B3 D3 -> Columna 4
B4 D4 -> Fila 1
B5 D5 -> Fila 2
B6 D6 -> Fila 3
B7 D7 -> Fila 4
Para utilizar el puerto B es necesario colocar una lnea de cdigo antes del llamado a la librera Tec4x4.c, dicho
cdigo indica en la misma librera Tec4x4.c.
#define use_portb_lcd TRUE // Puerto a utilizar para el LCD
#include Tec4x4.c // Libreria para el manejo del LCD a utilizar
NOTA.- Ojo solo est permitido utilizar los puertos B y D.
Problema: Mostrar en un LCD la te tecla pulsada de un Teclado matricial 4x4.
Recursos a Utilizar: RD (LCD), RB (Teclado 4x4).
El siguiente programa lee el teclado, y espera que un valor sea introducido, si es as, lo imprime en pantalla y
espera a que se suelte el botn para evitar imprimir dos veces.
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
52/65
#define use_portb_kbd TRUE // Puerto B, a utilizar para el Teclado Matricial
#include "Tec4x4.c" // Libreria para el manejo del Teclado Matricial a
utilizar
#define use_portd_lcd TRUE // Puerto D, a utilizar para el LCD
#include // Libreria para el manejo del LCD a utilizar
// FUNCION PRINCIPAL
void main(void){
char c=0; // Variable donde se almacena tecla pulsada
lcd_init(); // Iniciamos LCD
kbd_init();
lcd_putc('\f'); // Limpiamos LCD
lcd_gotoxy(4,1); // Linea 1 y Columna 6
printf(lcd_putc,"Mikropic");
lcd_gotoxy(1,2); // Linea 2 y Columna 2
printf(lcd_putc,"Tecla Pulsada:");
while(TRUE){ // Bucle infinito
do{ // Espera hasta...
c=kbd_getc();
}while(c==0); //...pulsar una tecla
lcd_putc(c); // Muestra tecla pulsada en lcd
lcd_putc("\b"); // Retrocede una posicion(escribe encima de la ultima
tecla mostrada)}
}
Ejemplo 10v1: Propongo un cdigo que realiza el mismo proceso pero este es por barrido, lo bueno sera
implementarlo para verificar su correcto funcionamiento.
Este cdigo trabaja bajo la siguiente explicacin. Para leer el teclado se debe preguntar cada fila, colocando en una
fila en particular un 0 y en las otras 1. Si se presiona una tecla de esa fila, se introduce un 0 al microcontrolador,
en otro caso un 1. Al ir verificando la presencia de un 0 en la bsqueda podemos retornar algn valor diferente si
es que no se ha presionado ninguna tecla. Sino retornar el valor asignado a esa tecla.
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
53/65
#FUSES NOLVP // No low voltage prgming, B3(PIC16) or B5(PIC18) used for
I/O
#FUSES NOCPD // No EE protection
#FUSES NOWRT // Program memory not write protected
#use delay(clock=4000000) // Oscilador a 4MHz
#byte PORTB=0x06 // Direccin del PortB
#define use_portd_lcd TRUE // Puerto a utilizar para el LCD
#include // Libreria para el manejo del LCD a utilizar
#define Col_1 0b11111110
#define Col_2 0b11111101
#define Col_3 0b11111011
#define Col_4 0b11110111
char var=0;
void Teclado(){
PORTB=Col_1;
if(PORTB==0b11101110) var='1';
if(PORTB==0b11011110) var='4';
if(PORTB==0b10111110) var='7';
if(PORTB==0b01111110) var='*';
PORTB=Col_2;
if(PORTB==0b11101101) var='2';
if(PORTB==0b11011101) var='5';
if(PORTB==0b10111101) var='8';
if(PORTB==0b01111101) var='0';
PORTB=Col_3;
if(PORTB==0b11101011) var='3';
if(PORTB==0b11011011) var='6';
if(PORTB==0b10111011) var='9';
if(PORTB==0b01111011) var='#';
PORTB=Col_4;
if(PORTB==0b11100111) var='A';
if(PORTB==0b11010111) var='B';
if(PORTB==0b10110111) var='C';
if(PORTB==0b01110111) var='D';
}
-
8/22/2019 Ccs Manual Basic
54/65
// FUNCION PRINCIPAL
void main(void){
set_tris_b(0xF0); // Definimos Parte alta entrada parte baja salida
lcd_init(); // Iniciamos LCD
PORTB=0x00;
lcd_putc('\f'); // Limpiamos LCD
lcd_gotoxy(4,1); // Linea 1 y Columna 6
printf(lcd_putc,"Mikropic");
lcd_gotoxy(1,2); // Linea 2 y Columna 2
printf(lcd_putc,"Tecla Pulsada:");
while(TRUE){ // Bucle infinito
Teclado();
lcd_putc(var); // Muestra tecla pulsada en lcd
lcd_putc("\b"); // Retrocede una posicion(escribe encima de la ultima
tecla mostrada)
}
}
Lectura y escritura de la memoria de datos EEPROM
En la familia de microcontroladores 16F87X tanto la memoria EEPROM de datos como la memoria de programa
FLASH puede ser modificada sin necesidad de utilizar un programador exterior.
Se dispone de seis registros de SFR para leer y escribir sobre la memoria no voltil, estos registros son: EECON1,
EECON2, EEDATA, EEDATH, EEADR y EEADRH. Para direccionar las 256 posiciones de la memoria EEPROM delPIC16F876 y 16F877 basta con 8 bit, por ello para escribir o leer solo hacen falta el registro EEADR para
direccionar la posicin y el registro EEDATA para colocar el dato ledo o escrito. Sin embargo para poder escribir o
leer datos en la memoria FLASH que puede tener hasta 8K palabras de 14 bits hacen falta dos registros para
direccionar la posicin de memoria, por ello se utiliza el registro EEADR concatenado con el registro EEADRH que
contiene la parte alta de la palabra de direccionamiento de memoria. De forma similar se utilizan los registros
EEDATA concatenado con el registro EEADRH que contiene los 6 bit de mayor peso de las palabras de 14 bits.
Adems para controlar el proceso de lectura y escritura de la memoria EEPROM y FLASH se dispone de dos
registros: el EECON1 y el EECON2.
-
8/22/2019 Ccs Manual Basic
55/65
Lectura de la memoria de datos
Para leer un dato de la EEPROM, el registro EEADR es cargado con la direccin de la EEPROM donde se encuentra
el dato y luego el microcontrolador copia el dato de dicha posicin a EEDATA. A continuacin hay que poner a 0 el
bit EEPGD (EECON1), para apuntar a la memoria de datos EEPROM. Una vez que se ponga a 1 la bandera RD
(EECON1), el dato estar disponible en el registro EEDATA, donde permanecer hasta la siguiente escritura o
lectura.
Escritura de la memoria de datos
La escritura, que es en realidad una programacin, es ms compleja por razones de seguridad. Antes de escribir
un dato en la EEPROM, debe ponerse a 1 la bandera de activacin de escritura WR (EECON1). Para transferir
el dato desde el registro EEDATA a la direccin de la EEPROM a la que apunta EEADR, debe ejecutarse una
secuencia obligatoria indicada por el fabricante. Posteriormente, cuando se ha realizado con xito la operacin de
la bandera EEIF (PIR1) se pone a 1. Si no lo hace, el almacenamiento ha sido incorrecto y no se ha realizado.
Funciones para el manejo de la Eeprom interna en CCS
READ_CALIBRATION(n)
Esta funcin lee "n" posiciones de la memoria de calibracin de un 14000.
Ejemplo:
Cdigo: (c)
Fin = read_calibration(16);
READ_EEPROM(address)
Esta funcin lee un byte en la direccin (address) de Eeprom especificada. La direccin puede ser 0-63.
Ejemplo:
-
8/22/2019 Ccs Manual Basic
56/65
Cdigo: (c)[#define LAST_VOLUME 10
volume = read_EEPROM (LAST_VOLUME );
NOTA.- Segn el manual de CCS lee la ubicacin de memoria de eeprom de datos (8 bits o 16 bit dependiendo del
dispositivo).
WRITE_EEPROM(address, value)
Esta funcin escribe un byte de datos en la direccin de memoria EEPROM especificada, address puede valer 0-63;
value es el byte de datos a escribir; Esta funcin puede tardar varios milisegundos para ejecutarse.
Ejemplo:
Cdigo: (c)
#define LAST_VOLUME 10
volume++;
write_eeprom(LAST_VOLUME,volume);
Preprocesador relevante:
#La direccin de ROM = {lista};
Tambin podemos utilizar una directiva de preprocesador para poner los datos en la memoria eeprom.
Ejemplo:
Cdigo: (c)
#rom 0x1100={1,2,3,4,5,6,7,8}; // Datos a guardar en la EEPROM
Interrupciones relevantes:
INT_EEPROM
Esta es instruccin es utiliza cuando la escritura de la EEPROM est completa por tanto produce una interrupcin
en el microcontrolador a futuro profundizaremos sobre el tema de las Interrupciones en los microcontroladores PIC
y en especifico este caso.
Ejemplo 11:
http://mikropic.delphiaccess.com/forum/index.php/topic,49.15.html?PHPSESSID=e27f7202ea78153d346411d305d4406fhttp://mikropic.delphiaccess.com/forum/index.php/topic,49.15.html?PHPSESSID=e27f7202ea78153d346411d305d4406fhttp://mikropic.delphiaccess.com/forum/index.php/topic,49.15.html?PHPSESSID=e27f7202ea78153d346411d305d4406fhttp://mikropic.delphiaccess.com/forum/index.php/topic,49.15.html?PHPSESSID=e27f7202ea78153d346411d305d4406f -
8/22/2019 Ccs Manual Basic
57/65
Con todo lo visto anteriormente ahora podemos hacer algunos ejemplos sencillos.
La memoria de datos EEPROM posee 256 bytes en el PIC16F877A donde puede almacenar de forma indefinida
cualquier dato que se desee retener, ya que estos datos guardados estarn presentes cuando se apague la
alimentacin.
Para poner en prctica la programacin de la memoria EEPROM, y aprovechando que se conoce ya como mostrar
datos en la pantalla LCD, se va a realizar un programa que permita visualizar los valores en el mismo.
Problema: Guardar una secuencia de datos en la memoria EEPROM del PIC con la directiva # rom.
Recursos a Utilizar: Memoria EEPROM del PIC y RD (LCD).
En la primera imagen podemos apreciar los datos que se tienen en la memoria EEPROM del PIC, como podemos
ver todos los datos son FF.
-
8/22/2019 Ccs Manual Basic
58/65
Esto es antes de aplicar la lnea de cdigo:
Cdigo: (c)
#rom 0x2100={1,2,3,4,5,6,7,8}; // Datos a guardar en la EEPROM
Una vez aplicado el cdigo en nuestro programa tendremos el siguiente cambio en la memoria EEPROM del PIC,
como podemos ver en la siguiente imagen:
Ahora que tenemos los datos guardamos en la EEPROM, visualicmoslo en el LCD.
-
8/22/2019 Ccs Manual Basic
59/65
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
60/65
lcd_putc('\f'); // Limpiamos LCD
lcd_gotoxy(1,1);
printf(lcd_putc," EEPROM Interna ");
lcd_gotoxy(1,2);
printf(lcd_putc," Foro Mikropic ");
delay_ms(3000);
while(TRUE){
lcd_gotoxy(1,1);
printf(lcd_putc,"DATOS: ");
for(i=0;i
-
8/22/2019 Ccs Manual Basic
61/65
// Cargamos Texto en la EEPROM interna
for(i=0;i
-
8/22/2019 Ccs Manual Basic
62/65
Secuencias para manejar motores paso a paso Unipolares
Existen tres secuencias posibles para este tipo de motores, las cuales se detallan a continuacin. Todas lassecuencias comienzan nuevamente por el paso 1 una vez alcanzado el paso final ( 4 u 8 ). Para revertir el sentidode giro, simplemente se deben ejecutar las secuencias en modo inverso.
Secuencia Normal: Esta es la secuencia ms usada y la que generalmente recomienda el fabricante. Con estasecuencia el motor avanza un paso por vez y debido a que siempre hay al menos dos bobinas activadas, seobtiene un alto torque de paso y de retencin.
Secuencia del tipo wave drive: En esta secuencia se activa solo una bobina a la vez. En algunos motores estobrinda un funcionamiento mas suave. La contrapartida es que al estar solo una bobina activada, el torque de paso
y retencin es menor.
Secuencia del tipo medio paso: En esta secuencia se activan las bobinas de tal forma de brindar un movimientoigual a la mitad del paso real. Para ello se activan primero 2 bobinas y luego solo 1 y as sucesivamente. Comovemos en la tabla la secuencia completa consta de 8 movimientos en lugar de 4.
Ahora si pongamos el esquema con el PIC y el circuito propuesto por Jose:
-
8/22/2019 Ccs Manual Basic
63/65
Cdigo: (c)
#include // PIC a utilizar
#FUSES XT // Crystal osc
-
8/22/2019 Ccs Manual Basic
64/65
int Sec1_Der[4]={3,6,12,9};
int Sec1_Izq[4]={9,12,6,3};
int Sec2_Der[4]={1,2,4,8};
int Sec2_Izq[4]={8,4,2,1};
int Sec3_Der[8]={1,3,2,6,4,12,8,9};
int Sec3_Izq[8]={9,8,12,4,6,2,3,1};
// FUNCION PRINCIPAL
void main(void){
int t=100,i=0;
set_tris_b(0x00); // Definimos el Puerto B como Salida
set_tris_c(0xFF); // Definimos el Puerto C como Entrada
PORTB = 0x00; // Limpiamos Puerto B
while(TRUE){ // Bucle infinito
if(Dir == 1){
if((PORTC&0x0E) == 2){ // Secuencia 1 Dir. Derecha
PORTB = Sec1_Der[i];
delay_ms(t);
i++;
if(i == 4) i = 0;
}
if((PORTC&0x0E) == 4){ // Secuencia 2 Dir. Derecha
PORTB = Sec2_Der[i];
delay_ms(t);
i++;
if(i == 4) i = 0;
}
if((PORTC&0x0E) == 8){ // Secuencia 3 Dir. Derecha
PORTB = Sec3_Der[i];
delay_ms(t);
i++;
if(i == 8) i = 0;
}
}
if(Dir == 0){
if((PORTC&0x0E) == 2){ // Secuencia 1 Dir. Izquierda
PORTB = Sec1_Izq[i];
delay_ms(t);
i++;
-
8/22/2019 Ccs Manual Basic
65/65
if(i == 4) i = 0;
}
if((PORTC&0x0E) == 4){ // Secuencia 2 Dir. Izquierda
PORTB = Sec2_Izq[i];
delay_ms(t);
i++;
if(i == 4) i = 0;
}
if((PORTC&0x0E) == 8){ // Secuencia 3 Dir. Izquierda
PORTB = Sec3_Izq[i];
delay_ms(t);
i++;
if(i == 8) i = 0;
}
}
}
}