Комментарии 16
Вам бы статью разбить хотя бы на две, длинно очень.
За старания, конечно, плюс… Но все же, раз уж вы столько сил в это вложили — не лучше ли было все-таки довести до ума?) Огромные релюшки вместо транзисторного H-моста убивают)
Циклы для атомарности выглядят жутко, кто вам сказал что чтение/запись обычного инта — не атомарна? Процессор 32-битный, эти операции должны быть атомарными.
Кроме того, почему бы не юзать напрямую регистр-каунтер таймера а не интеррапт и дополнительное прерывание, какой в это вложен смысл?
Ну и внешний декодер DTMF огорчает, СТМка сама вполне справится с этой задачей.
За старания, конечно, плюс… Но все же, раз уж вы столько сил в это вложили — не лучше ли было все-таки довести до ума?) Огромные релюшки вместо транзисторного H-моста убивают)
Циклы для атомарности выглядят жутко, кто вам сказал что чтение/запись обычного инта — не атомарна? Процессор 32-битный, эти операции должны быть атомарными.
Кроме того, почему бы не юзать напрямую регистр-каунтер таймера а не интеррапт и дополнительное прерывание, какой в это вложен смысл?
Ну и внешний декодер DTMF огорчает, СТМка сама вполне справится с этой задачей.
Спасибо за проявленный интерес!
Я долго думал, как оправдать, почему так длинно, но… не придумал. В крайнем случае, всегда можно прочитать в несколько подходов, на 5 глав разбил предусмотрительно. Я ж описывал, чтоб любой повторить мог…
Даже если довести эту машинку до ума, она будет хуже и дороже машинки из Окея за 700 рублей. Задачей было освоить микроэлектронику и получить некий результат, в дальнейшем использовать опыт и доводить до ума уже то, чем можно будет реально пользоваться. Транзисторы были куплены, но не заработали (хотя и грелись). Готовый Н-мост дороговат.
В «Задаче 8» приведён код (2-й по счёту), который докажет, что иногда чтение/запись не атомарны (условие выхода не срабатывает).
Искал как использовать регистр-счётчик, не нашёл. Решил не тратить время на правильность, т. к. этого (без кода) никто не оценит.
DTMF уже проверен и работает, и я, опять-таки для быстрого получения результата, решил не заморачиваться с программированием его внутрь STM.
Я долго думал, как оправдать, почему так длинно, но… не придумал. В крайнем случае, всегда можно прочитать в несколько подходов, на 5 глав разбил предусмотрительно. Я ж описывал, чтоб любой повторить мог…
Даже если довести эту машинку до ума, она будет хуже и дороже машинки из Окея за 700 рублей. Задачей было освоить микроэлектронику и получить некий результат, в дальнейшем использовать опыт и доводить до ума уже то, чем можно будет реально пользоваться. Транзисторы были куплены, но не заработали (хотя и грелись). Готовый Н-мост дороговат.
В «Задаче 8» приведён код (2-й по счёту), который докажет, что иногда чтение/запись не атомарны (условие выхода не срабатывает).
Искал как использовать регистр-счётчик, не нашёл. Решил не тратить время на правильность, т. к. этого (без кода) никто не оценит.
DTMF уже проверен и работает, и я, опять-таки для быстрого получения результата, решил не заморачиваться с программированием его внутрь STM.
Лучше все таки разбить на пару статей, несмотря на главы тяжело воспринимается.
Довести до ума не в смысле до «машинки из окея», а в смысле до более красивых решений — как раз ради освоения.
Нет, для первого эксперимента неплохо, но все таки, раз уж вы так за нее взялись — ну заставили бы мосты работать. Как вы их там подключили? Я подозреваю, что задержки между переключениями транзисторов не вставили, и открывали одновременно верхний и нижний, вот они и выгорали.
Насчет кода — это, скорее всего, какие-то ваши ошибки, gcc генерит вполне себе атомарный код на подобное, только что проверил:
Это как раз «присвоить локальной переменной значение глобальной», они оба интовые. Он вон вообще регистр заюзал для хранения. Вон этот LDR.W — это операция загрузки 32-битного значения из памяти, она не может быть прервана интерраптом.
Регистр счетчик — а чего его использовать, это просто регистр вашего таймера,
Это же не для того чтобы кто-то оценил, это как раз чтобы научиться.
Ну да, декодить будет несколько потруднее, чем просто дрыгать ногами GPIO, но тоже полезный опыт.
Довести до ума не в смысле до «машинки из окея», а в смысле до более красивых решений — как раз ради освоения.
Нет, для первого эксперимента неплохо, но все таки, раз уж вы так за нее взялись — ну заставили бы мосты работать. Как вы их там подключили? Я подозреваю, что задержки между переключениями транзисторов не вставили, и открывали одновременно верхний и нижний, вот они и выгорали.
Насчет кода — это, скорее всего, какие-то ваши ошибки, gcc генерит вполне себе атомарный код на подобное, только что проверил:
LDR R3, =_edata
LDR.W R8, [R3]
Это как раз «присвоить локальной переменной значение глобальной», они оба интовые. Он вон вообще регистр заюзал для хранения. Вон этот LDR.W — это операция загрузки 32-битного значения из памяти, она не может быть прервана интерраптом.
Регистр счетчик — а чего его использовать, это просто регистр вашего таймера,
uint32_t tmp = TIM6->CNT;
Это же не для того чтобы кто-то оценил, это как раз чтобы научиться.
Ну да, декодить будет несколько потруднее, чем просто дрыгать ногами GPIO, но тоже полезный опыт.
Я подключал проводками вручную, без STM, грелись даже при правильном подключении. Один раз получилось шевелить моторчик, когда по два параллельно транзистора воткнул. Но у меня их было всего 3 пары, поэтому даже на один мотор этого бы не хватило.
Схема, например, такая:
Спасибо. С LDR буду разбираться.
Получается, можно при достижении определённого значения счётчика обнулять его прямо в главном цикле? Тогда прерывания точно не нужны.
Схема, например, такая:

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

