//--------------------------------Definicion de Librerias y constantes-------------------------------------------------
#include "built_in.h" //Libreria para usar Lo() y Hi()
#define data_port PORTB //Definimos el puerto que manejara los datos del LCD
#define data_tris TRISB //Definimos el tris quemanejara al puerto de datos.
#define RS PORTB.F2 //Definimos el pin del PIC que manejara el pin RS del LCD
#define RSt TRISB.F2 //Definimos el tris que manejara el pin RS
#define EN PORTA.F1 //Definimos el pin del PIC que manejara el pin EN del LCD
#define ENt TRISA.F1 //Definimos el tris que manejara el pin EN
#define column_port PORTB //Definimos el puerto que manejara las columnas del KEYPAD
#define row_port PORTB //Definimos el puerto que manejara las filas del KEYPAD
#include "Lcd_4Bits.h" /*Libreria que maneja Lcd creada por mi ya que
la Libreria propia de Mikroelectronica ocupa mucha memoria
y produce muchos errores. por eso decidi hacerla. */
#include "Leer_ADC.h" /*Libreria que maneja el ADC desarrollada por mi ya que
la libreria propia de Mikroelectronica configura el reloj
del ADC como RC lo que lo hace muy lento. */
//--------------------------------Declaracion de Variables-------------------------------------------------------------
char kp, //Almacena el valor del KeyPad
txt[7], //Para Convertir el valor de los angulos a Cadenas.
banderas=0; //Para almacenar si se presionan + - * =.
int O1, //Almacena el angulo 1
signo=1, //Almacena el signo del angulo
tmp=0, //Variable temporal para hacer calculos con Angulos
//Los angulos se Trabajaran en Grados.
V, E; //Almacena el Voltaje de salida y el Error de entrada
float v0, //Almacena el valor de v(k)
v1, //Almacena el valor de v(k-1)
v2, //Almacena el valor de v(k-2)
e0, //Almacena el valor de e(k)
e1, //Almacena el valor de e(k-1)
e2; //Almacena el valor de e(k-2)
//-----------------------------Interrupcion del Programa----------------------------------------------------------
void interrupt(){
TMR0H=0XF8; //Hacemos que TMR0 realice 2^16-63660=1875 cambios
TMR0L=0XAC; //Equivalente a 5ms.
e2=e1;e1=e0; //Actualizamos los valores de los errores
e0=O1; //A e0 le asignamos el entero O1
e0-=Leer_adc(); //y luego le restamos el dato del ADC
//Formula del compensador optimo.
v0 = -2.444376528*e1+1.290036675*e0+1.155562347*e2+1.955990220*v1-.9559902200*v2;
V=v0; //Asignamos v0 a V.
//Aplicamos Anti-windup
if(V>1023) //Si el valor de V es mayor a 1023
V=1023,v0=1024; //hacemos que V sea 1023 y v0 sea 1024
if(V<0)V=0,v0=0; //si V es negativo hacemos que V y v0 sean 0;
//Mandamos los valores al DAC de salida
PORTE=Hi(V) & 0B11; //Luego enviamos los 2 bits menos significativos de la parte
PORTD=Lo(V); //Primero enviamos la parte baja de V al ADC
//alta de V al ADC
v2=v1; v1=v0; //Actualizamos los valores de los voltajes
INTCON.TMR0IF=0; //Apagamos el flag de TMR0 para salir de la interrupcion
}
//-----------------------------Funcion Principal del Programa----------------------------------------------------------
void main(){
T0CON=0B10000100; //Enciende TMR0 y le pone preescaler igual a 32.
INTCON=0B10100000; //Habilita interrupciones generales y la interrupcion del TMR0
TRISA=0B00000001; //Pone RA0 como entrada los demas pines de PORTA como salidas
ADCON0=0; //Seleccionamos el AN0 como entrada para el ADC
ADCON1=0b00001110; //Definimos solo AN0 como analogico, Vref+=Vdd y Vref-=Vss
ADCON2=0b10001110; //Definimos resultado del ADC justificado a la derecha, Tacqt=2 Tad y Tad=16/Fosc*4
CMCON=7; //Apagamos los comparadores Analogicos
TRISB=0XF0; //Define RB0..3 como salidas y Rb4..7 como Entradas
INTCON2.RBPU=0; //Habilita Resistencias internas de Pull-up para el Teclado.
Lcd_Inicia(); //Inicializa Lcd.
Lcd_Comando(LCD_CURSOR_OFF); //Enciende El cursor del Lcd.
Lo(O1)=EEprom_read(0); //Valor de EEprom al byte bajo de O1
// Delay_10ms();
Hi(O1)=EEprom_read(1); //Valor de EEprom al byte alto de O1
INTCON.TMR0IF=1;
// Lo(O2)=EEprom_read(2); //Valor de EEprom al byte bajo de O1
// Hi(O2)=EEprom_read(3); //Valor de EEprom al byte alto de O1
TRISD=0; TRISE=0; //Define los puertos D y E como salidas
L1: Lcd_printfc(0,0,"O1="); //Imprime "O1 = " en Lcd posicion 0,0 (Inicio).
IntToStr(O1,txt); //Convierte O1 de entero a Cadena y guarda en txt
Lcd_print(txt); //Imprime el valor de txt
// Lcd_printfc(1,0,"O2="); //Imprime "O2 = " en Fila 1, col 2 del Lcd
// IntToStr(O2,txt); //Convierte O2 de entero a Cadena y guarda en txt
// Lcd_print(txt); //Imprime el valor de txt
do{
kp=keypad_liberar(); //Almacena el valor de la tecla presionada en kp, no continua hasta soltar tecla.
switch(kp){ //Decide que hacer a partir del valor de kp.
case '-': //Si se presiono signo '-'
if(!tmp && !banderas.F0){//Si no hay valores en tmp ni en Banderas.F0
banderas.F0=1; //Setea bit banderas.F0 para indicar resta
Lcd_Pos(0,9); //Envia el cursor a Fila SO, col 9.
Lcd_caracter('-');} //Imprime el caracter '-'.
continue;
case '+': //Si se presiono signo '+'
if(!tmp && !banderas.F2)//Si no hay valores en tmp ni en Banderas.F2
banderas.F2=1, //Setea bit banderas.F0 para indicar suma
Lcd_Pos(0,9); //Envia el cursor a Fila SO, col 9.
Lcd_caracter('+'); //Imprime el caracter '+' y salta comienzo ciclo.
case 'c':
case '*': //Si se presiono signo '*' y salta comienzo ciclo.
case 'ý':continue; //Si se presiono signo '÷' y salta comienzo ciclo.
case '=':break; //Si se presiono signo '=', termina el Switch, y comienza a guardar los datos.
default: //Si no ocurre nada de lo anterior
if(!banderas){ //Si no se ha presionado ninguna tecla antes
Lcd_printfc(0,3," ");//Imprimir en la Fila SO, Col 3, " " para borrar los numeros escritos
Lcd_Pos(0,3); //Luego ubicar el cursor en la Fila SO, Col 3.
banderas.F1=1;} //Setear banderas.F1 para indicar que se han presionado numeros.
if(tmp<3276){ //Si tmp es menor que 3276 (El rango de un entero es -32768 .. 32767)
tmp=10*tmp+kp; //tmp sera 10*tmp+kp (kp=valor de teclado).
Lcd_caracter(kp+'0');} //Imprime el valor de la tecla presionada.
continue; //Comienza el ciclo.
} //Aqui comienza a almacenar los datos en la EEprom.
// if(!SO){ //Si SO es 0, guardara angulo1
if(banderas.F0)O1-=tmp; //Si banderas.F0=1, se resta tmp a O1.
else if(banderas.F2)O1+=tmp;//Si banderas.F1=1 y, se suma tmp a O1.
else O1=tmp; //Si banderas.F0=0 y banderas.F1=0, solo se asigna tmp a O1.
EEprom_write(0,Lo(O1)); //Se escribe el valor del byte bajo de O1 en EEprom(0)
Delay_ms(20);
EEprom_write(1,Hi(O1)); //Se escribe el valor del byte alto de O1 en EEprom(1)
Lcd_Pos(1,3); //Se manda el cursor a fila 1, col 5.
// SO=1;} //Seteamos SO.F0, indica que el siguiente dado se almacenara a O2
// else{ //Si banderas.F1 es 1, guardara angulo2
// if(banderas.F0)O2-=tmp; //Si banderas.F0=1, se resta tmp a O1.
// else if(banderas.F2)O2+=tmp;//Si banderas.F2=1, se suma tmp a O1.
// else O2=tmp; //Si no, se asigna tmp a O1.
// EEprom_write(2,Lo(O2)); //Se escribe el valor del byte bajo de O1 en EEprom(0)
// EEprom_write(3,Hi(O2)); //Se escribe el valor del byte alto de O1 en EEprom(1)
// Lcd_Pos(0,3); } //Se manda el cursor a fila 0, col 5.
tmp=0; //Limpia tmp, para almacenar un nuevo valor.
banderas=0; //Limpiar Bit banderas.F0
Lcd_comando(LCD_CLEAR);
goto L1;
}while(1); //Salta al comienzo del ciclo infinito
}