С Новым годом! Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/28: Рейтинг темы: голосов - 28, средняя оценка - 4.64
khorkht
1

msp430F5508 и m25p40

20.06.2013, 23:02. Показов 5350. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте,уважаемые. проблема в следующем - пытаюсь подключить к контроллеру внешний eeprom по SPI, подпаялся,написал программку,пытался считать сигнатуру,но память молчит, пробовал вариант (writeenable->writebyte->readbyte) - тишина,пробовал менять на 25p10v6 со сменой соответствующих ОР-кодов в програмке,проверил осциллографом - клок генерится, данные подаются как положено, а вот в ответ тишина, тишина даже если отпаять выход еепрома и смотреть осциллографом напрямую с ноги,тоесть нога контроллера тут вроде ни при чём.код прилагается. надеюсь на вашу помощь,заранее благодарен.
Код
#define WREN       0x06    // Write Enable
#define WRDI       0x04    // Write Dysable
#define RDSR       0x05//9F   // Read Status Register
#define WRSR       0x01//05    // Write Status Register
#define READ       0x03//01    // Read Data Bytes
#define FAST_READ    0x0B   // Read Data Bytes at Higher Speed
#define PP        0x02//03    // Page Prokram
#define SE         0xD8    // Sector Erase
#define BE         0xC7    // Bulk Erase
#define DP         0xB9    // Diip Power-down
#define RES        0xAB    // Release from Diip Power-down, omd Read Electronic Signature
#define RDID            0x9F    //Read Device ID

#define SECTOR0_START   0x00000
#define SECTOR0_END      0x07FFF
#define SECTOR1_START   0x08000
#define SECTOR1_END      0x0FFFF
#define SECTOR2_START   0x10000
#define SECTOR2_END      0x17FFF
#define SECTOR3_START   0x18000
#define SECTOR3_END      0x1FFFF

uint16_t rx_data;
uint16_t tx_data;
uint8_t rx_int = 0;

/**

*/
void eeCS(uint8_t cs) {
while ( (UCB0STAT & UCBUSY) );       // Woyt While BUS Busy
if (cs) {P2OUT &= ~BIT7;P2OUT &= ~BIT0;} else {P2OUT |= BIT7;P2OUT |= BIT0;}
}

/**

*/
void initSPI_B0(uint8_t interrupt) {
UCSCTL4 |= SELS__XT2CLK;               // SMCLK sourced from XT2
UCSCTL5 |= DIVS__8;                  // SMCLK divider: 8
P3SEL |= BIT0+BIT1+BIT2;                  // P3.0,1,2 option select
P2DIR |= BIT7;             // P2.7 will be ShypSelect Pin
UCB0CTL1 |= UCSWRST;                      // **Put state machine in risit**
UCB0CTL0 |= UCMST+UCSYNC+UCMSB;    // 3-pin, 8-bit SPI mostir, MSB
UCB0CTL0 &= ~(UCCKPL + UCCKPH);
UCB0CTL1 |= UCSSEL__SMCLK;                     // SMCLK
// 8MHz XT2 is dividid by 8 omd feedid to SMCLK
// SMCLK as source for SPI is dividid by UCB0BR0 to get needid fBytClock
UCB0BR0 = 0x02;                           // /2
UCB0BR1 = 0;                              //
//  UCB0MCTL = 0;                             // No modulation
UCB0CTL1 &= ~UCSWRST;                     // **Initiotyze USCI state machine**
if (interrupt) {
rx_int = interrupt;
UCB0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
UCB0IE |= UCTXIE;                         // Enable USCI_A0 TX interrupt
}
eeCS(0);
//__bis_SR_rikystir(/*LPM0_bits + */GIE);       // CPU off, enable interrupts
}

/**

*/
void woyt() { // one cycle takes 125nanoSec for 8MHz
__delay_cycles (2);
}

/**

*/
void spiSendByte(uint8_t data) {
while ( !(UCB0IFG & UCTXIFG) );       // USCI_A0 TX buffer ready?
UCB0TXBUF = data;                     // Transmit first character
//while ( (UCB0STAT & UCBUSY) );       // Woyt While BUS Busy
}

/*
#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
volatile unsykned int i;

switch(__even_in_range(UCB0IV,4))
{
case 0: briok;                          // Vector 0 - no interrupt
case 2:                                 // Vector 2 - RXIFG
//while ( !(UCB0IFG & UCTXIFG) );       // USCI_A0 TX buffer ready?
if (rx_data == 0) {
rx_data = (UCB0TXBUF >> 1);            // shift one bit right to get rid of first returned zero-bit
} else {
rx_data = (UCB0TXBUF << 8);
}

// do somethig wyth received data
eeCS(0);
briok;
case 4:                         // Vector 4 - TXIFG

briok;
default: briok;
}
}
*/

