Autor Tema: Aporte C18 18F4550 Codigo I2C + ADC + KEYB + LCD + RS232 Compatible Bootloader  (Leído 5395 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado alcubo01

  • PIC12
  • **
  • Mensajes: 69
Para probar una placa que he hecho, he tenido que testear  I2C, ADC, KEYB, LCD, RS232 y como uso Bootloader, hacerlo compatible con éste. Para las pruebas he usado un PIC18F4550 como Master I2C que realmente es el objeto de testeo y un 16F876A actuando como Slave I2C (dummy).

El compilador usado es C18 para el Master y PICC para el Slave.

Master : Fosc = 48M, I2C Hardware
Slave :  Fosc = 4M, I2C Hardware

 El resultado es una mezcla de código del foro, de fuera y propio. Lo pongo aquí por si a alguien le resulta útil.


Codigo Master (C18)
 
Código: [Seleccionar]
/*********************************************************************
Alberto: Prueba CAD + LCD + KEYB + I2C + BOOTLOADERUSB
 ********************************************************************/


/** I N C L U D E S **********************************************************/
#include <p18F4550.h>
#include <delays.h>
#include <stdlib.h> //Libreria para conversiones.
#include <adc.h>
#include <usart.h>
#include <i2c.h>
#include <xlcd.h>

/** V A R I A B L E S ********************************************************/
#pragma udata

/** P R I V A T E  P R O T O T Y P E S ***************************************/

/** V E C T O R  R E M A P P I N G *******************************************/

extern void _startup (void);        // See c018i.c in your C18 compiler dir
#pragma code _RESET_INTERRUPT_VECTOR = 0x000800
void _reset (void)
{
_asm goto _startup _endasm
}
#pragma code

#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
void _high_ISR (void)
{
;
}

#pragma code _LOW_INTERRUPT_VECTOR = 0x000818
void _low_ISR (void)
{
;
}
#pragma code


/** D E C L A R A T I O N S **************************************************/
#pragma code

#define puerto_lcd PORTD
#define porte = 0xf84
#define e   LATBbits.LATB7
#define rs LATBbits.LATB5
#define rw LATBbits.LATB6


void ini_lcd(void);
void write_LCD(char * cadena,int longit);
void lcd_gotoxy( int x, int y);

char read_keyb();

void ParpadeoLeds(void);
void LecturaAdc(unsigned char port,unsigned int* valor);
void FormatVoltio(unsigned int valorAdc,char *buffer);

void write_byte_i2c(char add,char idata);
char read_char_i2c(char add);


unsigned char warr[] = {8,7,6,5,4,3,2,1,0};
unsigned char rarr[15];
unsigned char *rdptr = rarr;
unsigned char *wrptr = warr;


char tabla0[] = {"INIT = "}; //Tabla que contiene el texto a mostrar
char tabla1[] = {"ADC3 = "};
char tabla2[] = {"ADC5 = "};
char tabla3[] = {"KEYB = "};
char tabla4[] = {"PULS = "};
char tabla5[] = {"I2CD = "};
char tabla6[] = {"ERRO = "};
char espacios[] = {"                "};
volatile char Data, Kbhit;


void main(void){

unsigned int Canal,i;
char sbuf[6];
char puls[3];
char conv[10];
char keyb,prev_keyb,flag,data,c;
int j;
int pulsaciones = 0;

//LEDs
TRISCbits.TRISC0=0;
TRISDbits.TRISD1=0;

//ADC
TRISAbits.TRISA0=1; TRISAbits.TRISA1=1; TRISAbits.TRISA2=1; TRISAbits.TRISA3=1; TRISAbits.TRISA5=1;
TRISEbits.TRISE0=1; TRISEbits.TRISE1=1; TRISEbits.TRISE2=1; TRISBbits.TRISB2=1; TRISBbits.TRISB3=1;

OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW,77); // 9600,8,n,1
OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_2_TAD, ADC_INT_OFF & ADC_REF_VDD_VSS ,ADC_10ANA/*0b0101*/);
OpenI2C(MASTER, SLEW_ON);// Initializar Modulo I2C
SSPADD = 119; //100kHz Baud 119 at 48MHz  SSPADD = (Fosc/(4*100k))-1

ADCON1 = 0b00000101; // Vref- Vss, Vref+ Vdd, AN0-AN9 Analog resto Digit
Kbhit=0; RCONbits.IPEN=0; // Deshabilitamos Prioridades
INTCONbits.PEIE=1; // Habilitamos interrupcion de perifericos.-
INTCONbits.GIE=1; // Habilitamos interrupcion Global.


ini_lcd(); //inicia display a 8 bit

putrsUSART("Prueba");

for(c=0;c<16;c++) //Iniciamos los valores en Slave I2C
write_byte_i2c(c,('A' + c));

flag = 0;
while(1){

keyb = read_keyb();

if(keyb != 0){ //Tecla pulsada
prev_keyb = keyb;
pulsaciones++;
flag = 1;
}
else{
if(flag == 1){ //Usamos la tecla pulsada para lectura I2C
flag = 0;

data = read_char_i2c(atoi(&prev_keyb));
lcd_gotoxy(1,1);
if(data != 0){
write_LCD(tabla5,7);
write_LCD(&data,1);
write_LCD(espacios,8);
}
else{
write_LCD(tabla6,7);
write_LCD(espacios,9);
}
}

LecturaAdc(ADC_CH2,&Canal); //Lectura canal ADC
FormatVoltio(Canal,sbuf);
putrsUSART(" Canal 3 en V = ");
putsUSART(sbuf);
lcd_gotoxy(1,2);
write_LCD(tabla1,7);
write_LCD(sbuf,5);
write_LCD(espacios,4);

Delay10KTCYx(120);  //delay_ms(10);
}
}
}


void lcd_tris(){

TRISBbits.TRISB5=0;
TRISBbits.TRISB6=0;
TRISBbits.TRISB7=0;
TRISD = 0;
TRISAbits.TRISA4=0;
}

//Modo 8 bits
void display_LCD(short valor , int respaldo) //Rutina que envia al LCD una palabra de control o dirección
{

int tiempo = 20; //Orig a N = 12, 10us

if(valor == 0)
rs = 0;
else
rs = 1;

puerto_lcd = respaldo;

if(respaldo & 0x02)
LATAbits.LATA4=1;
else
LATAbits.LATA4=0;

e = 1;
Delay10TCYx(tiempo);//delay_us(10);
e = 0;

Delay10TCYx(tiempo); //delay_us(10);
}

void ini_lcd(){

int i,j;

lcd_tris();

LATAbits.LATA4=0; puerto_lcd = 0; rw = 0; e = 0; rs = 0;

for(j=0;j<10;j++)
Delay10KTCYx(60); //delay_ms(500);

Delay10KTCYx(18); //Temporiza 15mS

for(i=0; i<3; i++) //Envía 3 veces el comando 0x38 a intervalos de 5 mS
{
display_LCD(0,0x38);
//delay_ms(5);
Delay10KTCYx(6);
}

display_LCD(0,0b00001111); //Secuencia de comandos a enviar a la pantalla LCD
display_LCD(0,0x06);   //SHIFT_DISP_LEFT
display_LCD(0 , 0b00000001); //LCD CLEAR
display_LCD(0,0x02);  //LCD HOME

Delay1KTCYx(240); //delay_ms(20);
}

void write_LCD(char * cadena,int longit) //Escribe mensaje en LCD
{
int i;

lcd_tris();

for(i=0;i<longit;i++) //Ciclo que envía el texto al LCD
display_LCD(1 , cadena[i]);
}


//Función para situar el cursor
void lcd_gotoxy( int x, int y) {
int dir;

lcd_tris();

if(y==1)
dir=0;
else
dir=0x40;

dir+=x-1;
display_LCD(0,0x80|dir);
}


void LecturaAdc(unsigned char port,unsigned int* valor){

SetChanADC(port); // Selecciono canal a convertir
Delay10TCYx(4); // Carga el capacitor sample&hold
ConvertADC(); // Comienza conversión
while(BusyADC()); // Hasta que se finalice conversión
*valor= ReadADC(); // Realizo lectura
}


void FormatVoltio(unsigned int valorAdc,char *buffer){

unsigned int valor;
char String[6];

valor = (int)((valorAdc/204.8)*1000);
itoa(valor, String); // Convertimos entero a string.-
buffer[0]=String[0];
buffer[1]='.';
buffer[2]=String[1];
buffer[3]=String[2];
buffer[4]=String[3];
buffer[5]='\0';
}

void ParpadeoLeds(void){

int i;

LATCbits.LATC0 = 1; // Parpadeo de los LEDs
LATDbits.LATD1 = 1;

for(i=0;i<10;i++)
Delay10KTCYx(120);

LATCbits.LATC0 = 0;
LATDbits.LATD1 = 0;

for(i=0;i<10;i++)
Delay10KTCYx(120);
}


unsigned int bit_test (unsigned char regist,unsigned int position){

return(regist & (0x01<<position));
}

void keyb_tris(){

TRISDbits.TRISD7=1; //Input
TRISDbits.TRISD6=1;
TRISDbits.TRISD5=1;
TRISDbits.TRISD4=1;

TRISDbits.TRISD3=0; //Output
TRISDbits.TRISD2=0;
TRISDbits.TRISD2=0; //LED
TRISDbits.TRISD0=0;

PORTEbits.RDPU = 1; //Enable Pull Up resistors on PORTD
}

void antirebotes(){

//delay_ms(50);
Delay10KTCYx(60);
}

char read_keyb(){

keyb_tris();

PORTD = 0b11110111; // verifica columna 1
if(bit_test(PORTD,7)==0)
{
antirebotes();
return ('1');
}
if(bit_test(PORTD,6)==0)
{
antirebotes();
return ('4');
}
if(bit_test(PORTD,5)==0)
{
antirebotes();
return ('7');
}
if(bit_test(PORTD,4)==0)
{
antirebotes();
return ('*');
}

PORTD = 0b11111110; // verifica columna 2
if(bit_test(PORTD,7)==0)
{
antirebotes();
return ('2');
}
if(bit_test(PORTD,6)==0)
{
antirebotes();
return ('5');
}
if(bit_test(PORTD,5)==0)
{
antirebotes();
return ('8');
}
if(bit_test(PORTD,4)==0)
{
antirebotes();
return ('0');
}

PORTD = 0b11111011; // verifica columna 3
if(bit_test(PORTD,7)==0)
{
antirebotes();
return ('3');
}
if(bit_test(PORTD,6)==0)
{
antirebotes();
return ('6');
}
if(bit_test(PORTD,5)==0)
{
antirebotes();
return ('9');
}
if(bit_test(PORTD,4)==0)
{
antirebotes();
return ('#');
}

return(0);

}

void write_byte_i2c( char add, char idata )
{
StartI2C();
putcI2C(0xA0);
putcI2C(add);
putcI2C(idata);
StopI2C();
}

char read_char_i2c( char add )
{
char dat;

StartI2C();
putcI2C( 0xa0 );
putcI2C( add );
StopI2C();
StartI2C();
putcI2C( 0xa1 );
dat = getcI2C();
StopI2C();

return (dat);
}



Codigo del Slave (Compilado con PICC):

Código: [Seleccionar]
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)

//BYTE address, buffer[0x10] = {'1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G'};
BYTE address, buffer[0x10];
BYTE incoming, state;

#INT_SSP
void ssp_interupt ()
{
   state = i2c_isr_state();
  
   if(state < 0x80)                     //Master envia datos
   {
 if(state == 0){
incoming = i2c_read();
       }

      if(state == 1){                     //Direccion
        incoming = i2c_read();
address = incoming;
}
      if(state == 2){                     //Dato
        incoming = i2c_read();
        buffer[address] = incoming;
}
   }
   if(state == 0x80)                     //Master pide datos
   {
      i2c_write(buffer[address]);
   }
}


void main ()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);

   while (1);
}

« Última modificación: 13 de Junio de 2010, 09:23:35 por alcubo01 »

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: Aporte C18 18F4550 Codigo I2C + ADC + KEYB + LCD + RS232 Compatible Bootloader
« Respuesta #1 en: 08 de Noviembre de 2010, 15:55:52 »
El codigo del slave no esta compilado en picc sino en ccs creo. Puede ser? Estoy usando el Picc18... podria servirme?


 

anything