Jump to content
    

ivan24190

Участник
  • Posts

    68
  • Joined

  • Last visited

Reputation

0 Обычный

About ivan24190

  • Rank
    Участник
    Участник
  • Birthday 01/24/1990

Информация

  • Город
    Array

Recent Profile Visitors

1,390 profile views
  1. Смотрите регистр BDTR и бит MOE.
  2. К сожалению не помогло. Карта возвращает 0x01 вместо 0x00.
  3. К1986ВЕ92

    Можно использовать инфо-сегмент с посекторным (1024 байта) стиранием, например как кольцо, тогда удастся увеличить ресурс перезаписи в 4 раза и ещё безболезненно перепрошивать, не теряя данные в этом инфо-сегменте.
  4. Здравствуйте уважаемые форумчане. Понадобилось к проекту прикрутить 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; }
  5. Можно попробовать определить константы в другом си-файле с указанием адреса/секции размещения без всяких root и т.д. Создать заголовочный файл с объявлением констант как extern const. А в остальных файлах программы подключать этот заголовочный файл. В таком случае всё корректно работает. Например, мы так храним настройки в info/flash-памяти MSP430, которые могут меняться пользователем.
  6. Когда требуется считать CRC данных с "разрывами", то в функцию, выполняющую расчёт CRC, дополнительным параметром можно передать CRC, которое было рассчитано для предыдущего блока данных. И так повторить для требуемого количества блоков.
  7. А почему нельзя воспользоваться такой формулой: Если x > 1000, то y = 255 Иначе y = x * 100 / 392. Считать всё в целых числах. Например y = 1000*100/392=255.
  8. Если float32_t здесь действительно float, то касательно этих массивов делать ничего не нужно, тут приведение типа произойдет автоматически. Но на места арифметики нужно обратить внимание.
  9. Да пожалуйста, но у вас операция деления на 3.0, а это по умолчанию double. Поэтому компилятор сначала преобразует все числа в double, затем выполнит всю арифметику в double и только в конце перед присваиванием преобразует во float. Поэтому нужно писать 3.0f, тогда все операции будут выполняться с float. Либо, как советовали выше, искать флаг компилятора, чтобы все вычисления с числами с плавающей точкой проводились во float.
  10. Помимо включения самого Single FPU, нужно и работать с переменными типа float, и математические операции делать с float (в частности добавлять в конце чисел букву 'f'), а не double. centerPoint[0] = (v1[3] + v2[3] + v3[3]) / 3.0f;
  11. ИМХО, Была бы интересна ветка с возможностями периферии разных производителей или серии МК. Например, у кого самые навороченные таймеры, АЦП и т.д. И для каких применений по собственному опыту.
  12. А бит "MOE" в регистре TIM1->BDTR установлен?
  13. Для того чтобы АЦП запускался по событию 'CaptureCompare', необходимо в регистре CCER таймера установить бит разрешения нужного канала, например TIM3->CCER |= TIM_CCER_CC1E; При этом АЦП уже должен быть настроен на запуск от данного события.
  14. В продолжение темы. Удалось пройти вибрацию с погрешностью ~2.5%. Для этого повысил частоту выдачи данных с акселерометра до 400 Гц и пропустил эти данные через ФНЧ БИХ с частотой среза ~9 Гц (коэффициенты рассчитывал с помощью matlab fdatool), но не суть, т.к. заказчика это не устроило - его пожелание 0.25%. Пытался уменьшать частоту среза вплоть до 1-2 Гц, комбинировал этот фильтр с фильтром Калмана, но максимум, который удалось достичь ~1.5-2.0%. Может быть есть какие более эффективные и быстрые методы фильтрации, чтобы достичь указанной погрешности? Кстати диапазон измерения датчика всего 600 Па, т.е. он чувствует вес собственной мембраны, может быть в этом проблема?
  15. Во многих акселерометрах есть внутренний ВЧ фильтр, который как раз отсекает постоянную составляющую. Включив его и, интегрируя за определенный промежуток времени, можно получить среднюю скорость за это время, а в состоянии покоя скорость будет равна нулю.
×
×
  • Create New...