реклама на сайте
подробности

 
 
> msp430 + flash память
mib383
сообщение Jun 18 2012, 04:35
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 4-04-12
Пользователь №: 71 177



Всем привет.
Работаю с через i2c с флэшкой STMicroelectronics M24M02-DR, микроконтроллер msp430f47187, использую встроенный i2c модуль микроконтроллера. Режим master transmit/recieve
В двух словах принцип работы флэшки такой:
Запись (изначально модуль настроен на передачу (transmit)):
0. старт
1. отправить байт адреса устройства (это делает встроенный i2c модуль)
2. отправить 2 байта адреса записываемого байта (начала адреса записываемого массива байтов(страницы байтов)) по одному
3. Отправлять байты для записи
4. стоп
Флэшка может писать либо байтами либо страницами (<=256байт), после каждой записи запускается внутренний "Write cycle", который длится максимум 10 мс. На это время флеха отключается от i2c, а после можно продолжать с ней работу.

Чтение (изначально модуль настроен также на передачу (transmit)):
0.старт
1. отправить байт адреса устройства (это делает встроенный i2c модуль)
2. отправить 2 байта адреса по одному считываемого байта(байтов)
3. Перенастроить модуль на прием
4.старт
5. считывать байты (ловить прерывания ресивера)
6.стоп
Считывать можно как единичный байт, так и страницу.
Проблема состоит в следующем: после цикла чтения почему то в течении какого-то времени флешка не реагирует на команды, как будто опять включается WriteCycle (т.е. не получается продолжить работу сразу после чтения, а если поставить задержку те же 10 мс, все нормально). pdf читал внимательно, на несколько раз, все равно не нашел ошибку. Может кто сталкивался с таким...

Проверяю так: без дополнительной задержки: запись, чтение, запись(не работает)
с задержкой: запись, чтение, запись, чтение.... все работает

Судя по документации на флешку никаких задержек при чтении делать не нужно!!!!!

Исходный код (тактирование 16 МГц, оптимизации нет)
union MyFloat
{
float flt;
char b[4];
};

class CFlashMemory
{
public:
CFlashMemory(void);
void WriteFloat(unsigned long, float);
void ReadFloat(unsigned long, float&);
};

CFlashMemory::CFlashMemory(void)
{
UCB1CTL1 |= UCSWRST;// Enable SW reset
UCB1CTL0 = UCMODE_3 + UCMST + UCSYNC; // I2C Master, synchronous mode

UCB1CTL1 |= UCSSEL_2 + UCSWRST;// clock from SMCLK
UCB1BR0 = 0xa0; //freq = 100 kHz
UCB1BR1 = 0x0;

UCB1I2CSA = 80; // Slave Address is 0A0h where b7-b4(device type identifier):1010; b3(chip enable (grounded is scheme)):0; b2-b1(msb address bits): 00; b0(RW): 0

P2SEL |= BIT1 + BIT2;

UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
}
CFlashMemory FlashMemory = CFlashMemory();

void CFlashMemory::WriteFloat(unsigned long address, float f)
{
MyFloat temp;
temp.flt = f;
UCB1I2CSA = 80;
UCB1I2CSA |= (address&( (1uL<<16) + (1uL<<17) ))>>16;//specific of the device 1st MSB bits of address

UCB1CTL1 |= UCTR; // master transmitter mode
UCB1CTL1 |= UCTXSTT;//init start condition

while(!(UC1IFG & UCB1TXIFG));
UCB1TXBUF = (address>>8) & 0x000000ffuL;//MSB of address

while(!(UC1IFG & UCB1TXIFG));//wait 4 tx interrupt
UCB1TXBUF = address & 0x000000ffuL;//LSB of address

while(!(UC1IFG & UCB1TXIFG));//wait 4 tx interrupt
UCB1TXBUF = temp.b[0];//send byte 1
while(!(UC1IFG & UCB1TXIFG));
UCB1TXBUF = temp.b[1];//send byte 2
while(!(UC1IFG & UCB1TXIFG));//wait 4 tx interrupt
UCB1TXBUF = temp.b[2];//send byte 3
while(!(UC1IFG & UCB1TXIFG));//wait 4 tx interrupt
UCB1TXBUF = temp.b[3];//send byte 4
while(!(UC1IFG & UCB1TXIFG));//wait 4 tx interrupt
UCB1CTL1 |= UCTXNACK;
UCB1CTL1 |= UCTXSTP;//init stop condition
UC1IFG &= ~UCB1TXIFG;
__delay_cycles(160000);
}


