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

 
 
> 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



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

 


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


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