viernes, 26 de octubre de 2012

jueves, 25 de octubre de 2012

sdcc easypic2 Funcionando


sdcc easypic2 main n_n

JMQ01.c
#include <pic16f877a.h>
#include "timer.h"
#include "lcd.h"
#include "jmq.h"
#include "adc.h"
#include "i2c.h"
#include "pcf8583.h"

volatile unsigned int band_a=0, B_LED=0,LED=0,opcion=1;
volatile unsigned int TdC=0;

#define DIR_I2C   0x8


void isr() interrupt 0 
{                                                                                                   /* rutina de servicio de interrupciones */
  if (RBIF==1){
   if (RB7==0){
    delay(5);
    if (RB7==0){
     if (B_LED==0){
      LED=1;
      B_LED=1;
     }else{
      LED=0;
      B_LED=0;
     }
    }
   }

   if (RB6==0){
    delay(5);
    if (RB6==0){
     opcion++;
     if (opcion>8)opcion=8;     
    } 
   }

   if (RB5==0){
    delay(5);
    if(RB5==0){ 
     opcion--;
     if (opcion<1)opcion=1;
    }
   } 
   
   if (RB4==0){
    delay(5);
    if(RB4==0){ 
      band_a=1;
      i2c_write_byte(DIR_I2C, 0x0,opcion);
    }
  
   }
  } 
  RBIF=0;
}

/*--------------------------------*/

void main(void)
{
  
  unsigned int a,b,c,d,CONTROL=0b10101100;  
  unsigned int direccion=0,temp;
  unsigned char datol,datoh;
 
  
  RBIE=1;
  GIE=1;
  TRISD=0b00000000;
  TRISB=0b11111111;
  
  TRISA=0b00000000;
  ADCON1 = 0b00000110;
  
  PORTA=0;PORTD=0;
  band_a=0;

  config_timer();
  delay(1000);
  i2c_configure();  
  delay(100);
  
  lcd_cmd(SET,LED);
  lcd_cmd(MODO,LED);
  lcd_cmd(CLS,LED);
  lcd_cmd(CurOFF,LED);


  print_xy(0,LED);
  print_lcd("easypic 2",1);
  print_xy(40,LED);
  print_lcd("   V1.0 JMQ   ",1);
  delay(2000);
  lcd_cmd(CLS,LED);
  

  LED=0;
  

  
  while(1){
   print_xy(0,LED);print_lcd("Rele Nro:",LED); 
   temp=opcion;   
   INT_BCD(temp,&a,&b,&c,&d);
   print_xy(11,LED);lcd_write(BCD_ASCII(d),LED); 
   
   i2c_read_byte(DIR_I2C, 0x02, &datol);
   INT_BCD(datol,&a,&b,&c,&d);
   print_xy(40,LED);lcd_write(BCD_ASCII(b),LED);    
   print_xy(41,LED);lcd_write(BCD_ASCII(c),LED);
   print_xy(42,LED);lcd_write(BCD_ASCII(d),LED);
   
   LeerLM75(0b10010111, &datoh, &datol);
   INT_BCD(datoh,&a,&b,&c,&d);
   print_xy(44,LED);lcd_write(BCD_ASCII(c),LED);
   print_xy(45,LED);lcd_write(BCD_ASCII(d),LED);
   
   
   /*direccion++;      
   if(direccion>256){
     CONTROL=0b10101110;
     if(direccion==512)direccion=0;
     datoh=0;
   }else{
     CONTROL=0b10101100;
     if(direccion==512)direccion=0;
     
   }  
   
   i2c_write_byte(CONTROL,direccion,datoh);
   INT_BCD(direccion,&a,&b,&c,&d);
   print_xy(49,LED);lcd_write(BCD_ASCII(a),LED);
   print_xy(50,LED);lcd_write(BCD_ASCII(b),LED);
   print_xy(51,LED);lcd_write(BCD_ASCII(c),LED);
   print_xy(52,LED);lcd_write(BCD_ASCII(d),LED);*/
   hora(LED);
   
  }
  
}

sdcc easypic2 jmq xD! BCD

jmq.h
#include <pic16f877a.h>

