|
|
  |
MSP430F149 + SPI EEPROM AT25256 |
|
|
|
Sep 1 2008, 06:26
|
Знающий
   
Группа: Свой
Сообщений: 517
Регистрация: 7-02-06
Пользователь №: 14 073

|
Здравствуйте, уважаемые коллеги, для ведения журнала и записи в него массива измерительной информации подключил к MSP430F149 память AT25256, которая должна работать в режиме SPI mode 0,0. Но в этом режиме она не работает: регистр состояния RS всегда нулевой, а когда ставишь U0TCTL = CKPH + SSEL1 + STC; // Polarity = Lo, 3-wire или U0TCTL = CKPL + SSEL1 + STC; // Polarity = HI, 3-wire
тогда профодят команды, с кодами WREN, WRDI, BP0, BP1 и в статус-регистре вижу состояние битов WEN, BP0, BP1. Цикл записи проходит, т.к. WEN сбрасывается по окончании цикла запись. Но команды чтения данных из ячейки не идут. А может и запись не идет, т.к. вычитываю из ячеек всегда нули. А какие данные должны быть в чистой м/с AT25256: 0x00 или 0xff? Почему может быть нестыковка? Временные диаграммы в норме, частота CLK = 240 кГц.
|
|
|
|
|
Sep 2 2008, 06:19
|
Знающий
   
Группа: Свой
Сообщений: 517
Регистрация: 7-02-06
Пользователь №: 14 073

