Перейти к содержанию
    

ivan24190

Участник
  • Постов

    68
  • Зарегистрирован

  • Посещение

Весь контент ivan24190


  1. Смотрите регистр BDTR и бит MOE.
  2. MSP430 + SD-карта

    К сожалению не помогло. Карта возвращает 0x01 вместо 0x00.
  3. Можно использовать инфо-сегмент с посекторным (1024 байта) стиранием, например как кольцо, тогда удастся увеличить ресурс перезаписи в 4 раза и ещё безболезненно перепрошивать, не теряя данные в этом инфо-сегменте.
  4. 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; }
  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. Во многих акселерометрах есть внутренний ВЧ фильтр, который как раз отсекает постоянную составляющую. Включив его и, интегрируя за определенный промежуток времени, можно получить среднюю скорость за это время, а в состоянии покоя скорость будет равна нулю.
  16. Точно, отключал акселерометр, датчик давления показывает значения с погрешностью 1,5 %.
  17. Одномерный или совмещаете данные с акселерометра и гироскопа?
  18. Например какой фильтр? Мне же по факту нужно положение (постоянная составляющая), а не ускорение. А если усреднять неуместно, то как определить постоянную составляющую? (БПФ или ФНЧ КИХ?)
  19. Рассматриваю этот вариант, но это крайний случай, т.к. я ограничен быстродействием и придется "оптимизировать" всю математику, а не хотелось бы ковыряться в "наследстве". Но если это единственный вариант, будем "пилить"...
  20. Здравствуйте, уважаемые форумчане. Так случилось, что "по наследству" мне досталась "доработка" датчика давления, показания которого зависят от положения в пространстве. Для компенсации ошибки от положения в нем использован акселерометр. Все бы ничего, но было выявлено, что он не может пройти испытания на вибростенде. Так вот возникает вопрос как правильно отфильтровать данные с акселерометра? Сейчасданные с акселерометра пропускаются через медианный фильтр с усреднием (32 точки, сортировка, усреднение по 16 центральным), а затем через экспоненциальный фильтр 2-го порядка, полученное значение используется для компенсации ошибки показаний. В состоянии покоя в любом положении все работает, причем импульсные помехи (удары, случайные короткие колебания и.т.д) отсекаются на ура. Но при проведении испытаний на вибростенде и снятия характеристик как с датчика, так и акселерометра выяснилось, что точное определение положения датчика возможно, только если усреднять показания за весь интервал проведения испытаний (30 - 60 минут), что невозможно в ввиду требований к быстродействию прибора 0,5 секунд. (Скорость обновления данных с акселерометра 50 ( можно сделать 100) Гц, полоса частот при испытаниях на вибрацию переменная 2 - 100 Гц). Можете посоветовать куда "копать" для решения данной проблемы. У меня была мысль использовать гироскоп для определения угла отклонения датчика вместо акселерометра, но идею отмели ввиду того, что комплектующие закуплены и платы уже изготовлены на опытную серию. Надо решать задачу на том что есть: STM32F100 + AIS328DQ.
  21. У меня такое случалось, когда вместо отладчика использовался симулятор. Проверьте вкладку настройки отладчика.
  22. А может стоит проверять флаги ошибок приема (FE, NF и т.д.) и сбрасывать их? Т.к. в некоторых случаях прием может "затыкаться" если эти флаги установлены.
  23. Попробуйте использовать DMA в режиме MEM2MEM. Хотя 36 МГц получить наверное не удастся, но будет быстрее, чем через таймер. Но учтите, что DMA в этом режиме займет шину целиком. Либо рассмотреть вариант с FSMC.
  24. Во вложении тестовый проект для AD7730 (рабочий, Keil 4.74), Вас интересует все файлы в папке \Lib\AD7730_drv_v1.x. Вдруг пригодится... (Если нужно, то могу отправить описание на микросхему на русском по почте, сюда выложить не удается пишет ошибка -200) Tensometer_1.4.zip
  25. Как вариант можно создать задачу-демон, которая будет иметь монопольный доступ к Вашей структуре. А все остальные задачи будут обращаться к этим данным только через задачу-демон, например с помощью очереди, тем более средства FreeRTOS позволяют это сделать. P.S. если интересно почитайте руководство к FreeRTOS "Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide" в частности главу "7.4 Gatekeeper Tasks". Данный файл можно найти на официальном сайте.
×
×
  • Создать...