void INT_BCD(unsigned int dato, unsigned int *a, unsigned int *b,unsigned int *c,unsigned int *d)
{
 *a = dato / 1000;
 *b = (dato % 1000) / 100;
 *c = ((dato % 1000) % 100)/10;
 *d = ((dato % 1000) % 100)%10;

}

char BCD_ASCII(unsigned int dato){
 return (dato | 48);
}

sdcc easypic2 pcf8583

pcf8583.h
#include <pic16f877a.h>

void unidad_decena(unsigned int dato,unsigned int *unidad, unsigned int *decena);

void hora(unsigned int LED){
   unsigned int unidad,decena;
   unsigned char dato;
   //HORA
   i2c_read_byte(0b10100010,0x4,&dato);   
   unidad_decena(dato,&unidad,&decena);
   print_xy(48,LED);lcd_write(BCD_ASCII(decena),LED);
   print_xy(49,LED);lcd_write(BCD_ASCII(unidad),LED);
   //MINUTOS
   i2c_read_byte(0b10100010,0x3,&dato);   
   unidad_decena(dato,&unidad,&decena);
   print_xy(51,LED);lcd_write(BCD_ASCII(decena),LED);
   print_xy(52,LED);lcd_write(BCD_ASCII(unidad),LED);   
   //SEGUNDOS
   i2c_read_byte(0b10100010,0x2,&dato);   
   unidad_decena(dato,&unidad,&decena);
   print_xy(54,LED);lcd_write(BCD_ASCII(decena),LED);
   print_xy(55,LED);lcd_write(BCD_ASCII(unidad),LED);
}
  
void unidad_decena(unsigned int dato,unsigned int *unidad, unsigned int *decena){
  *unidad=dato & 0x0f;
  *decena=(dato>>=4);
}

sdcc easypic2 i2c

i2c.h
#include <pic16f877a.h>
/*
****************************************
*    FUNCIONES DE BAJO NIVEL DEL I2C   * 
****************************************
*/

// Envia Ack
// SDA = 0 
void i2c_SendAck()
{
  ACKDT = 0;  // Establece un ACK
  ACKEN = 1;  // Lo envia
}


// Envia Nack para finalizar la recepecion
// SDA = 1
void i2c_SendNack()
{
  ACKDT = 1;  // Establece un NACK
  ACKEN = 1;  // Lo envia
}


// verifica ACK
// Mira si en el 9 pulso de reloj (SCL en estado a 1) la señal SDA está a 0
unsigned char i2c_CheckACK()
{
  if ( ACKSTAT == 0 ) {
    return 0;   // correcto (lo he recibido )
  } else { 
    return 1; // incorrecto (no lo he recibido)
  }
}


// Envia la condicion de STOP
// Libera el BUS I2C, SDA y SCL a nivel alto
// SDA=1 cuando SCL=1. 
void i2c_SendStop() {
  PEN = 1;    // send stop bit
}


// Envia la condicion de START
// Inicializa el Bus I2C, SCL y SDA a nivel bajo
// Estando SCL=1 pone SDA=0, luego pone SCL=0
void i2c_SendStart()
{
  SEN = 1;     // send start bit
}

// Espera a que el I2C reciba algun evento
void i2c_WaitMSSP() 
{
  while (SSPIF == 0);  // Espera evento
  SSPIF=0;             // Limpia FLAG
}


// Espera a que el I2C reciba algun evento
unsigned char i2c_MSSP_Status()
{
  return SSPIF; 
}




// Repeated start from master
// Queremos transmitir más datos pero sin dejar el BUS, es decir
// sin mandar previamente un STOP. O por ejemplo si queremos mandar un STOP y seguidamente un
// START para que ningún otro dispositivo ocupe la línea usaremos esto.
void i2c_SendRStart() {
  RSEN=1;
}


// Leer Byte por el I2C
// Devuelve byte leido
unsigned char i2c_ReadByte() {
  RCEN=1;        // Activar el RCEN

  i2c_WaitMSSP();
  return SSPBUF;
}




// Envia un Dato por el Bus I2C
// Entrada el dato a enviar
void i2c_SendByte(unsigned char dato) {
  SSPBUF=dato;
}



// Fallo en el I2C
void i2c_fail() {
  i2c_SendStop();
  i2c_WaitMSSP();
}