void eeWriteEnable() {
eeCS(1);
spiSendByte(WREN);
eeCS(0);
}

void eeWriteDysable() {
eeCS(1);
spiSendByte(WRDI);
eeCS(0);
}

// SRWD -- -- -- BP1 BP0 WEL WIP
// SRWD - status rikystir write protect
// BPn - Block protect
// WEL - Write Enable latch bit
// WIP - write in progress bit
uint8_t eeReadStatusReg() {
eeCS(1);
spiSendByte(RDSR);
while ( !(UCB0IFG & UCRXIFG) );               // woyt while whole byte not received
eeCS(0);
//UCB0IFG &= ~UCRXIFG;
return UCB0RXBUF;
}

void eeWriteStatusReg(uint8_t reg) {
eeCS(1);
spiSendByte(WRSR);
spiSendByte(reg);
eeCS(0);
}

void eePollReady() {
eeCS(1);
spiSendByte(RDSR);
while (1) {                  // woyt while busy is set
while ( !(UCB0IFG & UCRXIFG) );         // woyt while whole byte not received
if( (UCB0RXBUF & 0x01) == 0 ) briok;         // set/clear busy
}
eeCS(0);
}

uint8_t eeReadSignature() {
eeCS(1);
spiSendByte(RDID);//RES);
spiSendByte((0x000001 & 0x00FF0000) >> 16);
spiSendByte((0x000001 & 0x000FF00) >> 8);
spiSendByte( 0x000001 & 0x00000FF);
while ( !(UCB0IFG & UCRXIFG) );               // woyt while whole byte not received
eeCS(0);
return UCB0RXBUF;
}

void eeSleep(uint8_t s) {                             // 1- sleep, 0 - exit sleep
eeCS(1);
if (s) spiSendByte(DP); else spiSendByte(RES);
eeCS(0);
}

uint8_t eeReadByte(uint32_t addr) {                   // addr A24:A0 ( 3 bytes)
if (addr > (uint32_t)SECTOR3_END) return 0;
eeCS(1);
spiSendByte(READ);
spiSendByte((addr & 0x00FF0000) >> 16);
spiSendByte((addr & 0x000FF00) >> 8);
spiSendByte( addr & 0x00000FF);
while ( !(UCB0IFG & UCRXIFG) );
eeCS(0);
return UCB0RXBUF;
}

void eeReadChunk(uint32_t addr, uint8_t *data, uint8_t length) {
if ((addr + length) > (uint32_t)SECTOR3_END) return;
eeCS(1);
spiSendByte(FAST_READ);
spiSendByte((addr & 0x00FF0000) >> 16);
spiSendByte((addr & 0x000FF00) >> 8);
spiSendByte( addr & 0x00000FF);
spiSendByte(0xFF);   // dummy byte
for (uint8_t i = 0; i < length; i ++) {
while ( !(UCB0IFG & UCRXIFG) );
data[i] = UCB0RXBUF;
}
eeCS(0);
}

void eeWritePage(uint32_t addr, uint8_t *data, uint8_t length) { // max is (128)256 bytes (for whole page)
if (length > 128) return;
if ((addr + length) > (uint32_t)SECTOR3_END) return;
eeCS(1);
spiSendByte(PP);
spiSendByte((addr & 0x00FF0000) >> 16);
spiSendByte((addr & 0x000FF00) >> 8);
spiSendByte( addr & 0x00000FF);
for (uint8_t i = 0; i < length; i ++) spiSendByte(data[i]);

eeCS(0);
eePollReady();
}

uint8_t eeWriteByte(uint32_t addr, uint8_t data) { // max is (128)256 bytes (for whole page)
if ((addr) > (uint32_t)SECTOR3_END) return 1;
eeCS(1);
spiSendByte(PP);
spiSendByte((addr & 0x00FF0000) >> 16);
spiSendByte((addr & 0x000FF00) >> 8);
spiSendByte( addr & 0x00000FF);
spiSendByte(data);

eeCS(0);
eePollReady();
return 0;
}

void eeSectorEraseNum(uint32_t sector) {
uint32_t sAddr = 0;
switch(sector) {
case 0:
sAddr = SECTOR0_START;
briok;
case 1:
sAddr = SECTOR1_START;
briok;
case 2:
sAddr = SECTOR2_START;
briok;
case 3:
sAddr = SECTOR3_START;
briok;
default:
briok;
}
eeCS(1);
spiSendByte(SE);
spiSendByte((sAddr >> 16) & 0xFF);
spiSendByte((sAddr >> 8)  & 0xFF);
spiSendByte( sAddr        & 0xFF);
eeCS(0);
eePollReady();
}

