Pull to refresh

Comments 16

Вам бы статью разбить хотя бы на две, длинно очень.
За старания, конечно, плюс… Но все же, раз уж вы столько сил в это вложили — не лучше ли было все-таки довести до ума?) Огромные релюшки вместо транзисторного H-моста убивают)
Циклы для атомарности выглядят жутко, кто вам сказал что чтение/запись обычного инта — не атомарна? Процессор 32-битный, эти операции должны быть атомарными.
Кроме того, почему бы не юзать напрямую регистр-каунтер таймера а не интеррапт и дополнительное прерывание, какой в это вложен смысл?

Ну и внешний декодер DTMF огорчает, СТМка сама вполне справится с этой задачей.
Спасибо за проявленный интерес!
Я долго думал, как оправдать, почему так длинно, но… не придумал. В крайнем случае, всегда можно прочитать в несколько подходов, на 5 глав разбил предусмотрительно. Я ж описывал, чтоб любой повторить мог…

Даже если довести эту машинку до ума, она будет хуже и дороже машинки из Окея за 700 рублей. Задачей было освоить микроэлектронику и получить некий результат, в дальнейшем использовать опыт и доводить до ума уже то, чем можно будет реально пользоваться. Транзисторы были куплены, но не заработали (хотя и грелись). Готовый Н-мост дороговат.

В «Задаче 8» приведён код (2-й по счёту), который докажет, что иногда чтение/запись не атомарны (условие выхода не срабатывает).

Искал как использовать регистр-счётчик, не нашёл. Решил не тратить время на правильность, т. к. этого (без кода) никто не оценит.

DTMF уже проверен и работает, и я, опять-таки для быстрого получения результата, решил не заморачиваться с программированием его внутрь STM.
Лучше все таки разбить на пару статей, несмотря на главы тяжело воспринимается.
Довести до ума не в смысле до «машинки из окея», а в смысле до более красивых решений — как раз ради освоения.
Нет, для первого эксперимента неплохо, но все таки, раз уж вы так за нее взялись — ну заставили бы мосты работать. Как вы их там подключили? Я подозреваю, что задержки между переключениями транзисторов не вставили, и открывали одновременно верхний и нижний, вот они и выгорали.

Насчет кода — это, скорее всего, какие-то ваши ошибки, gcc генерит вполне себе атомарный код на подобное, только что проверил:

LDR     R3, =_edata
LDR.W   R8, [R3]


Это как раз «присвоить локальной переменной значение глобальной», они оба интовые. Он вон вообще регистр заюзал для хранения. Вон этот LDR.W — это операция загрузки 32-битного значения из памяти, она не может быть прервана интерраптом.

Регистр счетчик — а чего его использовать, это просто регистр вашего таймера,

uint32_t tmp = TIM6->CNT;


Это же не для того чтобы кто-то оценил, это как раз чтобы научиться.
Ну да, декодить будет несколько потруднее, чем просто дрыгать ногами GPIO, но тоже полезный опыт.
Я подключал проводками вручную, без STM, грелись даже при правильном подключении. Один раз получилось шевелить моторчик, когда по два параллельно транзистора воткнул. Но у меня их было всего 3 пары, поэтому даже на один мотор этого бы не хватило.

Схема, например, такая: image

Спасибо. С LDR буду разбираться.

Получается, можно при достижении определённого значения счётчика обнулять его прямо в главном цикле? Тогда прерывания точно не нужны.
А вы не забыли соединить базы (как, например, вот тут)

image
и подтянуть их к каким-то начальным значениям? Например, оба сигнала к земле.
Мне что-то кажется, что вы успели пожечь транзисторы, пока с проводками возились.
Иначе все должно работать. Да, и какие были резисторы в базах? Не великоваты?

Да, счетчик можно обнулять прямо в главном цикле. Ситуация, когда «половина числа записалась, половина нет» возможно только если оно записывается несколькими mov — например, если это 32-битное значение записывается 8-битной AVRкой.
Это ведь мост из 4-х NPN-транзисторов. В указанной мной схеме нужно подключить одну базу к земле, вторую — к «плюсу». Остальные две базы можно оставить в подвешенном состоянии, как написано в источнике.
Также пробовал эту схему. Работает отлично, но только на светодиодах.

Резисторы тоже пробовал разные. Из спецификации следует, что коэффициент усиления по току 10-25 (если я правильно понял). Сопротивление мотора в покое — 4 Ома. Получается, резистор нужен около 40 Ом? Тогда нужно ещё по транзистору на вход, чтобы микроконтроллер не мучить. Сейчас попробую.
Кстати, цоканье реле помогает при отладке…

Но ведь в следующем коде
do { sti=ti; todisp++; } while (ti>1+sti); todisp--;
переменная todisp постепенно увеличивается. Отчего же?
В воздухе лучше не бросать, это не полевики, конечно, но лучше если неподключенные базы будут подтянуты. Сколько моторы у вас под нагрузкой потребляют?
Вот, допустим — прямо на ваших транзисторах

image

Они у вас, видимо, не открываются до конца, вот и греются. Вы поглядите, тут им на базу подают 12 вольт через 1 КОм. У них по даташиту падение на Б-Э — до 1.2В аж.

По поводу кода — не знаю, честно говоря не охота в это лезть. Вероятно, из-за того, что прерывание приходит в момент ваших вайлов и инкрементов.
Такого эффекта, какого вы боитесь, с записью половины нового и половины старого значения, код точно не даст.
Я ещё раз попробовал с четырьмя транзисторами, базы подключал через 37 Ом — очень греются резисторы, мотор работает; 100 Ом — резисторы греются меньше, мотор работает; 1 кОм — не греются, но мотор работает только без нагрузки. PNP пару раз перегревался.

По Вашей последней схеме собрал, только вместо 12 Вольт — 4AA аккумулятора, вместо 47 Ом — 37. Всё работает, не греется, даже если вместо «нуля» просто подвешивать. Красота, в общем: image
Раньше не получалось… Вот он, Хабраэффект!

Надо попробовать на полевых собрать, там вроде меньше отопления.

С прерываниями ещё поэкспериментирую.
Ещё раз спасибо!

А с чего им быть атомарными. Load-Store еще никто не отменял. Атомарность может быть гарантирована только организационно. Ну или если писать на ассемблере.
Не в смысле инкремент атомарен, а в смысле что не может быть такой ситуации, что пара байт уже записалась из нового, а пара осталась из старого значения, как на АВРках, когда работают с 32-битными значениями.

То бишь сама операция LDR.W(STR.W) не может быть прервана на середине интерраптом, когда она уже перенесла один-два байта, а остальные не успела.

А между LDR.W, инкрементом и STR.W конечно может вклинится интеррапт, только тут это ни к чему ужасному не приведет, ну выполнится цикл лишний раз.
Если свежий CoIDE в винде не шьет и ругается на конфиг или кабель, то ему нужно в папке %path_to_coide%\bin заменить файл STLinkUSBDriver.dll на этот.
от души благодарю) шил через st-link utility довольно долгое время))
UFO just landed and posted this here
Согласен. Так же как и не даст возможности регулировать угол поворота или обороты двигателя.

Но ведь с программируемым микроконтроллером машинка может и сама проходить трассу, не так ли?..
UFO just landed and posted this here
Так-то всего сразу не попробовать! Но я учту, спасибо.
Sign up to leave a comment.

Articles