logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Flash + Atmega. Czy coś jest nie tak w adresowaniu?

EU07-210 17 Lip 2007 00:09 1803 2
REKLAMA
  • #1 4088115
    EU07-210
    Poziom 10  
    Posty: 8
    Witam

    Mam połączoną pamięć Flash AT45db161b z uP Atmega128.
    W poniższym programie dokonuje zapisu liczby 0x44 do Flash'a, jednak gdy potem odczytuję pamięć to zz=0xFF
    Czy coś może być nie tak w adresowaniu ? (od razu mówię, że jestem początkującym programistą uP i połączenie Flash'a z uP jest raczej ok)

    
    #include <avr/io.h>
    
    #define PORT_SPI PORTB
    #define DDR_SPI  DDRB
    #define SS       PB0
    #define BUFFER_1_WRITE 0x84
    #define BUFFER_2_WRITE 0x87
    #define B1_TO_MM_PAGE_PROG_WITHOUT_ERASE 0x88
    #define MM_PAGE_TO_B1_XFER 0x53
    #define BUFFER_1_READ 0x54
    
    void write_data(unsigned char x);
    unsigned char read_data(void);
    void Master_init(void);
    void write_SPI(unsigned char x);	
    
    int main(void)
    {
     unsigned char zz=0x00;
      
     Master_init();
     write_data(0x44);
     zz=read_data();
    	
     return 0;
    }
    
    void Master_init(void)
    {	
      /* Set MOSI, SCK and SS output, all others input */
      DDR_SPI = 0x07;
      PORT_SPI=0xFF;
      /* Enable SPI, Master, set clock rate fck/16 */
      SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
    }	
    
    
    void write_data(unsigned char x)
    {
      while(!(PINB & 0x10));	//sprawdza RDY-BUSY
      PORT_SPI &= ~(1<<SS);          //zeruje CS
      write_SPI(BUFFER_1_WRITE);  //zapis danych do bufora 1
      write_SPI(0x00);
      write_SPI(0x00);
      write_SPI(0x00);
      write_SPI(x);
      PORT_SPI |=(SS<<1); //ustawia CS 
    
      while(!(PINB & 0x10));	//sprawdza RDY-BUSY
      PORT_SPI &= ~(1<<SS);          //zeruje CS
      write_SPI(B1_TO_MM_PAGE_PROG_WITHOUT_ERASE);  //zapis danych z bufora 1 do FLASH
      write_SPI(0x00);
      write_SPI(0x00);
      write_SPI(0x00);
      PORT_SPI |=(SS<<1); //ustawia CS
    
    }
    
    
    void write_SPI(unsigned char x)
    {
      /* Start transmission */
      SPDR = x;
      /* Wait for transmission complete */
      while(!(SPSR & (1<<SPIF)));
    }
    
    
    unsigned char read_data(void)
    {
      unsigned char data;  
    
      while(!(PINB & 0x10));	//sprawdza RDY-BUSY
      PORT_SPI &= ~(1<<SS);          //zeruje CS
      write_SPI(MM_PAGE_TO_B1_XFER);  //odczyt z FLASH do bufora 1
      write_SPI(0x00);
      write_SPI(0x00);
      write_SPI(0x00);
      PORT_SPI |=(SS<<1); //ustawia CS 
    
      while(!(PINB & 0x10));	//sprawdza RDY-BUSY
      PORT_SPI &= ~(1<<SS);          //zeruje CS
      write_SPI(BUFFER_1_READ);  //odczyt z bufora 1
      write_SPI(0x00);
      write_SPI(0x00);
      write_SPI(0x00);
      write_SPI(0x00);
      
      data=SPDR;
      
      PORT_SPI |=(SS<<1); //ustawia CS 
    
      return data;
    }
    
  • REKLAMA
  • #2 4090279
    nojmi
    Poziom 20  
    Posty: 473
    Pomógł: 9
    Ocena: 18
    Ja na Twoim miejscu najpierw sprawdził bym komunikacje po SPI. Odczytaj status (opcode = 57H) i sprawdź czy odpowie prawidłowo:
    - bity 2,3,4,5 = 1 1 0 1

    Coś mi się wydaje, że masz ustawiony tryb 0 SPI (CPOL = 0 i CPHA = 0) i dobierasz do niego błędne opcody z "SCK Mode" dla odczytu.
    Czyli:
    #define BUFFER_1_READ 0xD4
    a dla statusu 0xD7

    Daj znać czy dałeś radę uruchomić, bo planuje na czasie sam się za tego flacha zabrać.
    A tak w ogóle to jakie korzyści daje ładowanie pamięci przez bufor?
  • #3 4091425
    EU07-210
    Poziom 10  
    Posty: 8
    Nie wiem jakie są korzyści ładowania przez bufor (możliwe że jest to szybsze , bo nie zajmuje tak długo magistrali).

    Problem rozwiązałem na razie w ten sposób, że zapełniam cały bufor liczbami 0x44, przesyłam to do main page, a potem odczytuję przez bufor któryś z elementów pamięci flash (odczytuję poprawną wartość 0x44). Zmieniłem też ustawienia rejestru SPCR.



    #include <avr/io.h>
    #include <avr/wdt.h>
    
    #define PORT_SPI PORTB
    #define DDR_SPI  DDRB
    #define SS       PB0
    #define BUFFER_1_WRITE 0x84
    #define BUFFER_2_WRITE 0x87
    #define BUFFER_1_READ 0x54
    #define MAIN_MEM_READ 0x52
    #define MM_PAGE_TO_B1_XFER 0x53
    #define B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83
    
    void write_data(unsigned char x);
    unsigned char read_data(void);
    void Master_init(void);
    void write_SPI(unsigned char x);	
    
    int main(void)
    {
     unsigned char zz;
    
     wdt_enable(WDTO_2S);
     Master_init();
     wdt_reset();
     write_data(0x44);
     zz=read_data();
     
     while(1)
     {
     	wdt_reset();
     }	
     return 0;
    }
    
    
    unsigned char read_data(void)
    {   
        unsigned int buffer_counter=528;
    	unsigned char data=0x00;
    
    	// zapis z main mem do buforu 1 
    	while(!(PINB & 0x10));  //czy zajety
    	wdt_reset();
    	PORT_SPI &= ~(1<<SS);	//ustawienie CS/ w stan niski	
    	write_SPI(MM_PAGE_TO_B1_XFER); //przeslanie do bufora1 z FLASH
    	write_SPI(0x00);
        write_SPI(0x00);
        write_SPI(0x00);
        PORT_SPI |=(1<<SS);
    
    
    	while(!(PINB & 0x10));  //czy zajety
    	wdt_reset();
        PORT_SPI &= ~(1<<SS);
    	write_SPI(BUFFER_1_READ); //przeslanie z bufora do zmiennej
    	write_SPI(0x00);
        write_SPI(0x00);
        write_SPI(0x00);
        write_SPI(0x00);
    	/*
         do
         {
          write_SPI(0xFF);               // write dummy value to start register shift    
    	  wdt_reset();                    
          data = SPDR;                       // play data from shift register              
         }while (--buffer_counter); 
    */
    	write_SPI(0xFF);
    	data=SPDR;
    	PORT_SPI |=(1<<SS); //ustawia CS na 1 	 
    	return data;
    }
    
    
    
    void Master_init(void)
    {	
    /* Set MOSI, SCK and SS output, all others input */
    DDR_SPI = 0x07;
    PORT_SPI=0xFF;
    
    SPCR=0x5C;
    }	
    
    void write_SPI(unsigned char x)
    {
     /* Start transmission */
    SPDR = x;
    /* Wait for transmission complete */
    while(!(SPSR & (1<<SPIF)));
    }
    
    void write_data(unsigned char x)
    {
      int i;	
      unsigned int buffer_counter=0;
      for (i=0;i<529; i++) 
      {
      	while(!(PINB & 0x10));	//sprawdza RDY-BUSY
      	wdt_reset();
      	PORT_SPI &= ~(1<<SS);          //zeruje CS
      	write_SPI(BUFFER_1_WRITE);
      	write_SPI(0x00);
      	write_SPI((char)(buffer_counter>>8));
      	write_SPI((char)buffer_counter);
      	write_SPI(x);
      	PORT_SPI |=(1<<SS); //ustawia CS na 1
    	buffer_counter++; 
      }
      //zapis z bufora do FLASH
      while(!(PINB & 0x10)); 
      wdt_reset();
      PORT_SPI &= ~(1<<SS);
      write_SPI(B1_TO_MM_PAGE_PROG_WITH_ERASE);
      write_SPI(0x00);
      write_SPI(0x00);
      write_SPI(0x00);
      PORT_SPI |=(1<<SS);
    }
    
    
REKLAMA