void CFlashMemory::ReadFloat(unsigned long address, float &f)
{
MyFloat temp;
UCB1I2CSA = 80;
UCB1I2CSA |= address&((1uL<<16)+(1uL<<17))>>16;//specific of the device 1st MSB bits of address

UCB1CTL1 |= UCTR; // master transmitter mode
UCB1CTL1 |= UCTXSTT;//init start condition
while(!(UC1IFG & UCB1TXIFG));//wait 4 tx interrupt

UCB1TXBUF = (address>>8) & 0x000000ffuL;//MSB of address
while(!(UC1IFG & UCB1TXIFG));//wait 4 tx interrupt

UCB1TXBUF = address & 0x000000ffuL;//LSB of address
while(!(UC1IFG & UCB1TXIFG));//wait 4 tx interrupt
UC1IFG &= ~UCB1TXIFG;

UCB1CTL1 &= ~UCTR; // master reciever mode
UCB1CTL1 |= UCTXSTT;//init start condition

while(!(UC1IFG & UCB1RXIFG));//wait 4 rx interrupt
temp.b[0] = UCB1RXBUF;//read byte 0
UC1IFG &= ~UCB1RXIFG;

while(!(UC1IFG & UCB1RXIFG));//wait 4 rx interrupt
temp.b[1] = UCB1RXBUF;//read byte 1
UC1IFG &= ~UCB1RXIFG;
while(!(UC1IFG & UCB1RXIFG));//wait 4 rx interrupt
temp.b[2] = UCB1RXBUF;//read byte 2
UC1IFG &= ~UCB1RXIFG;
while(!(UC1IFG & UCB1RXIFG));//wait 4 rx interrupt
temp.b[3] = UCB1RXBUF;//read byte 3
UC1IFG &= ~UCB1RXIFG;

//while(!(UC1IFG & UCB1RXIFG));//wait 4 rx interrupt
UCB1CTL1 |= UCTXSTP;//init stop condition

f = temp.flt;
//__delay_cycles(160000);//??????????????????????????????????????????????
}

Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Jun 18 2012, 06:16
Сообщение #2


Гуру
******

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



QUOTE (mib383 @ Jun 18 2012, 07:35) *
после цикла чтения почему то в течении какого-то времени флешка не реагирует на команды, как будто опять включается WriteCycle
Не вижу посылки NACK в ответ на последний считанный байт. В процессе передачи вижу (там она вроде как и лишняя и не к месту), а в приеме - не вижу. Не к месту - потому что взводить NACK надо перед приемом последнего байта или во время приема, но никак не после. Странно, что помогает задержка.

P.S. используйте кнопку оформления кода для публикации коротких исходников и теги [ codebox ] [ /codebox ] для длинных.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
mib383
сообщение Jun 18 2012, 07:32
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 4-04-12
Пользователь №: 71 177



Цитата(Сергей Борщ @ Jun 18 2012, 13:16) *
Не вижу посылки NACK в ответ на последний считанный байт. В процессе передачи вижу (там она вроде как и лишняя и не к месту), а в приеме - не вижу. Не к месту - потому что взводить NACK надо перед приемом последнего байта или во время приема, но никак не после. Странно, что помогает задержка.

P.S. используйте кнопку оформления кода для публикации коротких исходников и теги [ codebox ] [ /codebox ] для длинных.

NACK перед(сразу после приема предпоследнего) и после приема последнего байта пробовал, не помогает.
И в документации на msp написано, что если МК настроен на ресив, то перед стоп состоянием он генерит NACK

Сообщение отредактировал mib383 - Jun 18 2012, 08:08
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 06:06
Рейтинг@Mail.ru


Страница сгенерированна за 0.01391 секунд с 7
ELECTRONIX ©2004-2016