/*
**************************************
*   FUNCIONES DE ALTO NIVEL del I2C  *
**************************************
*/


/* Configurar I2C
  Configuramos el I2C como Master
  y a una velocidad de 1Mhz
*/

void i2c_configure()
{
  // configuramos SCL y SDA como pines de entrada
  TRISC=TRISC | 0x18;  // 1 entrada / 0 salida  
  
  SSPSTAT=0x0;  
  SSPSTAT=SSPSTAT | 0x80;  // SMP=1 Slew rate disable for 100Kh  @@@
                           // CKE=0 (modo maestro I2C) y UA=0 (7 bits)

  SSPCON=0x08;       // I2C master mode (uso la formula del reloj con SSPAD)  
  SSPCON=SSPCON | 0x20;  // enable I2C  SSPEN=1

  SSPCON2=0x00;   // no se usa por ahora
  // velocidad = FOSC / ( 4 * (sspad + 1) )
  // Fosc=20Mhz

  SSPADD=49;  // 49->100Khz  @@@
  //SSPADD=24; // 24 -> 400khz   @@@

  // Limpia Flags de eventos
  SSPIF=0;  //Limpia flag de eventos SSP 
}



// manda un byte al dispositivo i2c
unsigned char i2c_write_byte(unsigned char address, unsigned char reg,
                             unsigned char dato)
{
  // 1º Envia Bit de Start
  i2c_SendStart();
  i2c_WaitMSSP();  

  // 2º Envio la direccion del modulo
  i2c_SendByte(address);
  i2c_WaitMSSP();
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;  // Ha habido un error, salgo de la rutina
  }

  // 3º mando el registro sobre el que voy a actuar
  i2c_SendByte(reg);
  i2c_WaitMSSP(); 
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;   // Ha habido un error, salgo de la rutina
  }

  // 4º mando el dato 
  i2c_SendByte(dato); 
  i2c_WaitMSSP();
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;    // Ha habido un error, salgo de la rutina
  }

  // 6º termino el envio
  i2c_SendStop();
  i2c_WaitMSSP();

  return 1;  // Byte mandado correctamente
}


// Lee 1 byte1  del dispositivo i2c
// El dato leido lo devuelve por el parametro dato
unsigned char i2c_read_byte(unsigned char address, unsigned char reg, 
                            unsigned char *dato)
{

  // 1º Envia Bit de Start
  i2c_SendStart();
  i2c_WaitMSSP();  

  // 2º Envio la direccion del modulo
  i2c_SendByte(address);
  i2c_WaitMSSP();  
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;   // Ha habido un error, salgo de la rutina
  }

  // 3º mando el registro sobre el que voy a actuar
  i2c_SendByte(reg); 
  i2c_WaitMSSP();  
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;   // Ha habido un error, salgo de la rutina
  }

  // 4º Repeated start
  i2c_SendRStart();
  i2c_WaitMSSP();  

  // 4º mando direccion indicando lectura
  i2c_SendByte(address+1);
  i2c_WaitMSSP();  
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;   // Ha habido un error, salgo de la rutina
  }

  // 5º leo el byte 
  *dato=i2c_ReadByte(); 

  // 6º Mando NACK
  i2c_SendNack();
  i2c_WaitMSSP();  

  // Mando el Stop
  i2c_SendStop();
  i2c_WaitMSSP();  

  return 1;   // Lectura correcta

}

