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

adnega

Свой
  • Постов

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

  • Посещение

  • Победитель дней

    3

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


  1. http://www.gaw.ru/html.cgi/txt/interface/usb/ums.htm Спецификации на usb.org https://docs.espressif.com/projects/arduino-esp32/en/latest/api/usb_msc.html
  2. Я не пользуюсь стандартной библиотекой - у меня своя, но по исходнику все понятно - какие биты в каких регистрах взводить. Дык, видно же, что прерывание по таймеру используется. Вам прицепленный исходник понятен?
  3. Это не ШИМ, а правильнее назвать "сравнение". )) Ну, как бы таймер ногу дергает, а я только длительность задаю. Хотя, согласен, случай спорный. Можно сделать чисто TIMER+DMA, но только не для SEARCH_ROM, т.к. там по ходу нужно решения принимать. Правда, в IRQ для SEARCH_ROM можно данные в буфере DMA успевать подменять...
  4. //----------------------------------------------------------------------------- // void OW_start(void) //----------------------------------------------------------------------------- void OW_start(void) { ow_timeout = 0; OW_TIM->CCR1 = OW_START_PULSE - 1; OW_TIM->ARR = 1000 - 1; OW_TIM->CCMR1 = 0 | (OC_MODE_FORCE_ACTIVE << TIM_CCMR1_OC1M) | (1 << TIM_CCMR1_CC2S); OW_TIM->CCMR1 = 0 | (OC_MODE_SET_INACTIVE << TIM_CCMR1_OC1M) | (1 << TIM_CCMR1_CC2S); OW_TIM->CR1 = (1 << TIM_CR1_OPM) | (1 << TIM_CR1_CEN); #ifdef OW_DEBUG con_str("[START]"); con_start(); #endif } //----------------------------------------------------------------------------- // void OW_write(const int b) //----------------------------------------------------------------------------- void OW_write(const int b) { switch(b) { case 0: OW_TIM->CCR1 = OW_BIT_0 - 1; break; case 1: OW_TIM->CCR1 = OW_BIT_1 - 1; break; default: return; } OW_TIM->ARR = 100; OW_TIM->CCR2 = 0; OW_TIM->CCMR1 = 0 | (OC_MODE_FORCE_ACTIVE << TIM_CCMR1_OC1M) | (1 << TIM_CCMR1_CC2S); OW_TIM->CCMR1 = 0 | (OC_MODE_SET_INACTIVE << TIM_CCMR1_OC1M) | (1 << TIM_CCMR1_CC2S); OW_TIM->CR1 = (1 << TIM_CR1_OPM) | (1 << TIM_CR1_CEN); } //----------------------------------------------------------------------------- // void OW_read(void) //----------------------------------------------------------------------------- void OW_read(void) { OW_write(1); } //----------------------------------------------------------------------------- // void OW_IRQ(BYTE x) //----------------------------------------------------------------------------- void OW_on_data(int x) { #ifdef OW_DEBUG con_push('['); con_dec(x); con_push(']'); con_start(); #endif switch(ow_state) { //********************************************************* // ПОИСК НОВЫХ УСТРОЙСТВ //********************************************************* //--------------------------------------------------------- // OW_STATE_SEARCH //--------------------------------------------------------- case OW_STATE_SEARCH: if(OW_COND_START) { ow_cmd = OW_CMD_SEARCH_ROM; ow_count = 0; ow_state = OW_STATE_CMD_SEARCH_ROM; OW_send(); // инициализация поиска ... } //----------------------------------------------------------------------------- // void TIM8_BRK_TIM12_IRQHandler(void) //----------------------------------------------------------------------------- void TIM8_BRK_TIM12_IRQHandler(void) { if(TIM12->SR & (1 << TIM_SR_UIF)) { TIM12->SR = ~(1 << TIM_SR_UIF); OW_on_data(TIM12->CCR2); } } //----------------------------------------------------------------------------- // void init_TIMER12(void) //----------------------------------------------------------------------------- void init_TIMER12(void) { TIM12->CR1 = 0; TIM12->CCER = 0; if(rcc_state == RCC_STATE_PLL) TIM12->PSC = ((FPLL >> 1) / 1000000) - 1; else TIM12->PSC = (FHSI / 1000000) - 1; TIM12->ARR = 1000; TIM12->CCR1 = 2 - 1; TIM12->CCMR1 = 0 | (OC_MODE_FORCE_INACTIVE << TIM_CCMR1_OC1M) | (1 << TIM_CCMR1_CC2S); TIM12->CCER = (1 << TIM_CCER_CC1E) | (1 << TIM_CCER_CC2E) | (0 << TIM_CCER_CC2P); TIM12->DIER = (1 << TIM_DIER_UIE); TIM12->CR1 = (0 << TIM_CR1_CEN); } /****************************************************************************** * DEFINE *****************************************************************************/ #define OW_BIT_0 (70) #define OW_BIT_1 (10) #define OW_START_PULSE (480) #define OW_START_MIN (OW_START_PULSE + 15 + 60) #define OW_START_MAX (OW_START_PULSE + 60 + 240) #define OW_BIT_MIN (1) #define OW_BIT_MAX (20) #define OW_COND ((OW_BIT_MIN <= x) && (x <= OW_BIT_MAX)) #define OW_COND_START ((OW_START_MIN <= x) && (x <= OW_START_MAX)) Правда, без ногодрыга
  5. В широком диапазоне температур вместо привычных кодов для 0 и 1 начинают приходить "соседние" значения. Если ПО это сможет учесть, то норм.
  6. И прием, и передачу бита инициирует только мастер. Причем/чтение - это по сути запись бита 1, но в ответ может быть получена длительность как для бита 1, так и бита 0. Т.е. вы одним каналом таймера всегда формируете передачу какой-то длительности нуля на шине, а вторым каналом всегда считываете момент фронта (перехода из нуля в единицу шины) - т.е. длительность нуля на шине, по которой принимаете решение о считанном бите.
  7. Видел обе эти статьи, и бегло не понял в чем проблема: - да есть зависимость значений от температуры? Но это определяется во многом сенсором, а не HX711. У меня в стенде дорогущий датчик силы - он страшно плывет от температуры. А дешевый китайский значительно меньше. - есть проблема на китайском модуле? Да, решил одним проводочком. У нас в стенде нужно определять момент касания очень точно. Ловим касание на уровне 4 грамм. Все довольны. Шум +-50 единиц. Ниже график: положили 1 грамм Датчик на 10 кг.
  8. А можно ссылку, т.к. у меня от микросхемы (HX711) самые положительные ощущения? А вот модуль с Али какие-то проблемы с трассировкой/подключением имел (вроде, земли были не соединены - кидал что-то проводком).
  9. Я тут закупаюсь: https://www.rct.ru/ Например: https://www.rct.ru/catalog/enclosure-case-box/g505015b.html (но "B", вроде, без крышки)
  10. В CAN-стандарте конкретный физический уровень не определяется (только требования к нему). Но большинство физик в витую пару тянут CAN-H и CAN-L к середине напряжения питания Поэтому уровень там примерно в районе 2.5 В при питании 5В. В отличии от RS485 - шина без активных передатчиков летает безнаказанно от минус 7 до плюс 12 В. Недавно с такой же проблемой боролся: передатчик после стопового бита отпускал кратковременно шину. И одновременно с этим попались экземпляры ADM485, которые нулевое дифференциальное напряжение на входе устойчиво трактовали как лог. 0. Вот картинка по 4 образцам (R - это реф от надежного поставщика, 1-2-3 - какие-то "проблемные" ADM485) На вход B подавалось смещение (ось X) от -5 до +10В, а на входе A была пила от -2 до +2 В. Диф.сигнал по оси Y. Видно, что только экземпляр R имеет петлю гистерезиса включающую в себя нулевое дифференциальное смещение на всем интервале допустимых VCM. Т.е. только он не переключает выход приемника RXD, а сохраняет предыдущее значение. Для экземпляра 1 это условие выполняется при VCM меньше -2.5 В (зеленая жирная линия). Для экземпляра 2 это условие выполняется при VCM больше +2.5 В (красная жирная линия). Для экземпляра 3 это условие выполняется при VCM больше +5.0 В (синяя жирная линия). Обычно VCM в реальных системах находится в диапазоне 0 .. +5 В (желтая жирная линия). Т.е. экземпляр 2 иногда может паузы передатчика воспринимать за логическую 1, и обмен может вестись корректно, если VCM при этом будет по какой-то причине выше +2.5 В. Экземпляр 1 на рабочем диапазоне VCM всегда будет выдавать логический 0. Экземпляр 3 на рабочем диапазоне VCM от +2.5 В до +5.0В может сохранять логическую 1, и вести обмен корректно, но уровень переключения 1→0 настолько близок к нулю, что любая помеха может переключить приемник RXD. Я согласен, что нужно бороть протокольными методами (включать передатчик на какое время перед отправкой посылки) и/или добавлять несколько FF в начало. Но тут проблема, что передатчик "дурной", и ничего с этим не поделать. Были бы Phy с гистерезисом приемника, включающим 0 на входе (а еще лучше -200 мВ), но увы. Остается только растяжка.
  11. Обращаю внимание, что в G474 есть такой блок: Насколько я помню, он не сильно выигрывает в сравнении с обычным FPU по скорости, но, вроде, из жирных плюсов, что какую-то математику можно прогонять через DMA. Т.е. какую-то обработку можно делать аппаратно, а CPU+FPU доделывать основное. У ST есть IDE, на плате есть отладчик + UART поверх USB. По примерам можно легко стартануть. Документация хорошая, исходники немудренные, сообщество обширное. Для попробовать/эксперимент - милое дело.
  12. У меня такая отладка есть в наличии, но пощупать времени не было. Если вам не нужен непрерывный поток, то можно заполнить буфер в ОЗУ и по одному из медленных каналов передать на постобработку в ПК. Если буфер мал, то я бы выкидывал в какую-нить внешнюю параллельную шину (тоже через DMA) и ловил логическим анализатором в ПК. Или вам математика на стороне МК нужна?
  13. У меня на 4 модулях С24 (P/N:S2-108K7-Z1L1E) из "много" почему-то imei слетели к дефолтному. И никак побороть не могу. Был EAT на C32. Закупили случайно C24. При помощи SDK под C24 сделал EAT под C24, но шили старой утилитой, у которой не было различий в SIM800C (1.04). На четырех модулях imei сломались, и спецкомандами не возвращаются назад. Модули отложили в сторону. Пользуемся новой шилкой (1.19). Шьем C32 в C32, и C24 в C24. Больше сотни - полет нормальный. Итого: я бы не мешал ;))
  14. Говорят, в NUCLEO-G474RE установлен МК с такой вот начинкой Другими словами: пять АЦП, при 12 битах до 4 Мвыб/с, до 42 каналов (причем можно в дифференциальном режиме). Больше вопросов вызывает способ такой поток куда-то передать.
  15. Может, с учетом 0 должно быть 127 ?
  16. Типичное значение 20ppm, это менее 2 секунд в сутки. Но если нужен ноль, то можно и ноль сделать.
  17. В коде тоже нужно повнимательнее посмотреть, т.к. что-то очень большая ошибка. Мож, при предделителе clkio/256 у вас TCNT отличается от нужного на 1. Попробуйте TCNT туда-сюда на единичку поменять. delta = 10 минут / сутки = ~ 6944 ppm. delta = 1 - ((32768 - 256) / 32768) = ~7812 ppm, что соответствует уходу 11 минут 15 секунд в сутки.
  18. GD32F103CBT6, keil и st-link

    Если вдруг RDP установите, то либо GD-Link, либо UART-загрузчик вызывать. Через ST-Link защиту не снять.
  19. упс, я как-то это уточнение не заметил :)) он прав, что компилятор способен на трюки с упаковкой битов - пример из реальной жизни я привел. был бы у вас исходник, уверен, что правили бы его, а не бинарник. Тут мельком было упоминание про дизассемблер (тоже хочу пару байт найти и поправить). Кто что использует для cortex-m ? radare2 ?
  20. И Variant99, и jcxz по своему правы. Очень подробно и правильно расписан механизм инициализации памяти еще на первой странице, но такое поведение возможно, если не баловаться выше -O0. При других уровнях оптимизации компилятор может перепахать код до неузнаваемости. Например, такой исходник (обработчик энкодера опросом порта) enc_state = (enc_state >> 2) | ((GPIOA->IDR >> (13 - 2)) & 0x0C); switch(enc_state) { case 0b0010: case 0b1011: case 0b1101: case 0b0100: enc_count--; delay = 0; break; case 0b0001: case 0b0111: case 0b1110: case 0b1000: enc_count++; delay = 0; break; } Превращается в такой набор инструкций: 80033be: f04f 4390 mov.w r3, #1207959552 ; r3 = 0x48000000 80033c2: 8a1a ldrh r2, [r3, #16] ; r2 = GPIOA->IDR 80033c4: 4b2b ldr r3, [pc, #172] ; ([8003474] = 0x20000024 = .bss) 80033c6: 0ad2 lsrs r2, r2, #11 ; r2 = (GPIOA->IDR >> (13 - 2)) 80033c8: 6a99 ldr r1, [r3, #40] ; r1 = enc_state 80033ca: f002 020c and.w r2, r2, #12 ; r2 = (GPIOA->IDR >> (13 - 2))& 0x0C 80033ce: ea42 02a1 orr.w r2, r2, r1, asr #2 ; r2 = (enc_state >> 2) | ((GPIOA->IDR >> (13 - 2)) & 0x0C) 80033d2: 2a0e cmp r2, #14 80033d4: 629a str r2, [r3, #40] ; enc_state = r2 80033d6: d80a bhi.n 80033ee ; end switch 80033d8: 2101 movs r1, #1 80033da: fa01 f202 lsl.w r2, r1, r2 ; r2 = (1 << enc_state) 80033de: f642 0114 movw r1, #10260 ; 0x2814 = 0b0010100000010100 = (1 << 0b0010) | (1 << 0b0100) | (1 << 0b1011) | (1 << 0b1101) 80033e2: 4011 ands r1, r2 80033e4: d127 bne.n 8003436 ; dec_enc_count 80033e6: f244 1082 movw r0, #16770 ; 0x4182 = 0b0100000110000010 = (1 << 0b0001) | (1 << 0b0111) | (1 << 0b1000) | (1 << 0b1110) 80033ea: 4202 tst r2, r0 80033ec: d129 bne.n 8003442 ; inc_enc_count Компилятор красиво оптимизировал switch - я бы так не сообразил. При этом исходник для меня остался читабельным, а код стал эффективным. PS. А по теме - патчить бинарник = зло!
  21. Можно более широко поставить вопрос: есть ли альтернатива DRV88xx? Где смотреть? Есть много вариантов для игрушек (питание 12В, ток 2А), но с серьезными параметрами не вижу аналогов. Ток в районе 6А, напряжение больше 24В, полный мост с защитами и токовым монитором (типа DRV8874).
  22. Теперь понятно. 64 бита - это 8 байт. Т.е. нужно писать не менее 8 байт. Такое требование, действительно, есть у многих. У меня заголовок 16 байт - прокатывает. Сделано как обсуждалось: пишу обновление во флеш, считаю CRC, если совпало пишу заголовок; при старте проверяю заголовок и если он корректный, то считаю CRC, только после этого делаю полезную работу. На XMC4000 такое должно работать. Еще примеры будут (где более 16 байт)?
×
×
  • Создать...