Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: MSP430F149 + SPI EEPROM AT25256
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
Vladimir_T
Здравствуйте, уважаемые коллеги, для ведения журнала и записи в него массива измерительной информации подключил к 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 кГц.
Vladimir_T
Спасибо всем за соучастие. Сейчас память работает. Ошибка была у меня: при стробировании байта данных при приеме не дожидался флага URXIFG0.
Но ведь режим что Atmel приводит, не идет! Идет SPI mode 0,1.
rezident
Используйте SPI Mode 3, он более универсальный для большинства типов EEPROM и DataFlash.
А если вы хотите узнать, где у вас ошибка в программе, то приведите исходник вашей программы.
Vladimir_T
Вот привожу кусочек проекта с функциями для работы с 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 ();

}
Сергей Борщ
Цитата(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. Там написано, для чего и как использовать флаги окончания передачи и освобождения буфера.
Vladimir_T
Цикл записи для AT25256 может достигать 5 мсек - это довольно медленная память, а для FRAM FM25W256 это время - нулевое.
Сергей Борщ
Цитата(Vladimir_T @ Sep 2 2008, 11:30) *
Цикл записи для AT25256 может достигать 5 мсек - это довольно медленная память, а для FRAM FM25W256 это время - нулевое.
И как вам прерывание SPI сообщит об окончании цикла записи? Оно даст отмашку об окончании обмена, а конец записи вам все равно надо будет отлавливать периодическим чтением статуса памяти. Хотя, если вы этот опрос тоже повесите на прерывание, работать будет. Но 50% времени при этом процессор будет занят входом/выходом из прерывания. Ибо он еще не успеет выйти из текущего прерывания, как уже возникнет следующее. Так есть ли смысл использовать прерывания в этом случае вообще?
Vladimir_T
Вы абсолютно правы, не видно особого выигрыша чтобы делать обработку цикла записи с использованием прерываний, да и писать в EEPROM нужно лишь поминутно, это в режиме тестирования, и по часам в штатном режиме. Можно для ускорения работы писать блоками.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.