Hola, que tal?? yevo unas semnas muy liado por eso no he podido contarte los avances. Bueno pus la palca me ha dicho la empresa que para el martes estara imprimida y los componentes soldados.
Ahora estoy haciendo las funciones del protocolo I2C, en la página de maxim encontre las cabeceras de las funciones, aunque básicamente no sirve de mucho me dio una idea de por donde seguir.
Con esas cabeceras y las hojas de caracteristicas del max7300 y del max7318 he desarrollado 5 funciones, leer y escribir 1 bit, leer y escribir 1byte y luego la la condicion de start y de stop del protocolo I2C. Las funciones las he simulado con Keil3.0 (Muchas gracias por el link) y han funcionado bien.
Ahora me queda resolver el problema de la función delay, para el protocolo I2C se tienen que cumplir unos tiempos minimos para que el dato quede validado, yo lo he puesto con un bucle for de 10 ciclos pero no se si cumplira los 4uS que son necesarios para los componentes max7xxx, sera cuestion de probar y de averiguar la fercuencia de Osc que tiene la placa DS80C400.
Ahora ya simulado las funciones el siguiente paso es realizar un programita para leer del teclado y escribir en el display LCD. Y es este paso para mi el que puede ser más complicado.
Para empezar me he leido de cabo a rabo todas las hojas de caracteristicas, lo que no se aun muy bien es como detectar mediante el puerto que he pulsado una tecla, es decir. Ya tengo en un registro los 4bits del codigo binario de la tecla que se ha pulsado, al mismo tiempo tengo un pin que me da un pulso de nivel alto cada vez que se pulsa una tecla (esto es por si acaso se pulsa la misma tecla ver que se ha pulsado dos veces), pero no puedo estar consumiendo todos los recursos del I2c en ver si se ha pulsado una tecla.
No se si me explico bien, he leido en las hojas de caracteristicas que los componentes si estan configurados sus puertos a entrada (input) entonces estos pueden detectar cambios en las entradas, la cosa es que no se si funciona como interrupción o no se. El caso es que lo mejor sería tener en la placa una entrada de INT para asi mediante irq poder saber quien ha interrumpido y leer entonces del componente que gobierna al teclado.
Asi que ahora me dedicare a eso, mientras me darán la placa y terminare de montar todo, para entonces hacer las pruebas ya fisicamente y espero que no me den muchos errores, pero mi experiencia es que seguro que me darán.
Una vez hecho eso ya solo es programas los diagramas de estados que tengo hechos y espero que ya.
Dejo el codigo fuente *.c de las funciones de I2C, para que si alguien tiene que usarlas que no se rompa la cabeza como he hecho yo:
#include<reg51.h>
#include "uah_types.h"
//#include "uah_bit_access.h" esta dentro del uah_types.h
#define I2C_SDA P3_4
#define I2C_SCL P3_5
#define I2C_ENABLE_SCL_WAIT_FOR_SLOW_SLAVES 0
#define I2C_MAXIMUM_SCL_WAITCOUNT 10000
#define I2C_DELAY_LOOP_COUNT 0
//sbit SDA = p3^2;
//sbit SCL = p3^3;
unsigned char SLAVE1 = 0x40; // Variable con la direccion del periferico MAX7318.
unsigned char SLAVE2 = 0x82; // Variable con la direccion del periferico MAX7300.
unsigned char byte_leido; // Byte leido de algun esclavo.
unsigned char bit_leido; // Bit leido de algun esclavo.
void i2c_delay(void) // retardo minimo de 4.7uS.
{ // Fosc = 11.0592MHz.
byte wait;
for (wait=0;wait<10;wait++)
{
;
}
}
void i2c_start(void)
{
I2C_SDA = 1; // SDA en teoria debe estar ya a "1" para que tenga condicion de STOP
I2C_SCL = 1;
//P3_4 = 1;
//P3_5 = 1;
i2c_delay();
I2C_SDA = 0;
i2c_delay();
I2C_SCL = 0;
i2c_delay(); // START de la transmision
}
void i2c_stop(void)
{
I2C_SCL = 1;
i2c_delay(); // Cumplo Tsu, STO
I2C_SDA = 1;
i2c_delay(); // STOP de la transmision
}
void validar_escritura(void)
{
I2C_SCL=1; // Realizo la señal de reloj SCL
i2c_delay(); //
I2C_SCL=0; //
}
unsigned char i2c_select(unsigned char address)
{
// SELECCION DEL PERIFERICO QUE VAMOS A USAR
// SE PUEDE HACER EN EL MISMO CODIGO DEL MAIN()
}
void i2c_bit(unsigned char singlebit)
{
unsigned char bit_a_enviar;
unsigned char ACK;
bit_a_enviar=singlebit; // Asocio el bit que me pasan como parametro
i2c_start(); // Inicio la transmisión
if (bit_a_enviar == '1') // Transmito el bit
{ //
I2C_SDA = 1; //
}
else{
I2C_SDA = 0;
}
validar_escritura();
//I2C_SCL=1; // Lo realiza la función validar función,
//i2c_delay(); // asi me quito los errores de que no me ejecutaba
//I2C_SCL=0; // las lineas estas
i2c_delay(); //
i2c_stop(); // Fin transmision
//ACK=SDA; // Compruebo si he recibido el bit ACK
//
//if(ACK == 0) //
//{
// exit -1; // Problema grave: el esclavo no ha recibido el dato
// // (no ha mandado ACK)
//}
}
unsigned char i2c_readbit(void)
{
unsigned char i; // Variable auxiliar.
i2c_start(); // Inicio la transmisión.
I2C_SCL=1;
i2c_delay();
if(I2C_SDA == 1) // Asigno a la variable auxiliar el valor de SDA
{ //
i=1; //
}else i=0;
I2C_SCL=0; //
i2c_stop(); // Fin recepción
return (i); // Devuelvo el valor leido
}
unsigned char i2c_readbyte(unsigned char doACK)
//doACK = NACK = 1 para el ultimo byte.
//doACK = ACK = 0 para cualquier valor que no sea el ultimo.
{
unsigned char i; // Variable del contador del bucle
unsigned char aux; // Variable donde se va almacenar el dato leido temporalmente
i2c_start(); // Inicio la transmisión.
for (i=0;i<8;i++) // Lo realizo 8 veces – 1 byte.
{
I2C_SCL=1; // Comienzo la adquisicion.
i2c_delay();
aux = aux<<1; // Desplazo un bit (concateno el dato).
if (I2C_SDA == 1) aux++; // Obtengo el valor del bit de SDA.
I2C_SCL=0; // Bajo la señal para preparar la captura del siguiente.
i2c_delay();
}
I2C_SDA = doACK; // Esto es para el bit de ACK
I2C_SCL=1;
i2c_delay();
I2C_SCL=0;
i2c_delay();
return (aux); // Devuelvo eñ dato leido.
}
unsigned char i2c_writebyte(unsigned char singlebyte)
{
unsigned char byte_enviar;
unsigned char ACK;
unsigned char i;
byte_enviar = singlebyte;
i2c_start(); // Inicio la transmisión
for (i=0;i<8;i++)
{
if (byte_enviar & 0x80) // Realizo la transmision
{ //
I2C_SDA = 1; //
}else I2C_SDA = 0; //
validar_escritura();
//I2C_SCL=1; // Lo realiza la función validar función,
//i2c_delay(); // asi me quito los errores de que no me ejecutaba
//I2C_SCL=0; // las lineas estas
i2c_delay(); //
byte_enviar=byte_enviar<<1; // Desplazo byte a enviar hacia la izqda
}
i2c_stop(); // Fin transmision
ACK=I2C_SDA; // Compruebo si he recibido el bit ACK
//
// if(ACK == 0) //
// {
// exit -1; // Problema grave: el esclavo no ha recibido el dato
// (no ha mandado ACK)
// }
}
unsigned char i2c_writeblock(unsigned char address,unsigned char *barr,int length);
unsigned char i2c_readblock(unsigned char address,unsigned char *barr,int length);
unsigned char i2c_writereadblock(unsigned char address,unsigned char *barr1,int length1,
unsigned char *barr2,int length2);
void main (void)
{
// Mandar un bit
//i2c_bit('1'); // PERFECTO
//Leer un bit // PERFECTO
//bit_leido=i2c_readbit();
//P3_6=bit_leido;
//Mandar un byte
//i2c_writebyte(0x5F); // Perfecto
//P2=i2c_readbyte(1); // Perfecto, he leido (forzando la entrada del puerto)
// SDA a los valores 0x53 y me ha devuelto en el puerto
// P2 los valores que he leido del puerto SDA
}
Bueno si sabes alguna manera de como hacer que la placa se entere de que ha cambiado el teclado pues como siempre estaré muy agradecido.
te mando un mail ahora con algunos archivos.
En una semana espero poner más avances</reg51.h>