о каком прерывании речь? вообще-то я просил без "ожиданий/прерываний/ногодрыгов". процессор здесь используется только для инициализации железа и запуска секвенсора. в формировании цифрового сигнала процессор не участвует совсем. к слову сказать, можно легко менять временные параметры сигнала (внести задержки, сделать импульсы жирнее и т.п.), просто составив массив таймингов по другому. в случае с юсартом так не получится.
на столе будет работать, а в реальных условиях я подожду 100мкс между стартами слотов
да понятно, что мегагерцовые частоты в проводах не уйдут далеко. но паузы можно делать, хоть по десять часов:
"If for any reason a transaction needs to be suspended, the bus MUST be left in the idle state if . Infinite recovery time can occur between bits so long as the 1-Wire bus is in the inactive (high) state during the recovery period."
предложенная схема легко настраивается под различные тайминги. ограничение -- разрядность таймера.
всегда приходица выбирать между крайностями, при 100мкс периоде удобнее щитать тайминги кмк. готовый код есть на электрониксе
_________________ глаза баяца, руки из жопы, но я не здаюсь
самому считать дичь и варварство. скрипт на питоне -- наше все. Спойлер
Код:
# ---------- # 1-Wire Timing Array Generator # # Generates a C array of timer compare values for 1-Wire protocol bit-banging # ----------
def one_wire_bit_edges(byte, start_time, slot, low0, low1, event_counter, first_bit_low=True): """ Generate (time, comment) pairs for each edge in a 1-Wire byte transmission. - For the very first bit after the presence pulse, the line is already LOW, so only the RISE (HIGH) is recorded. - For all other bits, both FALL (LOW) and RISE (HIGH) are recorded. """ times = [] t = start_time if first_bit_low: # First bit: line is already LOW, so only RISE (HIGH) after LOW duration bitval = (byte >> 0) & 1 low = low1 if bitval else low0 t_rise = t + low comment_rise = f"Bit 0: RISE (HIGH) after {low} µs LOW, sending '{bitval}'" times.append((t_rise, comment_rise)) t += slot event_counter += 1 bit_start = 1 else: bit_start = 0 for bit in range(bit_start, 8): bitval = (byte >> bit) & 1 comment_fall = f"Bit {bit}: FALL (LOW) - sending '{bitval}'" times.append((t, comment_fall)) low = low1 if bitval else low0 t_rise = t + low comment_rise = f"Bit {bit}: RISE (HIGH) after {low} µs LOW" times.append((t_rise, comment_rise)) t += slot event_counter += 2 return times, event_counter
def generate_ccr_edges( reset_low=480, presence_high=500, command_bytes=None, start_time=0, slot=70, low0=60, low1=1 ): """ Generate the full sequence of (time, comment) pairs for a 1-Wire transaction. - Includes reset and presence pulses, and all command bytes. """ if command_bytes is None: command_bytes = [] times = [] t = start_time event_counter = 0
# -- 1. Reset Pulse (Master pulls line LOW) -- t += reset_low comment_rise = "RESET: RISE (HIGH) - end reset, start presence pulse" times.append((t, comment_rise)) event_counter += 1
# -- 2. Presence Pulse (Slave pulls line LOW after presence_high) -- t += presence_high comment_fall2 = f"PRESENCE: FALL (LOW) - end presence (width {presence_high} µs), line LOW for first bit" times.append((t, comment_fall2)) event_counter += 1
# -- 3. Command Bytes (LSB first) -- for idx, b in enumerate(command_bytes): # Add empty line and command byte comment for readability times.append((None, "")) byte_comment = (f"// Command byte 0x{b:02X} " f"(binary: {b:08b}, LSB first: {', '.join(str((b>>i)&1) for i in range(8))})") times.append((None, byte_comment))
# For the very first command byte, the line is already LOW after presence first_bit_low = (idx == 0) bit_times, new_counter = one_wire_bit_edges( b, t, slot, low0, low1, event_counter, first_bit_low ) times.extend(bit_times) event_counter = new_counter t += 8 * slot # Move to the start time for the next byte
return times
def format_c_array(name, times): """ Format the (time, comment) pairs as a C array, with header comments inside the array definition, separated by blank lines for clarity. """ out = f"const uint16_t {name}[] = {{\n" out += "\n" # Blank line after array definition out += ( " // Timer starts with channel output state LOW\n" " // Each value is a timer compare value for the next output edge\n" " // Indices in brackets are sequential events in the waveform\n" ) out += "\n" # Blank line after header comments indent = " " event_index = 0 for item in times: if isinstance(item, tuple): t, comment = item if t is not None: out += f"{indent}{t}, // [{event_index}] {comment}\n" event_index += 1 else: if comment == "": out += "\n" else: out += indent + comment + "\n" else: out += indent + str(item) + "\n" out += "};" return out
# ---------- # Example usage: Adjust the parameters below as needed for your application # ---------- if __name__ == "__main__": # Slot time (total bit period), LOW durations for '0' and '1' slot = 70 low0 = 60 low1 = 1
# Generate timing for reset, presence, and two command bytes (0xCC, 0x44) ccr_times = generate_ccr_edges( reset_low=480, # Reset pulse duration (µs) presence_high=500, # Presence pulse HIGH duration (µs) (wider than usual) command_bytes=[0xCC, 0x44], start_time=0, slot=slot, low0=low0, low1=low1 )
# Print the formatted C array print(format_c_array("ccr_seq", ccr_times))
Всем привет. Решил оседлать smt32. Почитал литературу, мануалы. Приобрел стлинк + bluepill, cube ide 1.18.1 поставил. Решил для начала повторить аналогичные телодвижения https://www.youtube.com/watch?v=6xhzoDGi4qA . При загрузке в плату, программа ругнулась и выдала следующее (см.прилож). Вопрос, что не так и как исправить?
А вы не ролики для имбецилов с Тытруба смотрите, а читайте мануал на Куб и ХАЛ. Да-да, есть и такие книжки! Глядишь, и понимание картинки на экране монитора сразу появится
А вы не ролики для имбецилов с Тытруба смотрите, а читайте мануал на Куб и ХАЛ. Да-да, есть и такие книжки! Глядишь, и понимание картинки на экране монитора сразу появится
пока он прочитает мануалы, калокубы безнадежно устареют. а раз ты такой умный, то запишы ролик для вундеркиндеров и выложы тут на абсерание.
_________________ глаза баяца, руки из жопы, но я не здаюсь
Кстати, про git: довел я до ума свои идеи, что здесь высказывал про кодстайл, работу с ds18b20 и прочее. Выложил здесь. Цель проекта -- общение с ds18b20 средствами TIM1 и нескольких каналов DMA для получение температуры. Без софтовых задержек, блокирующих полингов, прерываний и ногодрыжества. Все, что касается 1-wire, все в железе.
Чтобы собрать демо, иллюстрирующее, как оно работает, нужно иметь установленными gcc, make и wget. Под виндой не помешает cygwin, а под линем и так норм. Есть два варианта сборки: просто make в командной строке, чтобы собрать бинарь со всеми оптимизациями и make debug -- чтобы собрать без оптимизаций и с отладочной информацией. В процессе сборки make подтянет из интернета все недостающие заголовочники (CMSIS) и базовые файлы (стартап и пр.). make program -- зальет прошивку в мк через st-link (утилита ST-LINK_CLI.exe должна находится в каталоге, который прописан в PATH). make jprogram -- зальет прошивку через J-Link.
Демка работает с ds18b20 через PA8 (не забыть подтягивающий резистор 4.7к), мигает светодиодом на PC13 и выводит температуру текстом через USART1 (115200) на PA9. Все отлаживалось на голубой пилюле, что подразумевает наличие внешнего кварца. Можно и без кварца, да и частота может быть любая, но это потребует легкой правки кода.
С интересом послушаю критику, буде таковая случится.
Опция --no-warn-rwx-segments появилась в Binutils версии 2.39 и было это в 2022 году. Есть смысл подумать об обновлении. Второй вариант: убрать ее из Makefile, но тогда в процессе сборки будут вылезать предупреждения. Опция -lm тут никому не мешает, но может пригодится, если вдруг потребуется какие-нибудь синусы считать.
Второй вариант: убрать ее из Makefile, но тогда в процессе сборки будут вылезать предупреждения.
нет, ничего не вылазит. без этой опции проект собирается нормально. но все равно, это неполноценный драйвер, он работает только с одним датчиком на шине через "SKIP ROM".
Цель была показать, что так можно. Именно потому, что я так и не нашел даже следов реализации подхода "Все в железе", мне подумалось, что было бы любопытно провернуть такое. Ну а добавить Search ROM совсем не сложно -- надо добавить еще одну машину состояний и использовать те же самые техники отправки данных и считывания ответов.
нужно понимать, чем блокирующий код отличается от неблокирующего. статью на изиэлектрониксе я видел и она ничем не отличается от сотни подобных. в них обычно применяется подход, когда блокируется выполнение остального кода холостыми циклами в ходе проверки некоего флага (busy-wait). фу такое писать в 25-м году.
Добрый день. Есть функция . В ней метка к примеру aaa: . В Си (не переходя в asm) есть возможность определить ее адрес и присвоить глобальной переменной? &aaa не работает. Пишу в IAR.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения