Autor Tema: Eeprom SPI, problemas al escribir una pagina, se salta direcciones.  (Leído 1571 veces)

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

Desconectado PHLAKO

  • PIC10
  • *
  • Mensajes: 49
Hola foreros, primero que todo, felicito y doy las gracias a aquellas personas que aportan sus conocimientos en este foro, en particular del hilo: "Cursillo en C18 para PICS DESDE CERO". Me ha ayudado un monton en la migracion de ASM a C. Mi problema es el siguiente:

Ocupando la libreria spi.h del libro de microchip "MPLAB® C18 C COMPILER LIBRARIES", conecte la memoria 25LC640 al 18f452, cambie el largo de los arreglos para que escribiese una pagina de 32bytes, en vez de 16bytes que sale en el ejemplo del libro, ademas de hacer length=count, ya que en la libreria *.c, hace referencia a un length, pero debe ser el valor del count.

Al escribir 32B desde la direccion 0080 escribe lo siguiente:


lo cual esta bien, ahora el problea es que si cambio la direccion desde donde empezara a escribir a la 00B0, escribe lo siguiente:


si se fijan, comienza a escribir bien, desde la direccion 00B0, pero al completar 16Bytes, en vez de seguir en la direccion 00C0, retrocede y escribe los ultimos 16Bytes desde la direccion 00A0  :shock:

otro dato, en las direcciones 0000, 0020, 0040, 0060, 0080, etc. escribe bien, pero en el resto ocurre este problema :(

Pues bien, al debugearlo paso a paso, veo que carga la direccion inicial y todo lo que he probado, ocurre como se espera.

Ojala alguien me de una lucecita de por donde seguir buscando. Les dejo el codigo:

#include <p18f452.h>
#include <spi.h>

#pragma config OSC = HSPLL
#pragma config OSCS = ON //pll de osc
#pragma config PWRT = ON
#pragma config BOR = OFF //brown-out reset, BORV = 45 brown-out voltaje (4.5v)
#pragma config WDT = OFF //WDTPS = 1, postscaler 1:1
#pragma config CCP2MUX = OFF
#pragma config LVP = OFF,DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF,CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF
#pragma config EBTRB = OFF

// FUNCTION Prototypes
void set_wren(void);
void busy_polling(void);
unsigned char status_read(void);
void status_write(unsigned char data);
void byte_write(unsigned char addhigh,unsigned char addlow,unsigned char data);
void page_write(unsigned char addhigh,unsigned char addlow,unsigned char *wrptr);
void array_read(unsigned char addhigh,unsigned char addlow,unsigned char *rdptr,unsigned char count);
unsigned char byte_read(unsigned char addhigh,unsigned char addlow);

void READMEM( unsigned char *rdptr, unsigned char length );


// VARIABLE Definitions
unsigned char arrayrd[32];
unsigned char arraywr[] = {'A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B',0};

unsigned char var;
unsigned char wrptr;
unsigned char rdptr;
unsigned char addhigh;
unsigned char addlow;
unsigned char count;
unsigned char length;

#define SPI_CS LATCbits.LATC2
//**************************************************
void main(void)
{
   TRISA = 0X00;
   TRISB = 0b11101111;
   TRISC = 0b10010011;
   TRISD = 0b11111111;

   PORTA = 0b00000000;
   PORTB = 0b00000000;
   PORTC = 0b00000000;
   PORTD = 0b00000000;
   
   LATA = 0X00;
   LATB = 0X00;
   LATC = 0X00;
   LATD = 0X00;
   
   SPI_CS = 1; // ensure SPI memory device
            // Chip Select is reset

   OpenSPI(SPI_FOSC_16, MODE_00, SMPEND);

   set_wren();

   page_write(0x00, 0xB0, arraywr);

   busy_polling();
   array_read(0x00,0xB0,arrayrd,32);
   var = status_read();

   CloseSPI();

   while(1);
}
//********************************************************************************
   void set_wren(void)
   {
   SPI_CS = 0; //assert chip select
   var = putcSPI(SPI_WREN); //send write enable command
   SPI_CS = 1; //negate chip select
   }
   void page_write (unsigned char addhigh,unsigned char addlow,unsigned char *wrptr)
   {
   SPI_CS = 0; //assert chip select
   var = putcSPI(SPI_WRITE); //send write command
   var = putcSPI(addhigh); //send high byte of address
   var = putcSPI(addlow); //send low byte of address
   putsSPI(wrptr); //send data byte
   SPI_CS = 1; //negate chip select
   }
   void array_read (unsigned char addhigh,   unsigned char addlow,unsigned char *rdptr,unsigned char count)
   {
   SPI_CS = 0; //assert chip select
   var = putcSPI(SPI_READ); //send read command
   var = putcSPI(addhigh); //send high byte of address
   var = putcSPI(addlow); //send low byte of address
   length = count;
   getsSPI(rdptr, count); //read multiple bytes
   SPI_CS = 1;
   }
   void byte_write (unsigned char addhigh,unsigned char addlow,unsigned char data)
   {
   SPI_CS = 0; //assert chip select
   var = putcSPI(SPI_WRITE); //send write command
   var = putcSPI(addhigh); //send high byte of address
   var = putcSPI(addlow); //send low byte of address
   var = putcSPI(data); //send data byte
   SPI_CS = 1; //negate chip select
   }
   unsigned char byte_read (unsigned char addhigh,unsigned char addlow)
   {
   SPI_CS = 0; //assert chip select
   var = putcSPI(SPI_READ); //send read command
   var = putcSPI(addhigh); //send high byte of address
   var = putcSPI(addlow); //send low byte of address
   var = getcSPI(); //read single byte
   SPI_CS = 1;
   return (var);
   }
   unsigned char status_read (void)
   {
   SPI_CS = 0; //assert chip select
   var = putcSPI(SPI_RDSR); //send read status command
   var = getcSPI(); //read data byte
   SPI_CS = 1; //negate chip select
   return (var);
   }
   void status_write (unsigned char data)
   {
   SPI_CS = 0;
   var = putcSPI(SPI_WRSR); //write status command
   var = putcSPI(data); //status byte to write
   SPI_CS = 1; //negate chip select
   }
   void busy_polling (void)
   {
      do
      {
      SPI_CS = 0; //assert chip select
      var = putcSPI(SPI_RDSR); //send read status command
      var = getcSPI(); //read data byte
      SPI_CS = 1; //negate chip select
      }
       while (var & 0x01); //stay in loop until !busy
    }

Bueno, eso es todo, ojala me ayuden, ya que he estado 2 dias en esto, antes de postearlo aqui.

Saludos,

chaos :)
SIEMPRE TE RECORDARE AMADO Y FIEL COMPAÑERO "LOBO"

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Eeprom SPI, problemas al escribir una pagina, se salta direcciones.
« Respuesta #1 en: 29 de Enero de 2009, 17:54:02 »
Citando la hoja de características de la memoria 25LC640:



Dice que para hacer escrituras de página debes comenzar en XXX0 0000 y terminar en XXX1 1111.

Si envías un 0x00B0 el byte bajo equivale a 1011 0000, lo cual no cumple con lo que pide la especificación.

Cuando envías lo siguiente, sí cumple con la especificación:

0x00A0 = 1010 0000
0x0000 = 0000 0000
0x0020 = 0010 0000
0x0040 = 0100 0000

Otro que no cumpliría con la especificación sería:

0x0010 = 0001 0000

Cuida que addlow siempre tenga los bits 4, 3, 2, 1 y 0 iguales a cero para cualquier escritura de página.
« Última modificación: 29 de Enero de 2009, 17:56:04 por migsantiago »

Desconectado PHLAKO

  • PIC10
  • *
  • Mensajes: 49
Re: Eeprom SPI, problemas al escribir una pagina, se salta direcciones.
« Respuesta #2 en: 30 de Enero de 2009, 10:32:55 »
Estimado migsantiago, gracias por la aclaracion, error de mi parte, pasar por alto el datasheet, juste ese parrafo que citas, esta clarito.  gracias a esto, respiro tranquilo :mrgreen:, ya me estaba preocupando por no encontrar el error en el codigo.

Saludos y sigo explorando el lenguaje C. :-/

chaos :)
SIEMPRE TE RECORDARE AMADO Y FIEL COMPAÑERO "LOBO"