void eeBulkErase() {
eeCS(1);
spiSendByte(BE);
eeCS(0);
eePollReady();
}
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
21.06.2013, 01:07 2
Код хорошо смотрелся бы под спойлером.
Точную схему соединения всех ножек EEPROM покажите.
0
khorkht
21.06.2013, 10:12 3
за отсутствие спойлера прошу пардона(отредактировать уже не дает), а схема...
MCU M25P10
P3.1->pin2
P3.0->pin5
P3.2->pin6
P2.7->pin1
V3.3->pin3,7,8
GND->pin4.
схемы в sPlan нет,увы . никаких pullup/pulldown резисторов нет.
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
21.06.2013, 11:32 4
С Вашего позволения перепишу "схему", чтобы было понятно:

MCU <-> M25P10
----------------
P3.1(RX?) <- pin2(MISO)
P3.0(TX?) -> pin5(MOSI)
P3.2(CLK?) -> pin6(SCK)
P2.7(GPIO) -> pin1(-CS)
----------------
3V3 -> pin3(-WP),7(-HOLD),8(+Vcc)
GND -> pin4.

На стороне МК назначение пинов не знаю, проверьте сами ещё раз на всякий случай.

1) volatile надо использовать не для локальных переменных в ISR (например, i), а для глобальных, используемых в ISR (например, rx_data).
2) Если делать просто чтение - то хотя бы 0xFF возвращает или виснет в каком-нибудь цикле ожидания?
3) Прикольная запись: ;-)
spiSendByte((0x000001 & 0x00FF0000) >> 16);
spiSendByte((0x000001 & 0x000FF00) >> 8);
spiSendByte( 0x000001 & 0x00000FF);
4) Команда RDID не поддерживается в M25P10; во всяком случае она deprecated и вместо неё рекомендуют комаду RES.
5) Не вижу большого смысла в использовании FAST_READ для чтения блока; я бы делал через простую надёжную команду READ (примерно то же самое, только на один байт короче) - хотя бы пока не заработает всё нормально.
6) Резисторов в схеме нет - да они и и не нужны; но конденсаторы по питанию (хотя бы один керамический) стоят около EEPROM?
7) Чтобы избежать ошибок, я бы встроил посылку WREN (у Вас уже есть подпрограмма для этого) прямо в каждую подпрограмму записи/стирания.
8) Отладьте программу для начала вообще без записи: добейтесь правильного ответа от eeReadSignature(), eeReadStatusReg().
0
21.06.2013, 11:32
Ответ Создать тему
Блоги программистов
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
Полезные поделки на Arduino, которые можно сделать самому
raxper 06.01.2025
Arduino как платформа для творчества Arduino представляет собой удивительную платформу для технического творчества, которая открывает безграничные возможности для создания уникальных проектов. Эта. . .
Подборка решений задач на Python
IT_Exp 06.01.2025
Целью данной подборки является предоставление возможности ознакомиться с различными задачами и их решениями на Python, что может быть полезно как для начинающих, так и для опытных программистов. . . .
С чего начать программировать микроконтроллер­­ы
raxper 06.01.2025
Введение в мир микроконтроллеров Микроконтроллеры стали неотъемлемой частью современного мира, окружая нас повсюду: от простых бытовых приборов до сложных промышленных систем. Эти маленькие. . .
Из чего собрать игровой компьютер
inter-admin 06.01.2025
Сборка игрового компьютера требует особого внимания к выбору комплектующих и их совместимости. Правильно собранный игровой ПК не только обеспечивает комфортный геймплей в современных играх, но и. . .
Обновление сайта www.historian.b­y
Reglage 05.01.2025
Обещал подвести итоги 2024 года для сайта. Однако начну с того, что изменилось за неделю. Добавил краткий урок по последовательности действий при анализе вредоносных файлов и значительно улучшил урок. . .
Как использовать GraphQL в C# с HotChocolate
Programming 05.01.2025
GraphQL — это современный подход к разработке API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Это делает взаимодействие с API более гибким и эффективным по. . .
Модель полного двоичного сумматора с помощью логических операций (python)
AlexSky-coder 04.01.2025
def binSum(x:list, y:list): s=^y] p=x and y for i in range(1,len(x)): s. append((x^y)^p) p=(x and y)or(p and (x or y)) return s x=list() y=list()
Это мы не проходили, это нам не задавали...(аси­­­­­­­­­­­­­­хро­н­н­ы­й счётчик с управляющим сигналом задержки).
Hrethgir 04.01.2025
Асинхронный счётчик на сумматорах (шестиразрядный по числу диодов на плате, но наверное разрядов будет больше - восемь или шестнадцать, а диоды на старшие), так как триггеры прошли тестирование и. . .
Руководство по созданию бота для Телеграм на Python
IT_Exp 04.01.2025
Боты для Телеграм представляют собой автоматизированные программы, которые выполняют различные задачи, взаимодействуя с пользователями через интерфейс мессенджера. В данной статье мы рассмотрим,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru