DVyacheslavN Опубликовано 16 апреля, 2014 Поделиться Опубликовано 16 апреля, 2014 Товарищи, прошу помощи , несколько недель мучаюсь с организацией совместной работы карты памяти ММС и микроконтроллера pic 16f877. излазил кучу форумов . Задача стоит такая надо разобраться в алгоритме работы с картой памяти (запись, чтение. и тд.), не надо подсовывать алгоритмы с разных сайтов если не знаете что там и где . С библиотекой Petit FatFs не совсем разобрался в файле diskio.c необходимо прописать низкоуровневую работу(пока туда не лез). Предлагаю вашему вниманию часть программы, программа компилируется и записывает только 512 байт (1 блок) , при записи нескольких блоков записывает пробелы . Проверял в Протеусе, схему не собирал. 1) вопрос как организовать запись нескольких блоков да и комарду CMD 23 (только для ММС) Распишите . #include <pic.h> #define _XTAL_FREQ 20e6 extern void SerString (const char *str); extern char SPI (char d); extern char Command (char befF,/*unsigned char AdrH,*/ unsigned char AdrL,char befH ); extern char bhf ; char df=0; void read (); void write ( char x) { if (Command(24, 0, 0xff)!=0) { SerString("Write Error"); } SerString ("writing mmc"); //while (SPI(0xFF)!=0) ; SPI (0xff); SPI (0xff); SPI (0xfe); for (int g =0; g< 512; g++){ SPI ('f'); } SPI (0xff); SPI (0xff); while ((SPI(0xff) | 0b00011111) == 0x05); while (SPI(0xff) != 0xff); //for (char i=0; i<100 ;i++); SerString("writi complit"); } void read (){ char i; if (Command(0x51,512,0xFF) !=0) SerString("Lese_resp_Fehler "); while(SPI(0xFF) != 0xFE); // Ожидание 0xFE – начала каждой передачи данных for(i=0; i < 512; i++) { while(!TXIF); // Проверка, пуст ли регистр TXREG TXREG =SPI(0xFF); // Передача байта данных } SPI(0xFF); // В конце два незначимых байта SPI(0xFF); } Забыл добавить с кодом программы уже экспериментировал много так что он может немножко корявый. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 17 апреля, 2014 Автор Поделиться Опубликовано 17 апреля, 2014 Чтобы было проще разобраться предлагаю посмотреть следующий материал http://piclist.ru/S-64MMC-PIC-RUS/S-64MMC-PIC-RUS.html 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
DVyacheslavN Опубликовано 17 апреля, 2014 Автор Поделиться Опубликовано 17 апреля, 2014 вот еще интересный фрагмент кода . если кто то его может пояснить то прошу не скромничать. void write() { pwm_disable(); command(25, arg, 0xff); while (readdata != 0) { spi_read(); string("WRITE ERROR"); } string("WRITING MMC"); while (1) { spi_write(0xff); spi_write(0xff); spi_write(0b11111100); for (int g = 0; g < 512; g++) { char GO = 1; while (GO); spi_write(ADRESL); PORTD = ~ADRESL; } spi_write(0xff); spi_write(0xff); spi_read(); while ((readdata | 0b00011111) != 0x05) { spi_read(); } while (readdata != 0xff) { spi_read(); } if (RE0 == 1) { spi_write(0xff); spi_write(0xff); spi_write(0b11111101); //stop token spi_read(); spi_read(); while (readdata != 0xff) { spi_read(); } break; } } } вобще код достаточно понятный писал похожий только вот при симуляции в протеусе в файл карты (с расширением ММС. записывает одни пробелы.) Может проблема в Протеусе, 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Особенности хранения литиевых аккумуляторов и батареекПотеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
DVyacheslavN Опубликовано 1 мая, 2014 Автор Поделиться Опубликовано 1 мая, 2014 крик души, помогите разобраться, уж больно интерестно . 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
__alexander Опубликовано 2 мая, 2014 Поделиться Опубликовано 2 мая, 2014 (изменено) а вам не кажется, что тут программа зависает? char GO = 1; while (GO); Изменено 2 мая, 2014 пользователем __alexander 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 3 мая, 2014 Автор Поделиться Опубликовано 3 мая, 2014 не зависнит это регистр микроконтроллера который запускает процесс АЦП и сбрасывается в ноль после того как преобразование закончилось 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
__alexander Опубликовано 4 мая, 2014 Поделиться Опубликовано 4 мая, 2014 это обычная переменная, которая к ацп никакого отношения не имеет. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 5 мая, 2014 Автор Поделиться Опубликовано 5 мая, 2014 (изменено) while(ADGO){} // Ждем когда GODONE АЦП вернет 0 - опрос закончен buff[0] = ADRESL; // читаем младший байт с АЦП buff[1] = ADRESH; это тоже самое что и выше участок кода только место можно godone или же go смотря какие альтернативы подключены в файле инструкции к вашему контроллеру . Кроче говоря смысл понятен всем кто разбирается в программировании микроконтроллеров. Искать и устанавливать себе тот компилятор не собираюсь . Лучше по существу расскажите как правильно предавать инфу в карту памяти по интерфейсу SPI. для микроконтроллера. /* Alternate definitions for ADCON0 register */ volatile bit ADGO @ ((unsigned)&ADCON0*8)+2; #endif вот кусок из инструкции к моему контроллеру. GO/-DONE: Бит статуса модуля АЦП Если ADON=1 1 = модуль АЦП выполняет преобразование (установка бита вызывает начало преобразования) 0 = состояние ожидания (аппаратно сбрасывается по завершению преобразования) вот выдержка из даташита Изменено 5 мая, 2014 пользователем DVyacheslavN 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
__alexander Опубликовано 5 мая, 2014 Поделиться Опубликовано 5 мая, 2014 что конкретно не понятно? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 5 мая, 2014 Автор Поделиться Опубликовано 5 мая, 2014 многоблочная запись не работает (проверял в Proteus) если есть рабочие коды выложете и расскажите . может что в протеусе фиг знает 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
__alexander Опубликовано 5 мая, 2014 Поделиться Опубликовано 5 мая, 2014 (изменено) на запись команда 25 (0x59). шлете эту команду unsigned char cmd[] = {0x59,0x00,0x00,0x00,0x00,0xFF}; потом читаете ответ пока он не станет 0 сразу за этим пишем 0xFF, 0xFF, 0xFC (data token), потом 512 байт данных, потом 0xff, 0xff, потом читаем ответ, пока он не станет равным resp & 0x05 == 0x05, 5 - это данные картой захавались. потом снова проверка на ноль и по кругу, снова 0xff, 0xff, 0xFC. завершаем запись 0xff, 0xff, 0xfd. может что-то упустил. Изменено 5 мая, 2014 пользователем __alexander 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 6 мая, 2014 Автор Поделиться Опубликовано 6 мая, 2014 У меня выложена ссылка на один из материалов которым я пользовался и есть по нему вопросы , Вот к примеру функция отправки команды char Command(char befF,uns16 AdrH,uns16 AdrL,char befH ) .ее заголовок там он есть почему тут 4 переменные передаются в команду а в других примерах 3 а конкретно adrH и AdrL объединили . 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 6 мая, 2014 Автор Поделиться Опубликовано 6 мая, 2014 (изменено) // 512-байтовый режим записи if (Command(0x58,0,512,0xFF) !=0) SerString("Schreib_resp_Fehler "); SPI(0xFF); SPI(0xFF); SPI(0xFE); вот сижу сравниваю ту последовательность действий которую вы написали и которая в материале У вас написано что после команды читать до тех пор пока не станет 0 тоесть (WHILE) а тут получется если (IF) не ноль топрограма выдаст сообщение и побежит дальше. не дожидаясь этого нуля. правда и команда тут записи одного блока data token нет где его взять 0xFC или это и есть дата токен Изменено 6 мая, 2014 пользователем DVyacheslavN 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 15 мая, 2014 Автор Поделиться Опубликовано 15 мая, 2014 (изменено) void write () { Command(25, 0, 0xff); while (1) { char Ig=0; while ((SPI_W(0xFF) != 0) || Ig>200 ) { Ig++; } if (Ig>=200) { SerString("WRITE ERROR"); goto END_W; } SerString("WRITING MMC"); SPI_W(0xff); SPI_W(0xff); SPI_W(0xfc); for (int g = 0; g < 512; g++) { SPI_W('f'); } SPI_W(0xff); SPI_W(0xff); while ((SPI_W(0xff) & 0x05) != 0x05) { } if (1) { SPI_W(0xff); SPI_W(0xff); SPI_W(0xfd); //stop token while (SPI_W(0xff) != 0xff); break; } } END_W:; } Вот выкладываю код записи, пожалуйста посмотрите может ошибки есть. Стоп токен запускаю после первого блока но даже так при эмуляции в протеусе файл флешки заполняется пробелами. А когда ставлю CMD 24 и меняю старт токен на 0xFE то один блок записывается нормально Изменено 15 мая, 2014 пользователем DVyacheslavN 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
__alexander Опубликовано 16 мая, 2014 Поделиться Опубликовано 16 мая, 2014 всё правильно. для записи следующего сектора после while ((SPI_W(0xff) & 0x05) != 0x05) надо также подождать пока не станет равным 255. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 18 мая, 2014 Автор Поделиться Опубликовано 18 мая, 2014 while (SPI_W(0xff) != 0xFF) {} Ну добавил я строчку все ровно при эмуляции в протеусе файл флешки остается пустым. там флешка ММС. Еще хотел спросить а как после записи одного блока cmd 24 перейти к следующему и записать его. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
__alexander Опубликовано 19 мая, 2014 Поделиться Опубликовано 19 мая, 2014 не знаю как протеус, я проверил на живой плате. а записать один блок абсолютно точно также, только в команде меняется адрес. т.е. дали команду, записали, потом два FF, потом проверка на 5, потом проверка на FF...снова команда только с новым адресом. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 19 мая, 2014 Автор Поделиться Опубликовано 19 мая, 2014 Да я уже подозревал что скорее в протеусе чтото не так попробую собрать плату. Вопрос еще вот какой, работали с библиотекой Petit Fatfs туда надо прописать изкоуровнивые параметры записи чтения и инициализации кароче говоря тоже туже запись чтение ти т.д просто хотелось бы работать с файлами на флеш а не с блоками данных. Я пока буду собирать схему и проверять работу программы. И только потом займусь освоением библиотеки 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
fuckir Опубликовано 27 мая, 2014 Поделиться Опубликовано 27 мая, 2014 А почему не взяли микрочиповскую библиотеку , раз юзаете pic? Пробовал Чена и Джасио библиотеки, но только на 16 битках 0 В поисках работы.. Looking for job Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 27 мая, 2014 Автор Поделиться Опубликовано 27 мая, 2014 я только учусь так что я даже не знал что есть библиотеки микрочипа. какие на слуху те и взял если есть исходники программ то можете скинуть попробую разобраться . 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 30 июня, 2014 Автор Поделиться Опубликовано 30 июня, 2014 Товарищи помогите скинте простенький пример petty fatFS для pic а то скаченный у CHAN'a сложен для понимания. Не понятно все пишиут что надо подключить diskio. h ..... *.c и pff.h .... *.c . И потом править diskio.c но в примере еше добавлино прару файлов которые работают с библиотекой. Вобщем запутался. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 30 июня, 2014 Поделиться Опубликовано 30 июня, 2014 Не запустите Вы файловую систему на этом деревянном камне. Почитайте требования к любой готовой fs и подумайте, глядя на характеристики своего кирпича... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 1 июля, 2014 Автор Поделиться Опубликовано 1 июля, 2014 )))). ну такто да.. я хочу понять работу библиотеки. допустим буду писать для камня с достаточной памятью. охото разобраться с файлом diskio.c хотябы с минимальным набором необходимых функций. а точнее инициализация , чтение, запись, 1 и несколько блоков. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
DVyacheslavN Опубликовано 1 июля, 2014 Автор Поделиться Опубликовано 1 июля, 2014 для инициализации нам необходима функция которая будет обрабатывать команду cmd /*-----------------------------------------------------------------------*/ /* Send a command packet to MMC */ /*-----------------------------------------------------------------------*/ static BYTE send_cmd ( BYTE cmd, /* Command byte */ DWORD arg /* Argument */ ) { BYTE n, res; if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */ cmd &= 0x7F; res = send_cmd(CMD55, 0); if (res > 1) return res; } /* Select the card and wait for ready except to stop multiple block read */ if (cmd != CMD12) { deselect(); if (!select()) return 0xFF; } /* Send command packet */ xchg_spi(0x40 | cmd); /* Start + Command index */ xchg_spi((BYTE)(arg >> 24)); /* Argument[31..24] */ xchg_spi((BYTE)(arg >> 16)); /* Argument[23..16] */ xchg_spi((BYTE)(arg >> 8)); /* Argument[15..8] */ xchg_spi((BYTE)arg); /* Argument[7..0] */ n = 0x01; /* Dummy CRC + Stop */ if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) + Stop */ if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) + Stop */ xchg_spi(n); /* Receive command response */ if (cmd == CMD12) xchg_spi(0xFF); /* Skip a stuff byte on stop to read */ n = 10; /* Wait for a valid response in timeout of 10 attempts */ do res = xchg_spi(0xFF); while ((res & 0x80) && --n); return res; /* Return with the response value */ } эта функция реализована в примере для pic 24 вот как я реализовывал ее для pic 16f Command (char befF,unsigned char AdrH, unsigned char AdrL,char befH ) { // Передача команды в MMC SPI(0xFF); SPI(0b01000000 | befF); SPI((unsigned char) AdrH>>24); SPI((unsigned char) AdrH>>16); SPI((unsigned char) AdrL>>8); SPI((unsigned char) AdrL); SPI (befH); SPI(0xFF); //return SPI(0xFF); // Возвращаем ответ } char MMC_Init () { CS=1; // MMC отключена char i; // Переменные for(i=0; i < 10; i++)SPI(0xFF); // 10*8=80 тактовых импульсов CS=0; // Включить MMC // CMD0 Command(0,0,0,0x95); if (SPI(0xFF) !=1) goto Fehler ; // Сброс st: // Если MMC не существует, остаётся // CMD1 // Здесь находится программа Command(1,0,0,0xFF); if (SPI(0xFF) !=0) goto st ; return 1; Fehler: return 0; } и так зачем CMD 8 если spi (в описалове "Зарезервированно системой") 2, зачем arg такой большой. ну работу этой функции command (в примере анологично сделано) понимаю при инициализации записи или чтении отправляем туда соответствующую комннду. CMD 12 допустим мне тоже не понадобится (будем ждать пока обработается комманда) Вопрос хватит ли мне только функции command Про инициализацию . Вот пример для pic 24 /*-----------------------------------------------------------------------*/ /* Initialize Disk Drive */ /*-----------------------------------------------------------------------*/ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber (0) */ ) { BYTE n, cmd, ty, ocr[4]; if (pdrv != 0) return STA_NOINIT; /* Supports only single drive */ if (Stat & STA_NODISK) return Stat; /* No card in the socket */ power_on(); /* Initialize memory card interface */ FCLK_SLOW(); for (n = 10; n; n--) xchg_spi(0xFF); /* 80 dummy clocks */ ty = 0; if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ Timer1 = 1000; /* Initialization timeout of 1000 msec */ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */ for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); /* Get trailing return value of R7 resp */ if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ while (Timer1 && send_cmd(ACMD41, 0x40000000)); /* Wait for leaving idle state (ACMD41 with HCS bit) */ if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); ty = (ocr[0] & 0x40) ? CT_SD2|CT_BLOCK : CT_SD2; /* SDv2 */ } } } else { /* SDv1 or MMCv3 */ if (send_cmd(ACMD41, 0) <= 1) { ty = CT_SD1; cmd = ACMD41; /* SDv1 */ } else { ty = CT_MMC; cmd = CMD1; /* MMCv3 */ } while (Timer1 && send_cmd(cmd, 0)); /* Wait for leaving idle state */ if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Set read/write block length to 512 */ ty = 0; } } CardType = ty; deselect(); if (ty) { /* Function succeded */ Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ FCLK_FAST(); } else { /* Function failed */ power_off(); /* Deinitialize interface */ } return Stat; } свою инициализацию я уже выложел выше. понятно что инициализация для 2 х типов карт у меня допустим для одного типа будет. хватит ли MMC_Init да и вот еще вопрос DSTATUS disk_initialize (void) { DSTATUS stat; // Put your code here return stat; } пустышка от Chan'a stat как я понял по умолчанию 1 и если все нормлаьно то оставить его 1 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
fuckir Опубликовано 1 июля, 2014 Поделиться Опубликовано 1 июля, 2014 есть собраный Чан под 24-й пик. Могу скинуть 0 В поисках работы.. Looking for job Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.