ivan24190
Участник-
Постов
68 -
Зарегистрирован
-
Посещение
Репутация
0 ОбычныйИнформация о ivan24190
-
Звание
Участник
- День рождения 24.01.1990
Информация
-
Город
Array
Посетители профиля
1 809 просмотров профиля
-
Смотрите регистр BDTR и бит MOE.
-
К сожалению не помогло. Карта возвращает 0x01 вместо 0x00.
-
Можно использовать инфо-сегмент с посекторным (1024 байта) стиранием, например как кольцо, тогда удастся увеличить ресурс перезаписи в 4 раза и ещё безболезненно перепрошивать, не теряя данные в этом инфо-сегменте.
-
ivan24190 подписался на MSP430 + SD-карта
-
Здравствуйте уважаемые форумчане. Понадобилось к проекту прикрутить SD-карту с файловой системой. Выбрал FATFS от Чана, портировал драйвер низкого уровня из его примеров для STM32. Карты (от Qumo, Transcend, Samsung) ёмкостью 2 - 32 ГБ работают: папки создаются, файлы пишутся и т.д. Но вот карта от SanDisk на 64 ГБ работать никак не хочет. Выдаёт ошибку по таймауту (пробовал менять от 1 до 10 секунд) при отправке команды ACMD41 во время инициализации (отметил стрелкой). Может есть у кого какие соображения куда копать? Код инициализации. uint8_t sdcard_initialize(void) { // Если SD-карта отсутствует, то выход if (sdcard_status & STA_NODISK) return sdcard_status; // Отключить SD-карту sdcard_deselect(); // Инициализация карты всегда производится на низкой скорости SPI (100-400 кГц) spi_baud_rate_change(SPI_BAUD_RATE_LOW); uint8_t n; const uint8_t tx_byte = 0xFF; // Отправить не менее 80 единичных бит (обязательно, иначе карта не инициализируется!) for (n = 10; n; n--) spi_byte_exchange(tx_byte); // Тип SD-карты (после инициализации не должен быть нулевым!) uint8_t type = 0; // Перевести SD-карту в состояние SPI/Idle if (sdcard_send_cmd(SDCARD_CMD0, 0) == 1) { // Временная метка начала отсчёта const timer_interval_t start = timer_interval_total_get(); timer_interval_t timer; bool_t is_timeout; // Если тип SD-карты SDC ver. 2 или SDC ver. 2+ if (sdcard_send_cmd(SDCARD_CMD8, 0x1AA) == 1) { // Чтение 32-битного регистра R7 uint8_t ocr[4]; for (n = 0; n < 4; n++) ocr[n] = spi_byte_exchange(tx_byte); // Если SD-карта поддерживает напряжение питания 2.7-3.6 В if (ocr[2] == 0x01 && ocr[3] == 0xAA) { // Ожидание завершения инициализации командой ACMD41 (HCS бит) do { timer = timer_interval_total_get() - start; is_timeout = timer >= SDCARD_INITIALIZE_TIMEOUT; } while (!is_timeout && sdcard_send_cmd(SDCARD_ACMD41, 1ul << 30)); // <- Зависает на этой строке: всегда возвращает busy = 0x01! // Проверка CCS бита в OCR if (!is_timeout && sdcard_send_cmd(SDCARD_CMD58, 0) == 0) { for (n = 0; n < 4; n++) ocr[n] = spi_byte_exchange(tx_byte); // Тип SD-карты SDC ver. 2 type = (ocr[0] & 0x40) ? SDCARD_TYPE_SDC2 | SDCARD_TYPE_BLOCK : SDCARD_TYPE_SDC2; } } } // Иначе... else { uint8_t cmd; // Тип SD-карты SDC if (sdcard_send_cmd(SDCARD_ACMD41, 0) <= 1) { type = SDCARD_TYPE_SDC1; cmd = SDCARD_ACMD41; } // Тип SD-карты MMC ver. 3 else { type = SDCARD_TYPE_MMC3; cmd = SDCARD_CMD1; } // Ожидание завершения инициализации do { timer = timer_interval_total_get() - start; is_timeout = timer >= SDCARD_INITIALIZE_TIMEOUT; } while (!is_timeout && sdcard_send_cmd(cmd, 0)); // Установить значение блока данных по умолчанию if (is_timeout || sdcard_send_cmd(SDCARD_CMD16, SDCARD_SECTOR_SIZE) != 0) type = 0; } } // Сохранить тип SD-карты sdcard_type = type; sdcard_deselect(); if (type) { // Увеличить скорость обмена по SPI spi_baud_rate_change(SPI_BAUD_RATE_HIGH); // Обновить статус SD-карты sdcard_status &= ~STA_NOINIT; } // Ошибка инициализации else sdcard_status = STA_NOINIT; return sdcard_status; }
-
Можно попробовать определить константы в другом си-файле с указанием адреса/секции размещения без всяких root и т.д. Создать заголовочный файл с объявлением констант как extern const. А в остальных файлах программы подключать этот заголовочный файл. В таком случае всё корректно работает. Например, мы так храним настройки в info/flash-памяти MSP430, которые могут меняться пользователем.
-
Когда требуется считать CRC данных с "разрывами", то в функцию, выполняющую расчёт CRC, дополнительным параметром можно передать CRC, которое было рассчитано для предыдущего блока данных. И так повторить для требуемого количества блоков.
-
Преобразование данных
ivan24190 ответил whale тема в ARM, 32bit
А почему нельзя воспользоваться такой формулой: Если x > 1000, то y = 255 Иначе y = x * 100 / 392. Считать всё в целых числах. Например y = 1000*100/392=255. -
Если float32_t здесь действительно float, то касательно этих массивов делать ничего не нужно, тут приведение типа произойдет автоматически. Но на места арифметики нужно обратить внимание.
-
Да пожалуйста, но у вас операция деления на 3.0, а это по умолчанию double. Поэтому компилятор сначала преобразует все числа в double, затем выполнит всю арифметику в double и только в конце перед присваиванием преобразует во float. Поэтому нужно писать 3.0f, тогда все операции будут выполняться с float. Либо, как советовали выше, искать флаг компилятора, чтобы все вычисления с числами с плавающей точкой проводились во float.
-
Помимо включения самого Single FPU, нужно и работать с переменными типа float, и математические операции делать с float (в частности добавлять в конце чисел букву 'f'), а не double. centerPoint[0] = (v1[3] + v2[3] + v3[3]) / 3.0f;
-
ИМХО, Была бы интересна ветка с возможностями периферии разных производителей или серии МК. Например, у кого самые навороченные таймеры, АЦП и т.д. И для каких применений по собственному опыту.
-
Опять таймер, ADC и DMA на STM32F4 (Discovery)
ivan24190 ответил hd44780 тема в ARM, 32bit
А бит "MOE" в регистре TIM1->BDTR установлен? -
Опять таймер, ADC и DMA на STM32F4 (Discovery)
ivan24190 ответил hd44780 тема в ARM, 32bit
Для того чтобы АЦП запускался по событию 'CaptureCompare', необходимо в регистре CCER таймера установить бит разрешения нужного канала, например TIM3->CCER |= TIM_CCER_CC1E; При этом АЦП уже должен быть настроен на запуск от данного события. -
Обработка данных с акселерометра
ivan24190 ответил ivan24190 тема в В помощь начинающему
В продолжение темы. Удалось пройти вибрацию с погрешностью ~2.5%. Для этого повысил частоту выдачи данных с акселерометра до 400 Гц и пропустил эти данные через ФНЧ БИХ с частотой среза ~9 Гц (коэффициенты рассчитывал с помощью matlab fdatool), но не суть, т.к. заказчика это не устроило - его пожелание 0.25%. Пытался уменьшать частоту среза вплоть до 1-2 Гц, комбинировал этот фильтр с фильтром Калмана, но максимум, который удалось достичь ~1.5-2.0%. Может быть есть какие более эффективные и быстрые методы фильтрации, чтобы достичь указанной погрешности? Кстати диапазон измерения датчика всего 600 Па, т.е. он чувствует вес собственной мембраны, может быть в этом проблема? -
Во многих акселерометрах есть внутренний ВЧ фильтр, который как раз отсекает постоянную составляющую. Включив его и, интегрируя за определенный промежуток времени, можно получить среднюю скорость за это время, а в состоянии покоя скорость будет равна нулю.