|
Вот привожу кусочек проекта с функциями для работы с EEPROM/FRAM. В этом коде все работает. В следующей реализвции проекта, циклы ожидания флагов будут не нужны, т.к. работа с SPI будет по прерываниям от приемо/передатчика SPI. Хотел спросить по емкости буфера для передачи: на блок-схеме и в даташите MSP430F149 говорится об буфере передатчика, но какого размера он - не пишут. По моему - это просто буферный регистр, потому, что если засылать всего несколько байт подряд, то многие теряются.
// Bits of Status Register FRAM #define SR_RDY (BIT0) #define SR_WEN (BIT1) #define SR_BP0 (BIT2) #define SR_BP1 (BIT3) #define SR_WPEN (BIT7)
// Op-Code Commands of the chip FRAM #define OCC_WREN 0x06 // Set Write Enable Latch #define OCC_WRDI 0x04 // Write Disable #define OCC_RDSR 0x05 // Read Status Registr #define OCC_WRSR 0x01 // Write Status Registr #define OCC_READ 0x03 // Read from Memory #define OCC_WRITE 0x02 // Write to Memory
#define EN_FRAM (BIT7) //From P5 #define NoSel_FRAM P5OUT |= EN_FRAM #define Sel_FRAM P5OUT &= ~EN_FRAM
//****************************************************************************** // Init SPI //****************************************************************************** void Init_SPI (void) { P3SEL |= 0x0E; // P3.1,2,3 SPI option select U0CTL = CHAR + SYNC + SWRST + MM; // 8-bit, SPI U0TCTL = SSEL1 + STC + CKPH ; // Polarity = Lo, 3-wire Tmp = U0TCTL; U0BR0 = 0x02; // SPICLK = SMCLK/2 U0BR1 = 0x00; U0MCTL = 0x00; ME1 |= USPIE0; // Module enable U0CTL &= ~SWRST; // SPI enable } // Init SPI
//****************************************************************************** // Initialize SPI for FRAM //****************************************************************************** void FM25W_Init (void) {
NoSel_FRAM; // CS = HI disable FRAM Init_SPI ();
} // FM25W_Init (void)
//****************************************************************************** // Transfer Data from SPI. Wait becouse transfer is no finished //****************************************************************************** void SPI_Transfer (unsigned char Data) { TXBUF0 = Data; while ( !( U0TCTL & TXEPT )) ; // îæèäàíèå çàâåðøåíèÿ ïåðåäà÷è } //SPI_Transfer (unsigned char Data)
//****************************************************************************** // Read Data from SPI. Wait becouse read is no finished //****************************************************************************** unsigned char SPI_Read (void) { U0IFG &= ~URXIFG0; TXBUF0 = 0x00; // îáåñïå÷åíèå òàêòèðîâàíèÿ while ( !( U0IFG & URXIFG0 )) ; // Waiting for URXIFG0 return( U0RXBUF ); // âîçâðàùàåì ñîäåðæèìîå áóôåðà ïðè¸ìà }
//****************************************************************************** // WREN cycle must be first before any Write cycle to the FRAM //****************************************************************************** void FM25W_SR_WREN (void) { Sel_FRAM; // CS = Lo enable FRAM SPI_Transfer (OCC_WREN); NoSel_FRAM; // CS = HI disable FRAM }
//****************************************************************************** // WRDI cycle //****************************************************************************** void FM25W_SR_WRDI (void) { Sel_FRAM; // CS = Lo enable FRAM SPI_Transfer (OCC_WRDI); NoSel_FRAM; // CS = HI disable FRAM }
//****************************************************************************** // Write OP_Code to the FRAM //******************************************************************************
void FM25W_SR_WR (unsigned char Date) { FM25W_SR_WREN (); // Send WREN
Sel_FRAM; // CS = Lo enable FRAM SPI_Transfer (OCC_WRSR); // Send Op Code RDSR SPI_Transfer (Date); NoSel_FRAM; // CS = HI disable FRAM } // FM25W_SR_WR ()
//****************************************************************************** // Read Ststus Register of FRAM from SPI. Wait becouse read is not finished //****************************************************************************** unsigned char FM25W_SR_RD (void) { unsigned char Data;
Sel_FRAM; // CS = Lo enable FRAM SPI_Transfer (OCC_RDSR); Data = SPI_Read (); NoSel_FRAM; // CS = HI disable FRAM
return (Data); }
//****************************************************************************** // Write Data to memory FRAM // !!! Only one optocode per cycle enable CS //****************************************************************************** void FM25W_WR (unsigned int Address, unsigned char Data ) { FM25W_SR_WREN (); // Send WREN
Sel_FRAM; // CS = Lo enable FRAM TXBUF0 = OCC_WRITE; SPI_Transfer (Address >> 8); // Set HI Address SPI_Transfer (Address); // Set LO Address SPI_Transfer (Data); // Set Data NoSel_FRAM; // CS = HI disable FRAM, start program cycle do Tmp = FM25W_SR_RD (); while (Tmp & SR_RDY); // Wait finish for program cycle } //FM25W_WR
//****************************************************************************** // Read Data from memory FRAM //****************************************************************************** unsigned char FM25W_RD (unsigned int Address) { unsigned char Data; Sel_FRAM; // CS = Lo enable FRAM SPI_Transfer (OCC_READ); SPI_Transfer (Address >> 8); // Set HI Address SPI_Transfer (Address); // Set LO Address Data = SPI_Read (); NoSel_FRAM; // CS = HI disable FRAM return ( Data ); // âîçâðàùàåì ñîäåðæèìîå áóôåðà ïðè¸ìà
} //FM25W_RD
int main () {
for (Ind =0; Ind < 0x8000; Ind ++) FM25W_WR (Ind, Ind); for (Ind =0; Ind < 0x8000; Ind ++) D_FRAM[Ind] = FM25W_RD (Ind); T = FM25W_SR_RD ();
}
|
|
|
|
|
Sep 2 2008, 06:48
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Vladimir_T @ Sep 2 2008, 09:19)  Вот привожу кусочек проекта с функциями для работы с EEPROM/FRAM. Пожалуйста, используйте для оформления кода теги [ code ] (кнопочка # в форме ввода). Без форматирования исходники очень тяжело читать, и желание читать, а следовательно и разобраться в таком коде, чаще всего пропадает. Цитата(Vladimir_T @ Sep 2 2008, 09:19)  В следующей реализвции проекта, циклы ожидания флагов будут не нужны, т.к. работа с SPI будет по прерываниям от приемо/передатчика SPI. Насколько я помню, интерфейс памяти довольно быстрый и в идеале все ожидание выливается в два-четыре NOP, что гораздо короче, быстрее и удобнее, чем обработка прерываний от SPI. Цитата(Vladimir_T @ Sep 2 2008, 09:19)  в даташите MSP430F149 говорится об буфере передатчика, но какого размера он - не пишут. По моему - это просто буферный регистр, потому, что если засылать всего несколько байт подряд, то многие теряются. В даташите довольно скудная информация. Посмотрите User Guide, там все расписано более подробно и с картинками. Цитата(Vladimir_T @ Sep 2 2008, 09:19)  если засылать всего несколько байт подряд, то многие теряются Прочитайте User Guide. Там написано, для чего и как использовать флаги окончания передачи и освобождения буфера.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|