Académique Documents
Professionnel Documents
Culture Documents
2010
Tabla de contenido
Introduccin ........................................................................................................................................... 3
1.
1.2
1.2.1
1.2.2
Formato Radix................................................................................................................ 9
1.2.3
Expresiones.................................................................................................................... 9
1.2.4
Instrucciones ................................................................................................................ 10
1.3
Programas Sencillos............................................................................................................................... 14
1.4
Parpadeo.............................................................................................................................. 14
1.5
1.6
1.7
1.7.1
1.8
1.9
2.0
2.1
2.2
2.3
2.4
2.5
2.6
2.6.1
2.7
2.7.1
2.8
2010
Introduccin
Este curso ofrece a los alumnos o maestros que estn involucrndose en la
programacin de microcontroladores PIC, y algunas veces no se sabe que
compiladores en C se pueden usar ya que por internet se puede encontrar una gran
variedad de compiladores en C, y es muy importante elegir cul de estos es ms
flexible a la hora de programar. El compilador Hi tech es un buen compilador para no
empezar a programar ya que es un programa para los profesionales en la
programacin, ya que no ofrece libreras, ni drivers para nuestros proyectos, en este
compilador se necesita crear las libreras de casi todos los mdulos que contiene el
micro, mientras MikroC es un buen compilador para empezar, ya que se basa ms la
programacin a nivel educacional, ya que ofrece ms libreras de LCD, GLCD, MMC
CARD, PWM entre varios y la programacin se hace ms sencilla, pero la desventaja
es que es un compilador ya estructurado y no se puede hacer mucho en las libreras ya
que si se quiere modificar alguna de ellas es muy difcil. Ahora el compilador ms
famoso por internet ya que ofrece un sinfn de proyectos programados con el
compilador PIC C COMPILER por la compaa CCS, este programa es uno de los
mejores ya que ofrece libreras muy tiles y verstiles, gracias al internet se puede
encontrar varios ejemplos, es gran compilador recomendado por un servidor.
2010
2010
Hoja de proyectos
Para la creacin de nuestro primer programa se debe de crear un espacio de trabajo, abrimos
nuestro programa MPLAB, y despus dirigimos nuestro ratn donde dice <proyect> y despus
< proyect Wizard>
Aparcera una ventana, en esta venta solo es un saludo, presionamos <next>, despus
elegimos que microcontroladores usaremos en este caso usaremos el microcontrolador
PIC16F886 y presionamos <next>.
2010
Ahora nos pedir el compilador que usaremos para programar el micro, en este caso usaremos
el compilador Hi tech y presionamos <next>.
2010
2010
Tipos de Variables
El compilador HI-TECH Compiler soporta tipos de informacin bsica con 1, 2,3 y 4 tamao de
byte. Todos los tipos de milti-byte siguen por lo menos el formato del primer byte ms
significante. El tamao de valores WORD tienen el byte ms significante en la direccin ms
baja y DOUBLE WORD tiene el byte y WORD en el primer formato ms significante en la
direccin ms baja.
En la tabla siguiente se explica:
2010
Formato Radix
Cualquier constate integral tendr un tipo con la cual es el tipo ms pequeo que puede
mantener el valor sin desbordar. El sufijo l o L puede ser usado con la contante para indicar que
debe ser asignado tambin un tipo SIGNED LONG o UNSIGNED LONG tiene un sufijo u o U
podra usarse con la contante para indicar que debe ser asignado un tipo sin signo. Y ambos I o
L y u o U poden ser usados para indicar un tipo UNSIGNED LONG INT.
Para los valores de tipo carcter se pueden encerrar con apostrofes por ejemplo:
A
Una variable de tipo carcter de varios elementos no pueden usar este tipo de apostrofes ya
que son caracteres de tipo string, que es una cadena de caracteres, para usar este tipo de
variable string se debe de hacer como el ejemplo:
char cadena[ ]=HOLA MUNDO;
1.2.3
Expresiones
Las operaciones y directivas son comprimidas de expresiones. Expresiones pueden ser hechas
de nmero, identificadores, cadenas de caracteres y operadores. Los operadores pueden ser
unitarios (un operador ej. not) o binario (2 operadores ej. +). Los operadores permitidos estn
en la tabla siguiente.
1.2.4
2010
Instrucciones
while(1){ //accion}
Esta es una instruccin de Mientras sea verdad se puede hacer ciclos perpetuos o con un fin
por ejemplo:
While(var<10){
Var++;
}
do{ //accin }while(1);
Esta es una instruccin parecida a la de arriba la diferencia es que al menos una vez entrara al
ciclo y al ltimo se har la comparacin por ejemplo
10
2010
do{
Var++;
}while(var<3);
If(//comparacin) {//accin}
[else if()]{//accion}
[else {//accion}]
Esta sentencia compara si es cierta entra al ciclo, ejemplo:
Var=2;
If(var==1){
//accin
}else if(var==2){
//Aqu entra ya que es verdad la comparacin
}else{
//accin
}
De otra forma se puede desarrollar estas comparaciones, es muy comn usar la instruccin
Switch (variable){
11
2010
Case 0: //accin
Break;
Case 1; //accin
Break;
Case
Default: //accin
Break;
}
Como vemos si la variable tiene un valor fuera de rango de los case entonces lo que se
ejecutara ser lo que contenga en default, pero si es lo contrario si la variable contiene un
valor de 0 entonces entrara hacer la accin en el case 0.
Para desarrollar un ciclo contable y fcil de hacer se usa:
For(variable=0;variable<100;variable++){
//accin
}
Se usa un ciclo for, como vemos en el ejemplo la variable en inicializada cuando entra por
primera vez al ciclo, despus comparara en este caso la variable es menor de 100, si es as
entonces realiza la accin y despus suma uno a la variable.
12
2010
Despus se debe de configurar las __CONFIG, que son la configuracin del procesador. Se
debe de tomar en cuenta que siempre se debe de configurar lo ms importante.
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Estas tres lneas anteriores es lo bsico para tener configurado correctamente nuestro
programa y microcontrolador.
13
2010
Programas Sencillos
1.4 Parpadeo
Material a usar:
1 MCU PIC16F886
1 LED
1 Resistencia de 10Kohm
1 Resistencia de 330ohm
14
2010
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ
void main(void){
//Puerto B como salida
TRISB=0x00;
//Comparadores desactivados
//
CMCON=0x07;
GIE=0;
PEIE=0;
while(1){
__delay_ms(10);
RB0=0;
__delay_ms(10);
RB0=1;
}
}
15
16
2010
A
B
A,B,C,D,E,F
Para poner a uno cada uno de ellos se tiene que usar la siguiente forma, ponemos las letras
que empiecen al revs F,E,D,C,B,A y cada uno ser un UNO pero solo tenemos 6 valores y
necesitamos 2 ms para que sea un byte completo, entonces los que falten simplemente
estarn en cero. Hay que tomar en cuenta si nuestro display es catodo o anodo ya que puede
afectar que valores deben de ser cero o unos.
00111111 = 0 en el display catodo pero como usamos un anodo comn cambian lo valores
11000000
Y Asi para todos los nmeros, hasta el 9.
2010
Despus simplemente todos esos valores lo ponemos a una arreglo de un solo byte
0b10010010,0b10000011,0b11111000,0b00000000,0b00011000};
Ahora simplemente agregamos una variable mas para el uso del For.
for(x=0;x<10;x++){
//Ciclo for
PORTC=mostrar[x];
DELAY1S();
}
ESTE SERIA UN ALGORITMO MUY SIMPLE.
La funcin DELAY1S es un retardo de un segundo esta funcin se tuvo que hacer, ya que el
compilador no ofrece tanto retardo para una frecuencia de 4Mhz.
Entonces se desarrolla funciones que requieran mas temporizacin.
//Funcion de retardo de 1 seg
//1/10mS = 100 repeticiones para obtener un 1seg
void DELAY1S(void){
//Varibale local entonces solo se usa en esta funcion
unsigned char time;
for(time=0;time<100;time++){
__delay_ms(10);
}
}
18
2010
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ
//Arreglo de 1 byte que contiene la numeracion
//para que se muestre en un Display de 7 SEG
unsigned char mostrar[]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,
0b10010010,0b10000011,0b11111000,0b00000000,0b00011000};
//Variable para el ciclo FOR
unsigned char x;
//Funcion de retardo de 1 seg
//1/10mS = 100 repeticiones para obtener un 1seg
void DELAY1S(void){
//Varibale local entonces solo se usa en esta funcion
unsigned char time;
for(time=0;time<100;time++){
__delay_ms(10);
}
}
void main(void){
//Puerto B como salida
TRISC=0x00;
GIE=0;
PEIE=0;
while(1){
for(x=0;x<10;x++){
PORTC=mostrar[x];
DELAY1S();
//Ciclo for
//Saca el valor que correponde al puerto C
//LLama a la funcion de retardo de 1seg
19
20
2010
2010
21
2010
Si se cuenta con una laptop, recuerde adquirir un cable de USB<->SERIAL para poder hacer la
simulacin.
Un diagrama sencillo para entender la conexin de PC a PIC seria;
PC
MAX232
PIC
1
16
22
2010
4
1
9600 16
Value=25
Este valor se debe de cargar a la funcin openUSART (25,OFF,OFF);
Programa que contiene nuestro micro;
#include<htc.h>
//Incluimos libreria del micro a usar
#include<stdio.h>
//libreria para trabajar con conversiones
#include"libUSART/usartdr.h" //Libreria creada para uso del usart
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
//DEBUGDIS
= Desactiva Debug
//BOR
= Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 8MHZ
Unsigned char letra[]={HOLA MUNDO};
/////////////////////////////////////////////////
23
2010
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
TRISA=0x07;
TRISC=0x80;
//RC7=RX,RC6=TX
//Configuracion del USART
OpenUSART(25,OFF,OFF);
//value=(FOSC/(baud*16))-1
//SIN INTERRUPCIONES
//a 9600 baudios
GIE=0;
PEIE=0;
For(x=0;x<10;x++){
Putch(letra[x];
}
while(1);
}
Recuerde usar el CI max232 para la conexin PC<-<MAX>->PIC
24
2010
Ahora bien si deseamos no usar el ciclo for ni una variable que contenga el texto, podemos
usar la instruccin prinft(string) simplemente incluimos en nuestro proyecto el siguiente
archivo, <stdio.h>.
Entonces modificamos nuestro programita.
#include<htc.h>
//Incluimos libreria del micro a usar
#include<stdio.h>
//libreria para trabajar con conversiones
#include"libUSART/usartdr.h" //Libreria creada para uso del usart
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
//DEBUGDIS
= Desactiva Debug
//BOR
= Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 8MHZ
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
TRISA=0x07;
TRISC=0x80;
//RC7=RX,RC6=TX
//Configuracion del USART
OpenUSART(25,OFF,OFF);
//value=(FOSC/(baud*16))-1
//SIN INTERRUPCIONES
//a 9600 baudios
25
2010
printf("hola mundo");
while(1);
}
Este mtodo es muy simple, pero conlleva a usar mas memoria de la forma anterior, se
recomienda hacer una funcin simple, para realizar la misma funcin pero el uso de
memoria que sea menor.
26
2010
27
2010
interno tenemos que hay que contar los pulsos de oscilador/4. Se puede configurar este timer0
para que ocurra una interrupcin. En este caso que sea interno, por ejemplo.
Queremos que haga una interrupcin cada 3mS.
Entonces usaremos una frmula para configurar y saber qu valor del timer0 debemos de
cargar cada vez que ocurra una interrupcin.
4
=
(256 $0)
Prescalar es un valor que puede ser cargado de 2, 4, 8, 16, 32, 64, 128, 256 el TMR0 es el
valor que debemos de encontrar entonces simplemente despejamos.
$0 = 256 {
'
}
4
(
)
Se nota que la interrupcin es cada 3mS entonces sumando el voltaje positivo y cero es igual a
6mS, entonces estamos generando una frecuencia de 162Hz aprox.
28
2010
El programa que ahora haremos es el siguiente para comprobar cmo funciona la interrupcin
por timer0.
#include<htc.h>
//Incluimos libreria del micro a usar
#include"libTIMER0/OpenTimer0.h"//Incluimos libreria de timer0
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ
void main(void){
TRISB=0x00;
ANSELH=0x00;//Desactivamos PORTB como entrada analoga
OpenTIMER0(prescalar_256,ON);
//Interrupcion timpo=(1/(FOSC/4))*preescalar*(256-timer0)
//
500uS=tiempo maximo
//
timer0=+256-{tiempo/[(1/(FOSC/4))*preescalar]}
TMR0=244;
GIE=1;
PEIE=1;
29
2010
while(1);
}
////////////////////////////////////
///Interrupcion Por timer0
////////////////////////////////////
static void interrupt
isr(void){
if(T0IF){
RB0=~RB0;//Cmabia de estado cada vez ejecuta esta accion //amado TOGGLE
T0IF=0; //Camabia flag de interrupcion
}
TMR0=244;//Carga otra vez el timer 0
}
1.7.1
Este ejemplo es muy sencillo, utilizaremos la interrupcin por TIMER0, para que se desborde
cada ~65mS que es el tiempo mximo que puede desbordar el TIMER0, despus al tener 15
interrupciones cumplidas pasara aproximadamente 1 segundo, despus sumara +1 a la
variable que se mostrara por el USART.
Programa principal del PIC16f628A:
#include<htc.h>
//Incluimos libreria del micro a usar
#include<stdio.h>
//libreria para trabajar con conversiones
#include"timer0/OpenTimer0.h"//Incluimos libreria de timer0
#include"lib/usartdr.h" //Incluimos libreria del serial
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ
////////////////////////////////////////////
//Variables a usar
30
}
}
}
////////////////////////////////////
///Interrupcion Por timer0
////////////////////////////////////
static void interrupt
isr(void){
if(T0IF){
//Ha surguido una interrupcion?
cont++;
//Cuenta mas +1
if(cont==15){ //Ha llegado a 1 seg?
seg=1; //Pone flag de segundo
cont=0; //Vuelve a contar
}
T0IF=0;
//Rest falg de interrupcion por timer0
TMR0=2;
//Carga timer0 para dar 65mS*15=1seg
}
}
31
2010
2010
Nota: Use siempre el circuito MAX232 para adaptar los niveles rs232 a TTL cada vez que use
una comunicacin serial.
32
2010
33
2010
4
(
)
= /
01
1
01
4
11 (
) 16
4
34
2010
#include<htc.h>
//Incluimos libreria del micro a usar
#include<stdio.h>
//libreria para trabajar con conversiones
#include"timer2/timer2.h"//LLama la libreria de usar Timer2
#include"pwmdr/pwm.h"//LLama libreria para usar PWM
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
TRISB=0;
//Configuramos TIMER 2 para PWM
OpenTimer2(PRESCALE_16);
//Usamos libreria PWM
OpenPwm(61);
//PWM period = [(period ) + 1] x 4 x Tosc x TMR2 prescaler
//PWM period = [(255)+1]x(4/4Mhz)x16
// [.001s/((4/4Mhz)*16)]-1=period
// [1/(f*(4/Tosc)*preescalar)]-1=period
PwmDuty(127); //255=100% 127=50% de duty
GIE=0;
PEIE=0;
while(1);
}
35
2010
La simulacin tenemos:
= 125.256 125
36
2010
Como vemos se ha redondeado ya que lo que entrega el ADC es un valor entero de tipo
unsigned char , pero ahora usaremos uno de 10 bit;
=
5 125 5
=
255
255
'
= 2.450
10 ': '
=
5 503 5
=
1024
1024
'
= 2.456
Como vemos al usar un convertidor de 8 bit sea a perdido 6 mVolts, mientras el convertidor de
10 bit no se perdi nada ya que el valor se encuentra en rango.
Las operaciones anteriores lo hace automticamente el convertidor y nosotros simplemente
pedimos el valor obtenido.
La funcin que vamos a usar para la configuracin del ADC es la siguiente:
void OpenADC(const unsigned char FOSC,const unsigned char an0,const unsigned char an1);
Donde:
FOSC = tiempo de conversion, se puede tomar un valor de los siguientes:
FOSC_2
FOSC_8
37
2010
0X01
0X03
0X07
0X0F
0X1F
0X7F
0XFF
0X01
0X02
0X07
0X0F
0X1F
0X3F
El canal ADC contiene un multiplexor que hace la funcin de establecer el canal por el
cual pedimos el ADC. En la figura siguiente se muestra como est constituido el
convertidor anlogo-digital:
38
2010
39
40
2010
2010
41
42
2010
2010
Establece Display/Cursor:
DPrende lcd(1)/apaga LCD(0)
CCursor activado (1)/Desactivado (0)
BParpadeo del Cursor activado (1)/Desactivado (0)
Mover Cursor/Recorrer cursor:
SCCorrimiento del display activado (1)/Desactivado (0)
RLCorrimiento hacia derecha (1)/Izquierda (0)
43
2010
44
2010
//
guardadas en la RAM
//
guardadas en la ROM
Para dar un pequeo ejemplo del uso del Modulo LCD, se desarrolla lo siguiente, Al
iniciar la simulacin, se escribir en el LCD la letra A demostrando la funcin
writeCLCD(); despus borrara la pantalla con la instruccin que no es publica pero es
usada para poder limpiar la pantalla LCD, send_byte(CLEAR); enva un comando de
limpiar pantalla, y despus escribimos un string guardado en la ROM y comprobamos
la funcin, writeRSLCD(); despus con un ciclo for hara contar 0 a 100 y ser mostrado
en el lcd los valores de 0 a 100, poniendo en prueba una nueva funcin:
sprintf(arreglo,"datos en string %si hay valores a transformar ",valor a transformer a
string);
Esta instruccin para usarla se debe de agregar la librera stdio.h al principio del
programa.
Despus ser proyectado al LCD con el uso de la instruccin writeSLCD();.
45
46
2010
Simulacin correspondiente:
47
2010
2010
Ahora empecemos hacer una prctica sencilla para poner a prueba el funcionamiento
del LCD y el convertidor anlogo-digital, se trata de leer un dato anlogo y despus
transformar ese dato a un valor de voltaje, como el rango mximo es de 0 a 5 v,
entonces es una tarea muy sencilla, solo usaremos un canal anlogo, en mi caso el
AN0.
Use un potencimetro de cualquier valor, preferentemente de 1kohm a 500 kohm,
conecte la terminal del potencimetro hacia la entrada anloga del microcontrolador
(AN0), despus conecte el LCD, en el puerto C.
Para cambiar el puerto de trabajo del LCD, se puede modificar la librera lcddr.h Solo
cambie los parmetros indicados en el archivo .H y listo.
#define PUERTOX TRISC
#define PUERTOY PORTC
#define
RB4
#define
RS
RB5
#define
RW
RB6
Presentamos el Programa:
#include<htc.h>
//Incluimos libreria del micro a usar
#include<stdio.h>
//libreria para trabajar con conversiones
#include<math.h>
//para uso del float
#include"liblcd/lcddr.h" //Libreria creada para uso del lcd
#include"libADC/adcdr.h"//Inluimos libreria de trabajo con ADC
48
49
2010
writeRSLCD("Lectura de ADC");
while(1){
__delay_ms(100);
channelADC(0);
//Canal 0
startADC();
//Empieza Conversion
while(GODONE!=0);
//Ha terminado
adc=readADC();
//lee dato de 10 bit
adc=(adc*5)/1024;
//
sprintf(word,"AN0=%.2f volts",adc);//Cambia todo a un string completo
gotoXYLCD(1,2);
//Segunda Linea
writeSLCD(word);
//Escribe la conversion del LCD
}
}
Simulacin Correspondiente:
50
2010
2010
Despus de ver el uso de los canales anlogos, y el modulo LCD, ahora debemos de
conocer el uso del teclado 4x4, el funcionamiento es sencillo.
Un teclado que funciona a base de matriz, conexiones de fila y columna, es una
manera eficiente para utilizar menos pines y hacer la programacin de este ms
sencilla, para los que apenas inician en la programacin a lo mejor es muy complejo
realizar este tipo de libreras, por eso se ha realizado una librera para trabajar al
menos usar teclados 4x4.
Para que usted tengo nocin de cmo funcionan, se da un pequeos pasos de cmo se
debe de realizar una librera de cualquier tamao de teclado.
Realizar librera de 4X4 por pasos:
1.- Selecciona el puerto a usar (si el puerto contiene resistencias pull-ups mucho mejor)
2.- Hacer en nibble mas alto como entrada, y el nibble de menos peso como salida
51
2010
52
2010
53
while(1){
//Parte del Programa que menciona que canal queremos ver;
send_byte(CLEAR);
gotoXYLCD(1,1);
writeRSLCD("CANAL ANALOGO");
gotoXYLCD(1,2);
writeRSLCD("A0, A1, A2, A3");
value=0;
while(value==0)value=getkey(0);
//Funcion que te deja ver el canal analogo que hallamos elegido
switch(value){
case '0':
send_byte(CLEAR);
54
2010
55
2010
2010
56
2010
57
2010
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
//DEBUGDIS
= Desactiva Debug
//BOR
= Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ
///////////////////////////////////////////////////
//Librerias de trabajo
////////////////////////////////////////////////////
#include"libUSART/usartdr.h" //Libreria creada para uso del usart
#include"timer2/timer2.h"//Incluimos timer2
#include"pwmdr/pwm.h"
//Incluimos libreria para trabajar con PWM
////////////////////////////////////////////////
///Variables globales
////////
////////////////////////////////////////////////
unsigned int DUTY;
unsigned char uPWM[2];
bit flag=0;
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
58
59
2010
2010
flag=0;
}
}
}
Antes de Inicialar debemos de tener abierto el Software Virtual Serial port, Creamos 2
puertos Virtuales en el botn ADD PAIR al tener dos parece cada uno ser conectado
a un programa, por ejemplo para el COM1 ser conectado a proteus por medio del
compim, mientras que el COM2 ser conectado a nuestro software convertidor Digital a
Anlogo.
60
2010
Esta prctica es muy sencilla, es hacer un enlace con un programa creado en Visual
C# para luego ser conectado va serial a nuestro microcontrolador, que este toma un
valor anlogo en el canal 0 (AN0) y
despus es procesado para enviarlo
por el serial.
Use el MAX232 para hacer la
conexin entre PIC y PC, coloque un
potencimetro de cualquier valor que
usted desee a la entrada RA0 que es
la entrada anlogo que vamos a usar, abra el software para conectarlo en el COM
disponible en nuestra computadora, o si usted desea crear un enlace virtual entren
proteus y nuestro programa, utilizando el software Virtual Serial Port.
Abrimos el programa ADC.exe y dirigimos nuestro mouse al botn serial y elegimos el
COM2 a 2400 baud y decimos ok y conectamos.
61
2010
Ahora habr haga o abra la simulacin en proteus, use el COMPIM para simular
puertos, y seleccione COM1 a 2400 baud, y presione play.
Se observa que cambia el voltaje cada vez que movemos el potencimetro.
62
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
//DEBUGDIS
= Desactiva Debug
//BOR
= Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ
///////////////////////////////////////////////////
//Librerias de trabajo
////////////////////////////////////////////////////
#include"libUSART/usartdr.h" //Libreria creada para uso del usart
#include"libADC/adcdr.h"
//Libreria creada para uso del ADC
////////////////////////////////////////////////
///Variables globales
////////
////////////////////////////////////////////////
unsigned int ADC;
unsigned char send[2];
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
TRISA=0x01;
//RA0=entrada
TRISC=0x80;
//RC8=RX,RC7=TX
//Configuracion del USART
OpenUSART(207,OFF,OFF);
//value=(FOSC/(baud*16))-1
//No interrupciones
//a 2400 baudios
63
2010
2010
//Configuramos ADC
OpenADC(FOSC_FRC,AN0,OFF);//Canal AN0 como analogo
GIE=0;
//INTERRUPCIONES GLOBALES DesACTIVADAS
PEIE=0;
//DesACTIVA INTERURPCIONES POR PERIFERICOS
while(1){
__delay_ms(1);
//Tiempo antes de pedir otro dato
startADC();
//Empieza conversion
while(GODONE!=0);
//ha terminad?
ADC=readADC();
//SI, lee dato
send[0]=ADC&0xFF;
//toma el low byte
send[1]=(ADC>>8)&0x03;//Toma el high byte
putch(send[0]);
//envia low byte primero
putch(send[1]);
//envia high byte segundo
}
}
64
2010
Ahora haremos una prctica muy interesantes vamos a usar dos interrupciones por
timer0,1, cada uno manejara un tiempo establecido, para que estn en sincrona.
El timer 0 manejara el corrimiento entre los Display a esto se le llama multiplexado, ya
que solo un display ser activado por un cierto tiempo y despus apagara para prender
el siguiente Display. Ejemplo:
Para mostrar el numero en el primer display se debe de activar el pin 1 y los demas
se deben de dejar a cero, para que
solo muestre un solo numero en el
display correspondiente, como se
muestra en la imagen, debemos de
tener un controlador que pueda
cambiar el numero al correr los
pines del selector, para que estn
en sincrona.
Es muy importante realizar esta acciones a una gran velocidad, normalmente para 6
displays que sern multiplexados, se debe de tener mas de 60Hz en cada uno de los
displays ya para evitar flashazos.
El corrimiento se har con el timer0 que estar configurado a que haga un
desbordamiento cada 1mS, teniendo que cambiar al siguiente display, la frmula para
65
2010
calcular el valor para se pueda cargarse al TMR0 se debe de calcular con la frmula
del timer0.
$0 = 256 {
'
}
4
(
)
Este valor se debe de cargar cada vez que surja la interrupcin del timer0, si nuestro
reloj tiene 6 displays y cada uno se va a cambiar cada 1mS entonces tenemos que la
frecuencia de cada uno ser de:
=
117
1667
6
66
'
4
(
)
2010
Este valor es para tener una interrupcin cada 200mS para tener un segundo se debe
de dividir este valor por el reciproco y tenemos que:
8=
1
=5
2009
Deben surgir 5 interrupciones para tener 1 Segundo, entonces aumentara una variable
que guardara. Cada segundo que pase y as al llegar a 60 segundos y aumenta otra
variable que guardara los minutos y cuando los minutos alcancen 60 minutos este
aumenta la variable horas, y as.
Ahora para mostrar los nmeros en los display se debe de contar en cuenta los valores
de corrimiento como se hablo anteriormente, estos valores de corrimiento ser hecho
en el puerto B, como son 6 display entonces se usaran 6 pines del puerto B para
multiplexarlos, al Iniciar el corrimiento este tiene un valor de 1, al correrlo, tomara un
valor de 2, y de nuevamente al correrlo este tomara un valor de 4, por deduccin se
incrementa en mltiplos de 2, entonces solo basta de usar instrucciones de if cada vez
que llegue al valor deseado por ejemplo:
67
2010
If((PORTB&0x3F)==1) {
Mostrar el valor que corresponde al Display 1
}
Ahora bien como deseamos cambiar manualmente los valores de HORAS y MINUTOS,
se usaran simplemente 3 push botons para hacer estos cambios, uno ser el que
establece la hora y minutos, si este botn no est presionado no afecta presionar los
botones de hora y minutos, pero s lo contrario est presionado se podr cambiar
satisfactoriamente los valores hora y minutos.
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
68
2010
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
//DEBUGDIS
= Desactiva Debug
//BOR
= Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ
/////////////////////////////////////////////////
//Librerias
/////////////////////////////////////////////////
#include"timer0/OpenTimer0.h"//Incluimos libreria de timer0
#include"libADC/adcdr.h"
//Libreria creada para uso del ADC
#include"timer1/timer1dr.h"
//Libreria para uso del timer1
/////////////////////////////////////////////////
//Definiciones de trabajo
/////////////////////////////////////////////////
#define SET_TIEMPO
#define HORA
#define MIN
!(PORTA&0x01)
!(PORTA&0x02)
!(PORTA&0X04)
////////////////////////////////////////////////
//Variables Globales
////////////////////////////////////////////////
const unsigned char mostrar[]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,
0b10010010,0b10000011,0b11111000,0b00000000,0b00011000};
unsigned char H2,H1,M2,M1,S2,S1;
unsigned char overflow1;
unsigned char TIEMPO=1,FECHA=0;
////////////////////////////////////
///Interrupcion Por timer0 y timer1
////////////////////////////////////
static void interrupt
isr(void){
////////////////////////////////////////////
//CADA 1mS se efectuara esta accion
//Esta Funcion se encarga de correr los display
//Para cuando es necesario mostrar el numero
//En el Display siguiente
////////////////////////////////////////////
if(T0IF && !TMR1IF){
if((PORTB&0x3F)<32){
PORTB=(PORTB<<1)|0x40;
}else{
PORTB=0x41;
}
T0IF=0;
69
70
2010
2010
///////////////////////////////////////////////////
TRISB=0X00;
PORTB=0X41;
///////////////////////////////////////////////////
//Puerto C como salida
///
//Puerto C sera usado para sacar el numero ///
///////////////////////////////////////////////////
TRISC=0;
PORTC=0;
///////////////////////////////////////////////////
//PORTA <PIN A1 a A7> como salida
///
//PORTA <PIN A0> como entrada analoga
///
///////////////////////////////////////////////////
TRISA=0X07;
PORTA=0x00;
CM1CON0=0x00;//Desactiva comparadores
CM2CON0=0x00;
//Configuramos ADC
OpenADC(FOSC_FRC,OFF,OFF);//No usaremos Canal Analgos
//Configuramos TIMER0
//Para obtener 1 mS
OpenTIMER0(prescalar_16,ON);
//Interrupcion timpo=(1/(FOSC/4))*preescalar*(256-timer1)
//
1mS=tiempo maximo
//
timer0=+256-{tiempo/[(1/(FOSC/4))*preescalar]}
TMR0=131;
OpenTIMER1(pr_8,ON);
//Interrupcion timpo=(1/(FOSC/4))*preescalar*(256-timer1)
//
200mS=tiempo maximo
//
timer1=+65536-{tiempo/[(1/(FOSC/4))*preescalar]}
TMR1LOAD(15550);
GIE=1;
//INTERRUPCIONES GLOBALES ACTIVADAS
PEIE=1;
//ACTIVA INTERURPCIONES POR PERIFERICOS
/////////////////////////////////////////////////////
//Inicia el Ciclo Perpetuo
/////////////////////////////////////////////////////
while(1){
if(TIEMPO && !FECHA){
/////////////////////////////////////////////////////
//Cuando sea 1 en el puerto B este muestra el valor
//Que contiene la variable
//Asi es para todas las comparaciones
/////////////////////////////////////////////////////
if((PORTB&0x3F)==1){
PORTC=mostrar[S1];
71
72
2010
Curso de Hi-tech
Hi tech Compiler (lite Mode)
2010
}
}
Recuerde usar en cada Display una conexin de transistor como se muestra abajo:
73
2010
74
2010
Entender este tema es muy complicado ya que requiere muchas operacin si se desea
realizar un control de varios servos, por esta razn se simplificara a un solo servo a
controlar, haciendo ms sencilla la explicacin y las operaciones.
Primero que nada hay que saber que es un servo, servo es un pequeo pero potente
dispositivo que dispone en su interior de un pequeo motor con un
reductor de velocidad y multiplicador de fuerza, tambin dispone de
un pequeo circuito que gobierna el sistema. El recorrido del eje de
salida es de 180 en la mayora de ellos, pero puede ser fcilmente
modificado para tener un recorrido libre de 360 y actuar as como un
motor.
75
2010
Nosotros nos basaremos en las caractersticas que contiene la marca de servos hi tech
como se aprecia en la tabla anterior las caractersticas de ancho de pulso es de 0.9 ms
como mnimo y 2.1 ms como mximo entonces tenemos un rango de operacin del
servo es de:
8: = 2.19 0.99 = 1.29
Lgica de SERVO
Para operar un servo via rs232, con un microcontrolador en general, se debe de tomar
2 interrupciones, una por timer y otra por USART, en este caso el tiempo es muy
importante entonces es mas primordial que se atienda la interrupcin por timer que por
76
Curso de Hi-tech
Hi tech Compiler (lite Mode)
2010
recepcin del USART. Ya que necesitamos una estabilidad en la frecuencia que debe
de tener el servo.
Para tener la frecuencia estable aunque se
modifique el ancho de pulso, y que este en
rango de operacin del servomotor, se debe
de llevar a cabo las siguientes formulas.
Como sabemos que 50Hz equivale a tiempo
a 20 ms, y que solo va a variar una pequea
porcin en tiempo alto y el resto quedara en bajo
bajo,, las operaciones se harn para el
tiempo alto.
El uso del timer1 es muy importante su configuracin, en este caso se debe de
configurar de la siguiente manera:
1.-Prescalar
Prescalar de 2 para tener un tick cada 0.4uS
2.- Activar la interrupcin por TIMER1
Si tenemos un pulso mximo de 2.1ms este valor lo divi
dividimos
dimos por 0.4us:
'1; =
2.1
5250
0.4
Este valor son los tick necesarios para llevar a cabo un pulso positivo de 2.1ms, ahora
bien para sacar los tick mnimos para llevar el pulso a 0.9ms se divide entre 0.4us
como la vez anterior.
77
2010
0.9
= 2250
0.4
Para saber el rango con los que vamos a controlar solamente restamos:
8: = '1; '18
= 5250 2250 = 3000
Si observa que el rango es el mismo de 1.2ms (valor obtenido al restar 2.1ms-0.9ms)
3000 0.4
= 1.2
Ahora debemos de sacar el valor que es necesario para cada grado, es simplemente
dividir:
;:
=
8: 3000
=
= 16.6666 17
180
180
Entonces se nota que para que gire un grado se debe de tener 17.
Por ejemplo:
Si deseamos que nuestro motor gire a 50 grados entonces:
50 17 = 850
Pero como sabemos que los tick mnimos son 2250 entonces se lo sumamos:
2250 + 850 = 3100
Para cargrselo al timer1 se debe de restar 65536 que es el valor de 16 bit
65536 3100 = 62436
78
2010
20
= 50000
0.4
Al tener este valor se debe de restar 3100 (valor obtenido anteriormente para sacar
tiempo alto)
50000 3100 = 46900
Y por ultimo este valor se resta a 65536 para despus cargrselo al timer1:
65536 46900 = 18636
Recuerde que antes de cargarlo se debe de poner el pin en bajo y despus cargar el
valor obtenido al timer1.
En resumen, primero saque el valor para el tiempo alto y bajo, cuando surja la
interrupcin ponga el pin en alto y cargue con el tiempo alto, despus que surja otra
vez la interrupcin ponga el pin a bajo y cargue el tiempo bajo.
79
2010
El programa es el siguiente;
#include<htc.h>
//Incluimos libreria del micro a usar
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & HS & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 20000000 //Oscilador Externo de 20MHZ
/////////////////////////////////////////////////////////////
//Librerias a usar
/////////////////////////////////////////////////////////////
80
81
2010
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
CMCON=0x07;
//APAGA COMPRADORES INTERNOS
TRISA=0x00;
TRISB=0x02;
//RB1=RX,RB2=TX
//Configuracion del USART
OpenUSART(20,OFF,ON);
//value=(FOSC/(baud*16))-1
//interrupcion de recepcion activado
//a 57600 baudios
//Configuramos Timer1
OpenTIMER1(pr_2,ON); //Prescalar de 2
//Activamos la interrupcion por timer
TMR1LOAD(tick);
GIE=1;
//INTERRUPCIONES GLOBALES DesACTIVADAS
PEIE=1;
//DesACTIVA INTERURPCIONES POR PERIFERICOS
while(1){
if(flag==1){
RCIE=0; //Desactiva interrupcion por recepcion del USART
AUX=(POSICION*17)+2200; //AQUI OBTIENES LOS TICK'S~2250
AUXH=65536-AUX;
//AQUI OBTIENES EL TIEMPO EN ALTO
SERVOH=AUXH;
//ACTUALIZA EL SERVO SELECCIONADO
AUX=50000-AUX;
//20ms - (TIEMPO TRANSCURRIDO EN ALTO)
AUXL=65536-AUX;
//AQUI OBTIENES EL TIEMPO BAJO
SERVOL=AUXL;
//ACTUALIZAS SERVO SELECCIONADO
flag=0;
RCIE=1;
}
}
}
82
2010
2010
El software que vamos a usar en esta ocasin es Microsoft Visual C# 2010 Express,
este nos servir para realizar nuestras aplicaciones para entornos de Windows, es muy
fcil realizar prcticas sencillas de comunicacin serial.
No me involucrare en sintaxis y como se debe de programar
correctamente en este entorno lo que vamos a desarrollar
es cosas sencillas para que usted tenga una nocin de cmo funcionan las cosas.
Lo bueno de este software es que es free, entonces no gastaremos ningn centavo en
tenerlo, solo accedemos a la pgina de www.microsoft.com y buscamos visual c#
express y lo bajamos, ten en cuenta que se debe de registrar para poder bajar el
software.
Al bajarlo debemos de abrirlo y, crear un nuevo proyecto y
nos abrir una venta para seleccionar que tipo de proyecto
deseamos desarrollar, entonces debemos de usar
83
2010
Window form
application
Si deseamos cambiar
el nombre a control de
servo lo podemos
hacer en la parte
inferior. Y despus
damos OK para realizar el proyecto y al instante aparece nuestra ventana de trabajo,
que conforma, en la parte izquierda el toolbox <caja de herramientas> es donde se
localiza todos los componentes para realizar acciones especificas, mientras en el
centro el form, en la parte inferior derecha se encuentra las propiedades de los
elementos, si deseamos cambiar algunas propiedad de elementos, simplemente damos
click en el elemento y rpidamente aparecer las propiedades.
Lo que vamos a hacer primero es colocar el componente de serialport que se
encargara de crear el COM (puerto), que se encuentra en el toolbox, en componentes.
84
2010
85
2010
{
serialPort1.Close();
}
Y listo ya hemos configurado el abrir y cerrar del puerto, ahora falta enviar datos, solo
damos dos click en el trackbar y agregamos la siguiente cdigo.
private void trackBar1_Scroll(object sender, EventArgs e)
{
byte[] dato = {Convert.ToByte(trackBar1.Value) };
if (serialPort1.IsOpen)
{
serialPort1.Write(dato, 0, 1);
}
}
Damos F5 para correr programa y veremos con la ayuda de Virtual serial port la
conexin.
86
2010
87
2010
88
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ
/////////////////////////////////////////////////
//Librerias de perifericos
/////////////////////////////////////////////////
#include"timer2/timer2.h"//LLama la libreria de usar Timer2
#include"pwmdr/pwm.h"//LLama libreria para usar PWM
#include"libUSART/usartdr.h" //Libreria creada para uso del usart
////////////////////////////////////////////////
///Variables globales
////////
////////////////////////////////////////////////
unsigned int DUTY;
unsigned char uPWM[2];
bit flag=0;
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){
//Ha resivido un dato?
if(RCIF){
//Tomo 2 bytes del serial
uPWM[0]=getch();
uPWM[1]=getch();
//Ya termine de resivir
RCIF=0;
//Habilito cambio de PWM DUTY
flag=1;
}
89
2010
2010
}
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
TRISC=0x80;
//Configuracion del USART
OpenUSART(51,OFF,ON);
//value=(FOSC/(baud*16))-1
//interrupcion de recepcion activado
//a 9600 baudios
//Configuramos TIMER 2 para PWM
OpenTimer2(PRESCALE_16);
//Usamos libreria PWM
OpenPwm(124);
//PWM period = [(period ) + 1] x 4 x Tosc x TMR2 prescaler
//PWM period = [(255)+1]x(4/4Mhz)x16
// [.001s/((4/8Mhz)*16)]-1=period
// [1/(f*(4/Tosc)*preescalar)]-1=period
PwmDuty(0);
GIE=1;
PEIE=1;
while(1){
//Espera a habilitar
if(flag){
//////////////////////////////////////
//DUTY=0xPWM[1]PWM[0]=16bit
DUTY=(unsigned int)uPWM[1]<<8;
DUTY|=((unsigned int)uPWM[0]&0x00FF);
//////////////////////////////////////
//Cambiamos el duty del PWM
PwmDuty(DUTY);
//
flag=0;
}
}
}
90
2010
91
2010
Al tener la funcin de configuracin montamos el mouse en el, para despus hacer click
derecho en VISA resource name y seleccionamos <create><control> esto permite que
aparezca un control en el panel frontal donde nosotros podemos cambiar, o configurar
manualmente lo que nos pide, esta parte nos menciona que hemos creado un control
donde especifica que ah va estar COM disponible del serial, si usted tiene una
computadora casera nota que al presionar el control aparecer los COM disponibles en
su computadora de escritorio, mientras si tiene una laptop, puede usar un cable de
USB a Serial para hacer esta accin.
Regresamos a hace lo mismo con la opcin de configuracin de
los baudios, al tener estas dos opciones es necesario, ahora
poner una estructura <while> como usted sabe una funcin
while sirve para hacer un ciclo hasta que sea verdad, para
tener esta estructura nos dirigimos a
<programming><structures><while loop> Y simplemente lo
agregamos, hacemos esto para que solo entre una sola vez a la opcin de
configuracin cada vez que reiniciamos el programa, el <while loop> se encargara de
estar en un ciclo perpetuo hasta que
presionemos <stop>
Ahora agregaremos una funcin de
secuencia, esta funcin nos permitir
hacer que cada acciones se hagan paso
por paso (por secuencia una tras otra), la funcin llamada <flat sequence> esta en
92
2010
<structures>, al
agregarlo a la hoja
block diagram debe de
estar adentro del
<while loop> .
Al tener todo lo anterior
regresa a la hoja front panel y agregue un control de numrico el que usted desee, solo
que sea aquel que puede cambiar su valor cuando el usuario desee, y cambie el rango
que tenga el control que haya elegido de 0 a 100, que corresponde a porcentaje, es
mucho ms fcil trabajar de este modo, que poner el valor
actual enviado.
Despus agregue si usted lo desea un indicador de string,
para mostrar un texto donde especifique el porcentaje
actual. Ahora que ya tenemos los controles de muestra en el front panel, ahora falta
programar sus funciones, de envio.
Regresemos a la pagina <block diagram> y nos dirigimos a buscar la funcin <write>
que se encuentra en las funciones del <serial>, esta funcin <write> al encontrarla la
agregamos en la segunda secuencia ya que va hacer la ltima accin que es enviar el
dato. Al agregarlo conecte correctamente la salida de la funcin de configuracin a la
entrada de la funcin de <write> como se indica en la imagen.
Esto tiene que hacerse ya que permite la opcin de configuracin enviar el puerto
disponible y si hay algn error tambin enviarlo, y cuando llegue a la funcin de
93
2010
8'=9 8
512
;
100
94
2010
En la parte frontal se puede realizar algunos arreglos, para que pueda estar mejor
presentado:
95
2010
Ahora bien se ha realizado el programa pero ahora se desea realizar un ejecutable, que
se quiere decir con esto, que se puede ejecutarse sin abrir
labview.
Para hacer lo propuesto el se tiene que grabar en una
librera de tipo LLB, solo grabamos la practica en <save as>
y presionamos new LLB. Y despus nos pedir que
nombre queremos para la librera LLB, usted ponga el que
guste, despus abrir otra venta para grabar el archivo, tambin usted escriba el
nombre que desee.
Ahora nos dirigimos a LLB manager que est ubicado en tools lo abrimos y aparecer
una venta donde buscaremos la librera LLB que creamos.
Presionamos dos veces el archivo y nos llevara al proyecto, ahora nos dirigimos a
tools y presionamos la
opcin de buils aplication
(EXE), nos preguntar si
deseamos grabarlo ah,
solo decimos que si.
Y nos abrir la venta de
configuracin de nuestro
ejecutable
96
2010
97
2010
Este proyecto es una matriz de led 8x24, lo que vamos a desarrollar es un contador de
000 a 999, con el cual se usara una de tantas formas de programar una matriz, usando
diferentes circuitos adicionales, para facilitar el resultado.
Fila
Columna
98
Curso de Hi-tech
Hi tech Compiler (lite Mode)
Si en las filas enviamos un dato de la siguiente manera;
Para:
F1= 0
F2=0
F3=1
Y para las columnas
C=0
C2=1
C3=1
Esto quiere decir que solo va a prender los led que
interceptan de fila a columna, 1 a 0.
Ahora bien, haremos una tcnica de corrimiento de bit,
esto quiere decir por ejemplo:
Al Inciar un corrimiento siempre se inicializa enviando
un dato en este caso un 1 despus se enviara dat
datos
de valor 0 si nuestro corrimiento solo consta de 8 bit,
entonces el bit que contiene el 1 debe de correr 8 veces antes de salir.
10000000 ->01000000
00100000
99
2010
00000000
Para hacer esto se cuenta con un
circuito 74HC164 que es especialmente
para corrimientos, se mues
muestra el
esquema de este circuito. Ahora bien la
explicacin de las
conexiones es muy
simple:
MR Este
e pin es un Master Reset y su
funcin es resetear el dispositivo, si
esta al positivo este funciona
normalmente mientras si esta en cero (a
tierra) este estar en modo reset y el
circuito no funcionara,
aunque se este
enviado pulsos al CP.
DSA y DSB se
conectan las dos para
tener en los pines el
mismo estado lgico y
son el encargado de
enviar el dato un 1 o
0.
CP es el encargado de administrar el
tiempo (clock) el tiempo de corrimiento
depende del microcontrolador ya que
este puede generar la suficiente
frecuencia para tener un corrimiento
2010
conectar el MR y listo.
segundo.
el valor de la fila.
101
2010
abajo).
ejemplo:
102
2010
104
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS
= Watch Dog Timer Desactivado
//PWRTEN
= Power Activado
//INTIO
= Osiclador interno
//MCLREN
= Activamos Master Clear
//LVPDIS
= Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ
#define CLOCK RA0
#define DATO RA1
#define RESET RA2
void config(void);
void SEND_DATA(unsigned char DATA);
void CLEAR(void);
//--------------------------------------------------------//VARIABLES DONDE SE ENCUENTRA LOS NUMEROS
/
//--------------------------------------------------------const unsigned char ALFA[10][8]={0X00,0X3C,0X7E,0XC3,0XC3,0XC3,0X7E,0X3C, //0
0X00,0X00,0XC4,0XC6,0XFF,0XFF,0XC0,0XC0, //1
0X00,0X00,0XCE,0XE7,0XF3,0XDB,0XCF,0XE6, //2
0X00,0X00,0X42,0XDB,0XDB,0XDB,0XFF,0X7E, //3
0X00,0X10,0XD8,0XDC,0XD6,0XFF,0XFF,0XD8, //4
0X00,0X00,0XCE,0XDF,0XDB,0XDB,0XF3,0X73, //5
0X00,0X00,0X7E,0XFF,0XD3,0XD3,0XF7,0X66, //6
0X00,0X00,0XC3,0XE3,0X73,0X3B,0X1F,0X0F, //7
0X00,0X00,0X66,0XFF,0XDB,0XDB,0XFF,0X66, //8
0X00,0X00,0X4E,0XDF,0XDB,0XDB,0XFF,0X7E}; //9
105
2010
106
2010
2010
while(1){
for(dato3=0;dato3<10;dato3++){
//ciclo de vizializacion de centenas
for(dato2=0;dato2<10;dato2++){
//ciclo de vizualizacion de decenas
for(dato1=0;dato1<10;dato1++){
//ciclo de vizializacion de unidades
for(time=0;time<overload;time++){
//tiempo de retardo de vizualizacion que conlleva al timepo de 1segundo
for(Fila=0;Fila<8;Fila++){
//ciclo para mostrar filas, por mientras se switchean cada matriz para
//mostrar en cada matriz el numero correspondiente.
if(columna<8){
//Mostrar DATO3
//Cuando se encuentre empezando en la columna de la izquierda ya que es la primera en
//encender empezara a vizualizar el dato3 que contiene las centenas.
//Ya que cada matriz es de 8x8, al alcanzar la columna 8 este pasara a la suiguiente matriz
PORTB=ALFA[dato3][Fila];
__delay_ms(1);
PORTB=0;
}else if(columna<16){
//Mostrar DATO2
//Que contedra el valor ddecenas ya que el valor de dos matrices es de 16 la variable
//columna llega a 16 pasara a la suiente matriz
PORTB=ALFA[dato2][Fila];
__delay_ms(1);
PORTB=0;
}else if(columna<24){
//Mostrr DATO1
//Que contendra las unidades, al llegar al maximo de columnas que son 24 ya que
//es la union de 3 matrices de 8x8, que correponden a 24 columnas
//al llegar al maximo este enviara un dato 1 para inicializar toda la matriz...
PORTB=ALFA[dato1][Fila];
__delay_ms(1);
PORTB=0;
}
//Cuando llega la columna maxima ya que es 24 columnas se inicializa varibale
//"Columna" para empezar de nuevo.
if(++columna<24){
//Dato 0 para corrimiento
SEND_DATA(0);
}else{
//Dato 1 para inicializar matriz
SEND_DATA(1);
columna=0;
}
}
107
GIE=0;
}
//--------------------------------------------------------//FUNCION DE TE PERIMITE ENVIAR UN CERO O UNO
//--------------------------------------------------------void SEND_DATA(unsigned char DATA){
DATO=DATA;
CLOCK=0;
CLOCK=1;
}
//---------------------------------------------------------//FUNCION DE BORRADO
/
//---------------------------------------------------------void CLEAR(void){
for(MAX=1;MAX<=24;MAX++){
SEND_DATA(0);
}
}
108
2010
2010
Gracias!
Gracias!
He realizado varios proyectos y los he
recompilado para poder explicarlos y
realizar este manual para aquellos que
les gustan realizar proyectos a base de
microcontroladores picmicro.
Usted puede mandar dudas al correo.
george.manson.69@gmail.com
Curso v2.0
Copyright 2010
109