Aver si os vale esto, si quereis mas decidmelo
Trato de subir el proteus completo caratulas etc pero de momento no me deja
#include <16F877.h>
#use delay(clock=4000000)
// mas precision y velocidad de conteo si se usa a 20 Mhz
// tambien trabaja a 4 Mhz pero pierde velocidad
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT // 0x3F71
// Uso mi propia libreria de LCD por usar un lcd de 4x20 y no estar este
// configurado en la rutina propia de CCS
// se puede usar la libreria lcd.h de CCS con un display conectado tal y como indica
// la libreria de CCS
#include <lcd1.c> //"lcd.h"
// inicializa valores de contadores
// si se utiliza int16 pierde valor maximo de conteo, pero gana en velocidad de calculo por
// lo que permite mas velocidad de giro o mas impulsos por vuelta sin dar error
// int32 da mas pulsos contados a costa de perder velocidad en el contador y generar mas errores
signed int16 contador_X = 0;
signed int16 contador_Y = 0;
signed int16 contador_Z = 0;
// Rutina de cambio de codigo
// pasa de codigo gray (que es el que genera a dos bits el encoder) a binario
// gray binario
// 00 00
// 01 01
// 11 10
// 10 11
/**************************************************************************************/
byte pasa_a_binario(byte valor)
{
if(bit_test(valor,1)==1) // si el bit 1 de valor es 1
{
if(bit_test(valor,0)==0) // invierte el bit 0 de valor
bit_set(valor,0); // hace 1 el bit 0 de valor
else
bit_clear(valor,0); // hace cero el bit 0 de valor
}
return valor;
}
void main(void)
{
unsigned byte actual_X ;
unsigned byte anterior_X ;
unsigned byte diferencia_X ;
unsigned byte actual_Y;
unsigned byte anterior_Y;
unsigned byte diferencia_Y;
unsigned byte actual_Z;
unsigned byte anterior_Z;
unsigned byte diferencia_Z;
disable_interrupts(GLOBAL);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
// inicializa el lcd
lcd_init();
// visualiza los Textos
lcd_gotoxy(1,1);
lcd_putc("X:");
lcd_gotoxy(1,2);
lcd_putc("Y:");
lcd_gotoxy(1,3);
lcd_putc("Z:");
lcd_gotoxy(3,1);
printf(lcd_putc,"%4.2w ",contador_X);
lcd_gotoxy(3,2);
printf(lcd_putc,"%4.2w ",contador_Y);
lcd_gotoxy(3,3);
printf(lcd_putc,"%4.2w ",contador_Z);
// borra las salidas de los leds de error
output_c(0x00);
// Lectura inicial
// lee los dos bits de menos peso del puerto A y los pone en la variable estado_X
// estos corresponden a las entradas del pic asignadas al encoder del eje X
anterior_X=input_a() & 0x03; // lee solo los bits 0 y 1
// hace la lectura del encoder Y
// para solo considerar los dos bits que interesan
anterior_Y=(input_a() & 0x0c)/4; // lee los bits 2 y 3 y desplaza a la izda 2 bits
// hace la lectura del encoder Z
// para solo considerar los dos bits que interesan
anterior_Z=(input_a()& 0x30) / 16; // lee los bits 4 y 5 y desplaza a la izda 4 bits
// pasa de codigo gray (que es el que genera a dos bits el encoder) a binario
anterior_X = pasa_a_binario(anterior_X);
anterior_Y = pasa_a_binario(anterior_Y);
anterior_Z = pasa_a_binario(anterior_Z);
while(TRUE)
{
// hace la lectura del encoder X
actual_X=input_a() & 3; // lee solo los bits 0 y 1
// hace la lectura del encoder Y
actual_Y=(input_a()& 0x0c)/4;
// hace la lectura del encoder Z
actual_Z=(input_a()& 0x30)/16;
// hace la lectura del encoder Z
actual_X = pasa_a_binario(actual_X); // cambia de codigo gray a binario
actual_Y = pasa_a_binario(actual_Y); // cambia de codigo gray a binario
actual_Z = pasa_a_binario(actual_Z); // cambia de codigo gray a binario
// rutina del eje X
if(actual_X != anterior_X) // si ha cambiado el estado es que ha habido un pulso
{
// calcula la diferencia para ver los bits de signo y de error
diferencia_X = actual_X - anterior_X;
//lineas de testeo
// lcd_gotoxy(10,1);
// printf(lcd_putc,"%d %d %x", anterior_X,actual_X,diferencia_X&3);
// chequeo los bits de error y signo
if(bit_test(diferencia_X,0) == 0) // si se ha producido un error se habra puesto a cero el bit 0
{
output_high(PIN_C0); // enciende el led de error
lcd_gotoxy(12,1);
lcd_putc("ERROR");
}
else
{ // chequea el bit de sentido de giro
// si es hacia un lado incrementa el contador lo que
// sea necesario segun el numero de pulsos/vuelta
// y la precision requerida
if(bit_test(diferencia_X,1) == 1)
contador_X = contador_X + 5;
else
contador_X = contador_X - 5;
// visualizacion eje X
lcd_gotoxy(3,1);
printf(lcd_putc,"%4.2w ",contador_X/4);
}
// memoriza en anterior_X el estado actual
anterior_X = actual_X;
}
// rutina del eje Y
if(actual_Y != anterior_Y) // si ha cambiado el estado es que ha habido un pulso
{
// calcula la diferencia para ver los bits de signo y de error
diferencia_Y = (actual_Y- anterior_Y);
// chequeo los bits de error y signo
if(bit_test(diferencia_Y,0) == 0) // si se ha producido un error se habra puesto a cero el bit 0
{
output_high(PIN_C1); // enciende el led de error
lcd_gotoxy(12,2);
lcd_putc("ERROR");
}
else
{
if(bit_test(diferencia_Y,1) == 1) // chequea el bit de sentido de giro
contador_Y=contador_Y+5; // si es hacia un lado incrementa el contador
else
contador_Y=contador_Y-5; // hacia el otro lo decrementa igualmente
// visualizacion eje Y
lcd_gotoxy(3,2);
printf(lcd_putc,"%4.2w ",contador_Y/4);
}
// memoriza en anterior_Y el estado actual
anterior_Y = actual_Y;
}
// Rutina del eje Z
if(actual_Z != anterior_Z) // si ha cambiado el estado es que ha habido un pulso
{
// calcula la diferencia para ver los bits de signo y de error
diferencia_Z = actual_Z - anterior_Z;
// chequeo los bits de error y signo
if(bit_test(diferencia_Z,0) == 0) // si se ha producido un error se habra puesto a cero el bit 0
{
output_high(PIN_C2); // enciende el led de error
lcd_gotoxy(12,3);
lcd_putc("ERROR");
}
else
{
if(bit_test(diferencia_Z,1) == 1) // chequea el bit de sentido de giro que sera 1 girando a derecha
contador_Z=contador_Z+5; // si es hacia un lado incrementa el contador
else
contador_Z= contador_Z-5 ; // hacia el otro lo decrementa
// visualizacion eje Z
lcd_gotoxy(3,3);
printf(lcd_putc,"%4.2w ",contador_Z/4);
}
// memoriza en anterior_Z el estado actual
anterior_Z = actual_Z;
}
// Pulsadores de puesta a cero
/*
If(input(PIN_B0)) // puesta a cero de posicion Inicial tres ejes
{
output_low(PIN_C0); // pone a cero los leds de error
output_low(PIN_C1);
output_low(PIN_C2);
contador_X = 0;
contador_Y = 0;
contador_Z = 0;
lcd_gotoxy(12,1);
lcd_putc(" ");
lcd_gotoxy(12,2);
lcd_putc(" ");
lcd_gotoxy(12,3);
lcd_putc(" ");
lcd_gotoxy(3,1);
printf(lcd_putc,"%4.2w ",contador_X);
lcd_gotoxy(3,2);
printf(lcd_putc,"%4.2w ",contador_Y);
lcd_gotoxy(3,3);
printf(lcd_putc,"%4.2w ",contador_Z);
}
If(input(PIN_B1)) // puesta a cero de posicion Inicial Eje X
{
output_low(PIN_C0);
contador_X = 0;
lcd_gotoxy(12,1);
lcd_putc(" ");
lcd_gotoxy(3,1);
printf(lcd_putc,"%4.2w ",contador_X);
}
If(input(PIN_B2)) // puesta a cero de posicion Inicial Eje Y
{
output_low(PIN_C1);
contador_Y = 0;
lcd_gotoxy(12,2);
lcd_putc(" ");
lcd_gotoxy(3,2);
printf(lcd_putc,"%4.2w ",contador_Y);
}
If(input(PIN_B3)) // puesta a cero de posicion Inicial eje Z
{
output_low(PIN_C2);
contador_Z = 0;
lcd_gotoxy(12,3);
lcd_putc(" ");
lcd_gotoxy(3,3);
printf(lcd_putc,"%4.2w ",contador_Z);
}
*/
}
}