и подтянуть их к каким-то начальным значениям? Например, оба сигнала к земле.
Мне что-то кажется, что вы успели пожечь транзисторы, пока с проводками возились.
Иначе все должно работать. Да, и какие были резисторы в базах? Не великоваты?
Да, счетчик можно обнулять прямо в главном цикле. Ситуация, когда «половина числа записалась, половина нет» возможно только если оно записывается несколькими mov — например, если это 32-битное значение записывается 8-битной AVRкой.

и подтянуть их к каким-то начальным значениям? Например, оба сигнала к земле.
Мне что-то кажется, что вы успели пожечь транзисторы, пока с проводками возились.
Иначе все должно работать. Да, и какие были резисторы в базах? Не великоваты?
Да, счетчик можно обнулять прямо в главном цикле. Ситуация, когда «половина числа записалась, половина нет» возможно только если оно записывается несколькими mov — например, если это 32-битное значение записывается 8-битной AVRкой.
Это ведь мост из 4-х NPN-транзисторов. В указанной мной схеме нужно подключить одну базу к земле, вторую — к «плюсу». Остальные две базы можно оставить в подвешенном состоянии, как написано в источнике.
Также пробовал эту схему. Работает отлично, но только на светодиодах.
Резисторы тоже пробовал разные. Из спецификации следует, что коэффициент усиления по току 10-25 (если я правильно понял). Сопротивление мотора в покое — 4 Ома. Получается, резистор нужен около 40 Ом? Тогда нужно ещё по транзистору на вход, чтобы микроконтроллер не мучить. Сейчас попробую.
Кстати, цоканье реле помогает при отладке…
Но ведь в следующем коде
переменная todisp постепенно увеличивается. Отчего же?
Также пробовал эту схему. Работает отлично, но только на светодиодах.
Резисторы тоже пробовал разные. Из спецификации следует, что коэффициент усиления по току 10-25 (если я правильно понял). Сопротивление мотора в покое — 4 Ома. Получается, резистор нужен около 40 Ом? Тогда нужно ещё по транзистору на вход, чтобы микроконтроллер не мучить. Сейчас попробую.
Кстати, цоканье реле помогает при отладке…
Но ведь в следующем коде
do
{
sti=ti;
todisp++;
} while (ti>1+sti);
todisp--;
переменная todisp постепенно увеличивается. Отчего же?
В воздухе лучше не бросать, это не полевики, конечно, но лучше если неподключенные базы будут подтянуты. Сколько моторы у вас под нагрузкой потребляют?
Вот, допустим — прямо на ваших транзисторах

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

Они у вас, видимо, не открываются до конца, вот и греются. Вы поглядите, тут им на базу подают 12 вольт через 1 КОм. У них по даташиту падение на Б-Э — до 1.2В аж.
По поводу кода — не знаю, честно говоря не охота в это лезть. Вероятно, из-за того, что прерывание приходит в момент ваших вайлов и инкрементов.
Такого эффекта, какого вы боитесь, с записью половины нового и половины старого значения, код точно не даст.
Я ещё раз попробовал с четырьмя транзисторами, базы подключал через 37 Ом — очень греются резисторы, мотор работает; 100 Ом — резисторы греются меньше, мотор работает; 1 кОм — не греются, но мотор работает только без нагрузки. PNP пару раз перегревался.
По Вашей последней схеме собрал, только вместо 12 Вольт — 4AA аккумулятора, вместо 47 Ом — 37. Всё работает, не греется, даже если вместо «нуля» просто подвешивать. Красота, в общем:
Раньше не получалось… Вот он, Хабраэффект!
Надо попробовать на полевых собрать, там вроде меньше отопления.
С прерываниями ещё поэкспериментирую.
Ещё раз спасибо!
По Вашей последней схеме собрал, только вместо 12 Вольт — 4AA аккумулятора, вместо 47 Ом — 37. Всё работает, не греется, даже если вместо «нуля» просто подвешивать. Красота, в общем:

Раньше не получалось… Вот он, Хабраэффект!
Надо попробовать на полевых собрать, там вроде меньше отопления.
С прерываниями ещё поэкспериментирую.
Ещё раз спасибо!
А с чего им быть атомарными. Load-Store еще никто не отменял. Атомарность может быть гарантирована только организационно. Ну или если писать на ассемблере.
Не в смысле инкремент атомарен, а в смысле что не может быть такой ситуации, что пара байт уже записалась из нового, а пара осталась из старого значения, как на АВРках, когда работают с 32-битными значениями.
То бишь сама операция LDR.W(STR.W) не может быть прервана на середине интерраптом, когда она уже перенесла один-два байта, а остальные не успела.
А между LDR.W, инкрементом и STR.W конечно может вклинится интеррапт, только тут это ни к чему ужасному не приведет, ну выполнится цикл лишний раз.
То бишь сама операция LDR.W(STR.W) не может быть прервана на середине интерраптом, когда она уже перенесла один-два байта, а остальные не успела.
А между LDR.W, инкрементом и STR.W конечно может вклинится интеррапт, только тут это ни к чему ужасному не приведет, ну выполнится цикл лишний раз.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Программируемый микроконтроллер STM32 — с места в карьер