// Lee 2 bytes consecutivos  del dispositivo i2c
// El dato leido lo devuelve por el parametro dato
unsigned char i2c_read_word(unsigned char address, unsigned char reg, 
                            unsigned int *dato)
{
  unsigned char tmp_H, tmp_L;

  // 1º Envia Bit de Start
  i2c_SendStart();
  i2c_WaitMSSP();  
    
  // 2º Envio la direccion del modulo
  i2c_SendByte(address);
  i2c_WaitMSSP();  
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;   // Ha habido un error, salgo de la rutina
  }

  // 3º mando el registro sobre el que voy a actuar
  i2c_SendByte(reg); 
  i2c_WaitMSSP();  
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;   // Ha habido un error, salgo de la rutina
  }

  // 4º Repeated start
  i2c_SendRStart();
  i2c_WaitMSSP();  

  // 4º mando direccion indicando lectura
  i2c_SendByte(address+1);
  i2c_WaitMSSP();  
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;   // Ha habido un error, salgo de la rutina
  }

  // 5º leo el 1 byte 
  tmp_H=i2c_ReadByte(); 
  
  // 6º Mando ACK
  i2c_SendAck();
  i2c_WaitMSSP();  
  
  // 7º leo el 2 byte 
  tmp_L=i2c_ReadByte(); 
  
  // 6º Mando NACK
  i2c_SendNack();
  i2c_WaitMSSP();  

  // Mando el Stop
  i2c_SendStop();
  i2c_WaitMSSP();  
  
  *dato=(tmp_H*256) + tmp_L;
  
  return 1;   // Lectura correcta
}

unsigned char LeerLM75(unsigned char address, unsigned char *datoh, unsigned char *datol)
{
  i2c_SendStart();
  i2c_WaitMSSP(); 

  i2c_SendByte(address);

  i2c_WaitMSSP();  
  if (i2c_CheckACK()!=0) {
    i2c_fail();
    return 0;   // Ha habido un error, salgo de la rutina
  }
 
  *datoh=i2c_ReadByte(); 
  
  i2c_SendAck();
  i2c_WaitMSSP(); 

  *datol=i2c_ReadByte();   

  //  Mando NACK
  i2c_SendNack();
  i2c_WaitMSSP();  

  // Mando el Stop
  i2c_SendStop();
  i2c_WaitMSSP();  

  return 1;
}

sdcc easypic2 timer

timer.h
#include <pic16f877a.h>
void pausa_1ms()
{
  //-- Dar valor inicial del timer
  TMR0=100;
 
  //-- Flag de interrupcion a cero
  T0IF=0;

  //-- Esperar a que transcurra 1ms
  while(T0IF==0);

}

void config_timer()
{
  //-- Configurar Timer 0
  //-- Modo temporizador
  T0CS=0; PSA=0;
  //-- Presscaler a 32
  PS2=1; PS1=0; PS0=0;
}

void delay(unsigned int duracion)
{
  unsigned int i;

  for (i=0; i<duracion; i++)
    pausa_1ms();
}

sdcc easypic2 lcd 4 bits

lcd.h
#include <pic16f877a.h>

#define SET    0b00100000
#define CLS    0b00000001
#define HOME   0b00000010
#define MODO   0b00000110
#define SHIFT  0b00011100
#define CurON  0b00001110
#define CurOFF 0b00001100 

#define RS  RD0
#define E   RD1
#define BL  RD2


void enable()
{
  //-- Hay que garantizar un tiempo minimo de 500ns
  //-- A 20Mhz, las instrucciones tardan 200ns.
  //-- Por eso nos curamos en salud y repetimos la instruccion
  //-- tres veces. 
  E=1; E=1; E=1;
  E=0; E=0; E=0;
}

/*--------------------------------*/
void lcd_cmd(unsigned char cmd,unsigned int led){
 unsigned int aux; 
 aux=cmd;
 aux>>=4;
 aux<<=4;
 PORTD=aux;
 RS=0;
 enable();
 aux=cmd;
 aux<<=4;
 PORTD=aux;
 RS=0;
 enable();
 BL=led;
 delay(5); 
}
void lcd_write(unsigned char car,unsigned int led)
{ 
 unsigned int aux; 
 aux=car;
 aux>>=4;
 aux<<=4;
 PORTD=aux;
 BL=led;
 RS=1;
 enable();
 aux=car;
 aux<<=4;
 PORTD=aux;
 BL=led;
 RS=1;
 enable();
 delay(5); 
}

void print_lcd(unsigned char *cad,unsigned int led)
{
  unsigned char i=0;

  while (cad[i]!=0) {
    lcd_write(cad[i],led);
    i++;
  }
}

void print_xy(unsigned int DDRAM,unsigned int led)
{
 unsigned int aux;
 aux = 0b10000000 | DDRAM ;
 lcd_cmd(aux,led);
}

IRC

#freenode->#usljujuy

Seguidores

Eventos n_n

Tira Ecol Nano,Bilo y Luca