• Объявления

    • admin

      Просьба всем принять участие!   24.11.2017

      На форуме разыгрывается спектроанализатор Arinst SSA-TG LC (цена 18500 руб). Просьба всем перейти по ссылке ниже и принять участие!
GDK

Советы для грамотной архитектуры прошивки.

32 сообщения в этой теме

GDK    2

Здравствуйте.

Есть желание делать прошивки более-менее грамотно. Чтобы не изобретать велосипедов хотелось бы увидеть советы, может быть ссылки на к-либо статьи.

Я начал делать таймер для водяного насоса, вот на этом подопытном кролике и будет конкретика. Что собираюсь в него впихнуть и зачем:

1. Выход на одно реле. Оно и будет управлять насосом (~240 Вт.)

2. Дисплей - 2 модуля, каждый из 3х 8ми сегментных цифр, внутри модуля соединены для динамической индикации, т.е. 11ти ногие. Показывать будет время в часах/мин/сек ну и закорючки для индикации режимов.

3. Клавиатура - матрица 3*4. Настройка таймера/запуск/остановка.

4. Пищалка - динамик 8 Ом. Для звуковых сигналов о состоянии и при настройке таймера.

5. [Датчик тока/напряжения] его может быть и не стану делать, назначение - косвенно определять количество перекачанной воды, определять отсутствие воды в скважине.

 

Плата готова уже, МК выбран 16LF1823 (на глазок, т.к. они уже есть и задача вроде как не сложная). Дисплей тоже готов и проверян средним пальцем левой ноги )) состоит из ключа подачи питания, 3х микросхем (8 D-триггеров каждая), из которых получился длинный сдвиговый регистр, ну и самих цифр, о которых уже написал. Получилось 3 входа: Power ON,  Clk,  Data, ну и питание +  - .

Планируется 4 программы работы: 1)-бесконечная работа с перерывами на восстановление скважины;   2)-30л;    3)-10л;     4)-по времени с клавиатуры.

2 и 3 можно настроить с клавиатуры, вход в режим настройки - долгим удержанием кнопки "OK", настройку можно проводить и в режиме, когда уже идёт перекачка. Запуск 2 коротким нажатием кнопки "отмена", 3 - кнопки "ОК". Запуск по времени просто вводом цифр, перед запуском анализ - если <10 сек, то это не секунды, а минуты. В процессе перекачки звуковые сигналы. После запуска перекачки дисплей гаснет по истечении некоторого времени, для включения - нажать любую кнопку из некоторой группы.

По истечении времени перекачки - пикалка звуковой сигнал в теч. некоторого времени, затем выключение в спящий режим.

Собираюсь задействовать DAC для пищалки (синусоиду слушать приятнее, чем меандр имхо), для дисплея - SPI, для задержек всяких разных - аппаратный таймер, если будет не лень, хватит ресурсов и вообще звёзды сойдутся, то может ещё ADC понадобится.

Получается будут параллельно выполняться функции:

1. опрос клавиатуры

2. индикация

3. звук

4. расчёт оставшегося времени, либо ожидание запуска

Делать собираюсь на С с компилятором XC8.

Вопрос  с чего нАчать. Ну решил начать с алгоритмма, понял что нужны будут отрезки времени со стабильной длительностью/периодичностью, и для отсчёта самих интервалов работы насоса и для опроса клавиатуры и для звука и для дисплея. Посоветуйте где что почитать, чтобы отстойный код не получился. Сейчас есть мысль что понадобится делать программные таймеры и возможно будет желательно конечные автоматы использовать, о которых почти ничего не знаю. По программным таймерам нашёл статью http://chipmk.ru/index.php/spisok-statej/24-uchimsya-programmirovat/120-programmnye-tajmery-na-assemblere,  но она на асме, зато показалась хорошей. Есть разные и статьи и литература для начинающих, но там обычно как диодиком помигать, что такое МК и т.п., как правильно делать с точки зрения ресурсов МК, возможности корректировки кода в будущем, добавлении нового функционала мало где встречается, поэтому и нужны советы. Сейчас вопросы - не маловато ли ресурсов у выбранного МК для моих хотелок, как делать программные таймеры и почему они работают с точной периодичностью независимо от основной программы, действительно ли мне нужны конечные автоматы. В общем то разбираться планирую как можно больше самостоятельно, но просьба указать направление, в котором надо самопнуться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
Alex    525

Правильно мыслим по таймерам и автоматам.
По программным таймерам на Си, там же - http://forum.chipmk.ru/index.php/topic/146-программные-таймеры/

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    268
6 часов назад, GDK сказал:

Получается будут параллельно выполняться функции:

1. опрос клавиатуры

2. индикация

3. звук

4. расчёт оставшегося времени, либо ожидание запуска

В вашей концепции только индикация должна выполняться параллельно с остальными задачами, так как реализуется динамически и любая пауза в ее работе будет видна пользователю. Думаю, объяснить, по какой причине остальные "задачи" должны выполняться параллельно друг другу, вы не сумеете... Особенно смешно выглядит параллельное ожидание запуска :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
GDK    2

Хоть попробую.

Работа с клавиатурой должна быть доступна когда угодно, во время перекачки можно например настраивать параметры "избранных"  действий. Это 30л и 10л. Например чтобы перенастроить 10л на 15л. Или, например, чтобы немедленно отменить текущую перекачку без выдёргивания вилки из розетки.

Ожидание может и смешно, но с точки зрения насоса - либо перекачка, либо ожидание запуска, либо сдох нафих ^_^. Ну а в процессе перекачки может быть буду считать скока литров, аднака. Может через 30 сек. какой-нибудь дятел включит козла и напряжение станет вместо 220 - 170? Значит придётся увеличить время на какое-то значение. Т.е. прилепить ещё датчик тока и "интегрировать" ток, пока не накопится заданное значение. И это не должно мешать опросу клавиатуры.

Звук - ну может мне не хочется, чтобы "в траве сидел кузнечик" прерывалось, когда я тыкаю на кнопочки.

Не убедил?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
semic    23

Для начала лучше светодиодиком помигать, а потом 2 диодиками, потом кнопку подключить и потом возможно придет понимание как МК работает.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
GDK    2

Диодиками мигалось уже, даташиты курились, понимание есть.  Вопрос в том, чтобы сделать не как-нибудь, а хотя бы более-менее грамотно.

Как ходят ладьи с конями знаю, но как из этого получить выигранные партии  - представления пока что совсем смутные, отсюда и тема.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alex    525

Дак Вы начните, а там по-ходу всё решится... :)


 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
GDK    2

Уже начал. Ну с прерываниями вроде бы уже проясняется, с автоматами пока туговато. Инфы слишком много знает гугл, а это, при определённых условиях, - то же самое что её отсутствие.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alex    525

По-простому, автомат - это примитивный планировщик, который циклически, по очереди или по событиям, вызывает определённые функции.
Ещё автоматом иногда считают машину состояний, основой которой является switch-case.

Вообще, на сколько мне известно, инфа есть в интернете по этой теме.
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
GDK    2

Да, и немало, вот и пытаюсь разобраться в этои инфе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    268
5 часов назад, GDK сказал:

Не убедил?

НЕ убедил. 

Обычно все рассуждают так, как вы. Однако, если динамическую индикацию задержать на 0,1 секунды, вы увидите, как индикатор мигнет. А если кнопку нажать на 0,1 сеунды позже, или там реле у вас сработает на 0,1 секунды позже, или датчик - никто вообще не заметит. Именно поэтому индикация должна работать ПАРАЛЛЕЛЬНО с остальными задачами, а остальные задачи МОГУТ работать ПОСЛЕДОВАТЕЛЬНО, только быстро-быстро :) Быстренько опросили кнопки, быстренько отреагировали на датчики, быстренько обновили дисплей и снова быстренько опрашиваем кнопки. За 0,1 секунды эта последовательность у вас раз 10 отработает запросто.

В этом случае все выглядит ГОРАЗДО проще, чем когда все процессы работают одновременно.

Изменено пользователем ARV

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
oldmao    1 310

Я делаю так: прерывание по аппаратному таймеру каждые 20 миллисекунд (частота получается 50 Гц), загружаем очередную цифру в 74HC595 и переключаем аноды (или катоды) индикатора. К общим анодам (или катодам) подключены и кнопки (по количеству цифр, у меня их 4), подающие при нажатии сигнал на вход МК. Не забывайте подтянуть вход (к минусу при общих анодах или к плюсу при общих катодах). Этот вход проверяется в этом же прерывании. Состояние кнопок сохраняем в глобальной переменной, из глобальных же переменных берётся и значение для индикации (готовый байт для засылки в 74HC595). Ничего больше в прерывании не делаем, поэтому оно выполняется быстро. А дальше уже в основном цикле сначала обрабатываем состояние кнопок, затем формируем индикацию, опрашиваем датчики (если есть) и всё прочее. По такому принципу у меня работают часы-будильник-таймер с термометром. При тактовой 8 МГц у меня процессор в основном простаивал, ожидая прерывания. Снизил тактовую до 1 МГц для уменьшения энергопотребления.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vovka    23
В 20.04.2017 в 00:31, GDK сказал:

Я начал делать таймер для водяного насоса...

Ну не знаю зачем такой "огород" городить, я поступил намного проще: Двухрежимная автоматическая водокачка

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
GDK    2

@Вуйко  Ага, эти материалы и начал читать вчера.

17 часов назад, ARV сказал:

Быстренько опросили кнопки, быстренько отреагировали на датчики, быстренько обновили дисплей и снова быстренько опрашиваем кнопки. За 0,1 секунды эта последовательность у вас раз 10 отработает запросто.

1. А звук? Если, допустим, мне хочется иметь возможность пищать синусоиду до 10кГц, или произвольной формы сигнал выдавать с помощью DAC (он 5 разрядный).

2. Я почему то изначально не был уверен в том, что всё будет успеваться, да и сейчас тоже. Для комфортной работы с клавиатурой 4х3 какой период опроса надо будет сделать, может придётся 1мс?

9 часов назад, oldmao сказал:

К общим анодам (или катодам) подключены и кнопки (по количеству цифр, у меня их 4),

Я тоже так хотел сначала, но у меня предусмотрено гашение дисплея снятием питания с него, а при этом клавиатуру опрашивать надо, чтобы я мог "разбудить" устройство, ножек у МК как бы хватало, решил не отказываться от возможности обесточить дисплей полностью.

А как у Вас устроен интидребезг?

 

9 часов назад, oldmao сказал:

При тактовой 8 МГц у меня процессор в основном простаивал, ожидая прерывания. Снизил тактовую до 1 МГц для уменьшения энергопотребления.

У меня другой подход - всё быстро сделал, и спать. Проснулся по прерыванию от таймера, разобрался с делами, и опять баиньки.  Вот и думаю встроенный RC генератор попробовать на 16 МГц запустить или на 8...

8 часов назад, Vovka сказал:

Ну не знаю зачем такой "огород" городить

Не хочу проводов от датчиков и бочку, хочу наливать сколько хочу, хочу перехотеть когда захочу, хочу наливать где захочу, хочу уходить когда захочу... Короче гибкость.

 

И вот тут я кажется понял, что тупанул - 6 цифр на дисплее сделал для настройки в чч.мм.сс, а можно было тупо 3 цыфры и настройку в литрах...

Изменено пользователем GDK

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 103
Только что, GDK сказал:

А звук? Если, допустим, мне хочется иметь возможность пищать синусоиду до 10кГц,

 

http://www.pic24.ru/doku.php/osa/articles/pk2_osa_piano

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
oldmao    1 310
14 минуты назад, GDK сказал:

А как у Вас устроен интидребезг?

Три переменных в прерывании: текущее значение кнопок, счётчик и глобальная переменная состояния кнопок. Если текущее состояние кнопок не совпадает с глобальной переменной, то инкременируем счётчик. Если совпадает - счётчик обнуляем. Если счётчик равен 10, то переписываем текущее значение в глобальную переменную, счётчик обнуляем. Таким образом реакция на нажатие кнопки 200 мс. Длинное-короткое нажатие определяет логика в основном цикле.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
GDK    2

@IMXO , там 3 октавы, я не разбираюсь в этом, это до 2 кГц? Ну и МК там... напр.   14кбайт - память программ, 368 байт - опер. память, а у меня 4к и 168 байт соответственно. Там ОСРВ, в мой МК наверное не влезет.

Только что, oldmao сказал:

Таким образом реакция на нажатие кнопки 200 мс.

200мс. Довольно таки долго. Ну и как получается по ощущениям, комфортно? Нет ощущения, что клавиатура не успевает обрабатывать короткие нажатия и надо давить "как следует" ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
oldmao    1 310

Удобно, задержка в 0,2 секунды не ощущается совсем. Это же не клавиатура компьютера, скоростной набор не требуется. Длительное нажатие у меня 2 секунды, это вход в режим установки часов. 

PS В одном проекте у меня опрос кнопок вообще 0,5 сек (правда антидребезг аппаратный), с такой же скоростью автоповтор. Привыкаешь быстро, даже удобно, на случайные нажатия не реагирует.

Изменено пользователем oldmao

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
КЭС    978
1 час назад, GDK сказал:
12 часа назад, oldmao сказал:

К общим анодам (или катодам) подключены и кнопки (по количеству цифр, у меня их 4),

Я тоже так хотел сначала, но у меня предусмотрено гашение дисплея снятием питания с него, а при этом клавиатуру опрашивать надо

Гасить можно сегменты, активный уровень по разрядам индикатора пусть гоняется.ю чтобы кнопки опрашивать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    268
12 часа назад, GDK сказал:

Если, допустим, мне хочется иметь возможность пищать синусоиду до 10кГц

Если, если... если вам хочется добиться постановки неразрешимых в рамках выбранной платформы задач, это всегда можно сделать. Нет такого процессора, чтобы для него нельзя было придумать неразрешимую задачу. Вы этого хотите?

Но если и в самом деле нужен звук, он делается так же, как динамическая индикация - фоновым процессом. Просто лично я не понимаю стремления все делать "незаметно", т.е. параллельно с чем-то. С чем параллельно, если все прячется? Кнопки, датчики и многое другое вовсе не обязательно должно делаться в фоне.

Я вот сейчас увлекся цветомузыкой, (см. видео первой пробы, сейчас все гораздо лучше), так вот, вы не поверите, там нет ни одной параллельной задачи, все делается последовательно! Причем, хоть на видео этого не видно, есть энкодер и ЖКИ: энкодер обрабатывается "одновременно" (внешне, а по факту - по опросу "последовательно") с индикацией на ЖКИ спектра сигнала, и 32 штуки WS2812 при этом мерцают вовсю... И, хотя задержек в коде много, ни одного таймера для этого напрямую не задействовано (ну, почти...).

Скачать видео

Вот то самое видео...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
oldmao    1 310

На самом деле любая многозадачность на AVR - это в первую очередь грамотное планирование последовательности задач. Почитайте про ОС реального времени для AVR (это одна из многих существующих, но принцип работы расписан хорошо). Для 95% задач такая сложность ни к чему, критичные к времени части программы (динамическая индикация, опрос кнопок, звук) реализуем в прерываниях по таймеру. Отдельно делаем опрос датчиков, например 1-Wire, где критичны временные интервалы, с запретом остальных прерываний на время работы с датчиком. Это миллисекунды, пропуск даже пары тактов динамической индикации глазом будет не заметен. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
GDK    2
Только что, ARV сказал:

если вам хочется добиться постановки неразрешимых в рамках выбранной платформы задач...

Мне показалось, что 16LF1823 справится. Считаете что вряд ли получится на нём?  Я всё таки попробую, но по остаточному принципу, если будет хватать ресурсов, если не будет хватать, тогда уже урезать хотелки, да. Но дело в том, что не хочется делать задачу невыполнимой, которая в общем то выполнима.  А ещё я стараюсь выключать свет, когда он мне не нужен...

Но тем не менее мысль уловил, ну и выводы сделал, что не обязательно "все косточки выбирать", на некоторые можно и подзабить и хуже не будет.

 

Только что, ARV сказал:

так вот, вы не поверите,...

У меня практически нет опыта работы с МК, поэтому могу поверить во что угодно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
GDK    2
Только что, oldmao сказал:

На самом деле любая многозадачность на AVR МК- это в первую очередь грамотное планирование последовательности задач...

Раньше читал про ОСРВ. И это понятно.

Получается как бы 3 крайности при выборе архитектуры:

  • Просто последовательное выполнение задач
  • Прерывания и конечные автоматы
  • ОСРВ

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    268

Верно, укрупненно так и есть. Я бы добавил примечания:

  • Последовательное выполнение - простое для понимания и реализации, самое то для начинающих
  • Прерывания - простое для понимания, но требующее внимательности к "нюансам" при реализации (например, атомарность доступа к многобайтным переменным и т.п.)
  • Конечные автоматы - сложнее в понимании и реализиации, как по мне, так я бы сказал, что если состояний в автомате больше трех, понять чужую писанину практически невозможно, а в свей перестаешь разбираться при числе состояний больше 6 :)))
  • ОСРВ (вообще "многозадачная" ОС, не обязательно РВ) - это весьма сложная в реализации вещь (если не сторонняя), требующая заметных усилий по привыканию к парадигме многопоточности, расходующая большое количество ресурсов на собственные цели, но после преодоления всех препон, дающая максимальную свободу в программировании.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: gsclock
      Всем привет. Подскажите, пожалуйста, простые статьи по ИИП на английском языке, было бы хорошо если бы были с переводом и подлиннее, задали по английскому языку перевод. Сам я нашел несколько, но возникают проблемы с переводом. Спасибо!
    • Автор: TIGER53501
      Привет, никак не могу разобраться с таймером в режиме сброса по внешнему событию,
      сам сброс работает, таймер сбрасывается, вопрос вот в чём, могу ли я в этом режиме использовать захват на оставшихся каналах?
      т.е. по внешнему событию сбрасывать таймер, и потом внешними событиями записывать сколько он протикал с момента сброса?
      STM32F429ZI
      СИ + VisualGDB + HAL + Cube
    • Автор: balistik
      Всем доброго времени суток. Я реальный нуб в ATMEGA. Могу более-менее понять чужой код и из кусков сделать целое. Вопрос такой: реально ли на ATMEGA8 сделать 2 ШИМ (таймер 1 и2) и внутреннее прерывание (по таймеру 0) для чтения данных с DS18B20 на 8Мгц чтобы еще осталось на опрос кнопок и небольшую логику? Я выложу пример кода. По отдельность: ШИМ, прерывания, логика, запись в ЕПРОМ работает. Собираю все вместе - не работает. Пробовал в Протеусе, тоже глючит, да и протеус тормозит. Может кто чего подскажет.
      //#define F_CPU 8000000UL // устанавливаем рабочую частоту контроллера #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <avr/eeprom.h> #include "ds18x20.h" #include "onewire.h" #define MAXSENSORS 1 unsigned int tempint = 0; // переменная для целого значения температуры unsigned int subzero = 0; // переменная отрицательных значений температуры unsigned int clock = 0; //задержка для опроса датчика температуры unsigned int termo_error = 0; //флаг ошибки термодатчика unsigned char regim, R1_SHIBER, R1_VENT, R2_SHIBER, R2_VENT, R3_SHIBER, R3_VENT; //переменные режимов работы volatile char press = 0, pr = 0, pr1 = 0, set = 0; //дополнительные переменные для кнопок #define SHIBER_PB 1 //шибер подачи топлива #define SHIBER_PWM OCR1A #define VENT_PB 2 //вентилятор подачи воздуха #define VENT_PWM OCR1B #define LED1_ON PORTD |= _BV(PD3) // светодиод режим 1 #define LED1_OFF PORTD &= ~_BV(PD3) #define LED2_ON PORTD |= _BV(PD4) // светодиод режим 2 #define LED2_OFF PORTD &= ~_BV(PD4) #define LED3_ON PORTD |= _BV(PD6) // светодиод режим 3 #define LED3_OFF PORTD &= ~_BV(PD6) #define LED4_ON PORTD |= _BV(PD7) // светодиод 4 программирование #define LED4_OFF PORTD &= ~_BV(PD7) #define BUT_M PIND & (1 << PD1) // кнопка MENU #define BUT_U PIND & (1 << PD2) // кнопка UP #define BUT_D PIND & (1 << PD0) // кнопка DOWN unsigned char eep1 EEMEM; // режим работы unsigned char eep2 EEMEM; // режим 1 ШИМ вентилятор unsigned char eep3 EEMEM; //режим 1 ШИМ шибер unsigned char eep4 EEMEM; // режим 2 ШИМ вентилятор unsigned char eep5 EEMEM; // режим 2 ШИМ шибер unsigned char eep6 EEMEM; // режим 3 ШИМ вентилятор unsigned char eep7 EEMEM; // режим 3 ШИМ шибер unsigned char eep8 EEMEM; // флаг первого запуска uint8_t Temperature, szero; //-255 uint8_t nSensors, j; uint8_t cel_frac_bits; uint8_t gSensorIDs[MAXSENSORS][OW_ROMCODE_SIZE]; uint8_t search_sensors(void) // поиск DS18B20 { uint8_t i; uint8_t id[OW_ROMCODE_SIZE]; uint8_t diff, nSensors; nSensors = 0; for( diff = OW_SEARCH_FIRST; diff != OW_LAST_DEVICE && nSensors < MAXSENSORS ; ) { DS18X20_find_sensor( &diff, &id[0] ); if( diff == OW_PRESENCE_ERR ) { Temperature = 255; szero = 1; break; } if( diff == OW_DATA_ERR ) { Temperature = 255; szero = 1; break; } for (i=0; i<OW_ROMCODE_SIZE; i++) gSensorIDs[nSensors][i]=id[i]; nSensors++; } return nSensors; } void get_temp(int sensor){ // получаем температуру с датчиков DS18X20_start_meas(DS18X20_POWER_EXTERN, NULL); DS18X20_start_meas(DS18X20_POWER_EXTERN, NULL); j = gSensorIDs[0][sensor]; // family-code for conversion-routine if (DS18X20_read_meas_single(j, &szero, &Temperature, &cel_frac_bits) != DS18X20_OK) { //если не прочиталось то -255 Temperature = 255; szero = 1; } if (DS18X20_read_meas_single(j, &szero, &Temperature, &cel_frac_bits) != DS18X20_OK) { //если не прочиталось то -255 Temperature = 255; szero = 1; } tempint=(int)Temperature; subzero=(int)szero; } void pin_init(void) { //инициализация портов ШИМ DDRB |= (1<<SHIBER_PB) | (1<<VENT_PB); PORTB &= ~((1<<SHIBER_PB) | (1<<VENT_PB)); } void timer0_init(void) { //инициализация таймера для термодатчика TCCR0 |= (1<<CS00); TIMSK |= ( 1 << TOIE0); TCNT0 = 0xFF; } void timer1_init(void) { //инициализация таймера ШИМ шибера TCCR1A |= (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10); TCNT1 = 0x00; ICR1 = 0xFF; OCR1A = 0x00; OCR1B = 0x00; } void timer2_init(void) { //инициализация таймера ШИМ вентилятора TCCR2 |= (1 << COM21) | (1 << WGM21) | (1 << WGM20) | (1 << CS20); TCNT2 = 0x00; OCR2 = 0x00; } ISR(TIMER0_OVF_vect){ //прерывание таймера 0 для термодатчика if (clock != 4294967295){_delay_us(50);clock++;}else{get_temp(0);clock=0;} } //***************** обработка нажатия кнопок ********************** void buttons(){ if(~BUT_U){if(set == 0)pr++; // кнопка UP if(pr == 10){ // долгое нажатие } _delay_ms(100); }else{ if(pr >= 1 && pr < 10){ // короткое нажатие regim++; if (regim>3){regim=0;} eeprom_write_byte(&eep1, regim); // сохранение настройки в eeprom set = 0; pr = 0; } pr = 0; } if(~BUT_D){if(set == 0)pr1++; // кнопка DOWN if(pr1 == 10){ // длинное нажатие } _delay_ms(100); }else{ if(pr1 >= 1 && pr1 < 10){ // короткое нажатие. //set = 20; regim--; if (regim<0){regim=3;} eeprom_write_byte(&eep1, regim); // сохранение настройки в eeprom _delay_ms(100); set = 0; pr1 = 0; } pr1 = 0; } if(~BUT_M){ // кнопка MENU press++; if(press == 1 && set != 0){set++;} // переход по настройкам if(press >= 100 && set == 0){set = 1; _delay_ms(200);} // ход в настройки if(set == 1) eeprom_write_byte(&eep2, R1_VENT); if(set == 2) eeprom_write_byte(&eep3, R1_SHIBER); if(set == 3) eeprom_write_byte(&eep4, R2_VENT); if(set == 4) eeprom_write_byte(&eep5, R2_SHIBER); if(set == 5) eeprom_write_byte(&eep6, R3_VENT); if(set == 6) eeprom_write_byte(&eep7, R3_SHIBER); if(set > 6){ _delay_ms(100); set = 0; press = 0;} // если включена настройка даты, }else{ if(set == 0 && press >= 1){ // если не вошли в настройки regim++; if (regim>3){regim=0;} eeprom_write_byte(&eep1, regim); // сохранение настройки в eeprom } press = 0; } } //*****************режим настроек******************** void settings(){ //визуальное подтверждение настроек if(press >= 1 && set == 1) { LED1_ON; LED2_OFF; LED3_OFF; LED4_ON; SHIBER_PWM = R1_VENT;} //ШИМ шибер 0-255 if(press >= 1 && set == 2) { LED1_ON; LED2_OFF; LED3_OFF; LED4_ON; VENT_PWM = R1_SHIBER;} //ШИМ вентилятор 0-255 if(press >= 1 && set == 3) { LED1_OFF; LED2_ON; LED3_OFF; LED4_ON; SHIBER_PWM = R2_VENT;} //ШИМ шибер 0-255 if(press >= 1 && set == 4) { LED1_OFF; LED2_ON; LED3_OFF; LED4_ON; VENT_PWM = R2_SHIBER;} //ШИМ вентилятор 0-255 if(press >= 1 && set == 5) { LED1_OFF; LED2_OFF; LED3_ON; LED4_ON; SHIBER_PWM = R3_VENT;} //ШИМ шибер 0-255 if(press >= 1 && set == 6) { LED1_OFF; LED2_OFF; LED3_ON; LED4_ON; VENT_PWM = R3_SHIBER;} //ШИМ вентилятор 0-255 switch(set) // включена настройка { case 1: // настройка R1_VENT if(~BUT_U){R1_VENT++; if(R1_VENT > 254) R1_VENT = 0; _delay_ms(100);} if(~BUT_D){R1_VENT--; if((~BUT_D) && R1_VENT == 0) R1_VENT = 254; _delay_ms(100);} break; case 2: // настройка R1_SHIBER if(~BUT_U){R1_SHIBER++; if(R1_SHIBER > 254) R1_SHIBER = 0; _delay_ms(100);} if(~BUT_D){R1_SHIBER--; if((~BUT_D) && R1_SHIBER == 0) R1_SHIBER = 254; _delay_ms(100);} break; case 3: // настройка R2_VENT if(~BUT_U){R2_VENT++; if(R2_VENT > 254) R2_VENT = 0; _delay_ms(100);} if(~BUT_D){R2_VENT--; if((~BUT_D) && R2_VENT == 0) R2_VENT = 254; _delay_ms(100);} break; case 4: // настройка R2_SHIBER if(~BUT_U){R2_SHIBER++; if(R2_SHIBER > 254) R2_SHIBER = 0; _delay_ms(100);} if(~BUT_D){R2_SHIBER--; if((~BUT_D) && R2_SHIBER == 0) R2_SHIBER = 254; _delay_ms(100);} break; case 5: // настройка R3_VENT if(~BUT_U){R3_VENT++; if(R3_VENT > 254) R3_VENT = 0; _delay_ms(100);} if(~BUT_D){R3_VENT--; if((~BUT_D) && R3_VENT == 0) R3_VENT = 254; _delay_ms(100);} break; case 6: // настройка R3_SHIBER if(~BUT_U){R3_SHIBER++; if(R3_SHIBER > 254) R3_SHIBER = 0; _delay_ms(100);} if(~BUT_D){R3_SHIBER--; if((~BUT_D) && R3_SHIBER == 0) R3_SHIBER = 254; _delay_ms(100);} break; } } int main(){ /*******************************настройка переферии******************************/ cli(); ow_set_bus(&PIND, &PORTD, &DDRD, PD5); // иництализация протокола 1-wire nSensors = search_sensors(); // поиск датчиков DS18B20 DS18X20_start_meas(DS18X20_POWER_EXTERN, NULL); //включаем преобразование температуры pin_init(); //timer0_init(); timer1_init(); timer2_init(); _delay_ms(5); if(eeprom_read_byte(&eep8) != 1){ // читаем eeprom, если там мусор (первый запуск), пишем свои данные eeprom_write_byte(&eep1, 0); // режим работы eeprom_write_byte(&eep2, 150); // режим 1 ШИМ вентилятор eeprom_write_byte(&eep3, 100); //режим 1 ШИМ шибер eeprom_write_byte(&eep4, 200); //режим 2 ШИМ вентилятор eeprom_write_byte(&eep5, 150); //режим 2 ШИМ шибер eeprom_write_byte(&eep6, 230); //режим 3 ШИМ вентилятор eeprom_write_byte(&eep7, 200); //режим 3 ШИМ шибер eeprom_write_byte(&eep8, 1); // флаг первого запуска } //читаем настройки из памяти regim = eeprom_read_byte(&eep1); // читаем режим работы из eeprom R1_VENT = eeprom_read_byte(&eep2); // читаем режим 1 ШИМ вентилятор из eeprom R1_SHIBER = eeprom_read_byte(&eep3); //читаем режим 1 ШИМ шибер R2_VENT = eeprom_read_byte(&eep4); //читаем режим 2 ШИМ вентилятор R1_SHIBER = eeprom_read_byte(&eep5); //читаем режим 2 ШИМ шибер R3_VENT = eeprom_read_byte(&eep6); //читаем режим 3 ШИМ вентилятор R1_SHIBER = eeprom_read_byte(&eep7); //читаем режим 3 ШИМ шибер sei(); _delay_ms(5); /**********************************инициализация ШИМ*************************************/ while(1){ //if (tempint=255) {LED1_ON;LED2_OFF;LED3_ON;termo_error=1;} else {termo_error=0;}//выводим код ошибки датчика темппературы buttons();//обработик нажатия кнопок if (termo_error == 0){//блокировка по термодатчику if(set == 0) { //нормальный режим работы if (regim == 0){ //режим работы 0 LED1_OFF; LED2_OFF; LED3_OFF; LED4_OFF; SHIBER_PWM = 0; //ШИМ шибер 0-255 VENT_PWM = 0; //ШИМ вентилятор 0-255 } if (regim == 1){ //режим работы 1 LED1_ON; LED2_OFF; LED3_OFF; LED4_OFF; VENT_PWM = R1_VENT; //ШИМ вентилятор 0-255 if (tempint >=40) { //блокировка по температуре SHIBER_PWM = 0; //ШИМ шибер 0-255 }else{ SHIBER_PWM = R1_SHIBER; //ШИМ шибер 0-255 } } if (regim == 2){ //режим работы 2 LED1_OFF; LED2_ON; LED3_OFF; LED4_OFF; VENT_PWM = R2_VENT; //ШИМ вентилятор 0-255 if (tempint >=60) { //блокировка по температуре SHIBER_PWM = 0; //ШИМ шибер 0-255 }else{ SHIBER_PWM = R2_SHIBER; //ШИМ шибер 0-255 } } if (regim == 3){ //режим работы 3 LED1_OFF; LED2_OFF; LED3_ON; LED4_OFF; VENT_PWM = R3_VENT; //ШИМ вентилятор 0-255 if (tempint >=80) { //блокировка по температуре SHIBER_PWM = 0; //ШИМ шибер 0-255 }else{ SHIBER_PWM = R3_SHIBER; //ШИМ шибер 0-255 } } } }else{ SHIBER_PWM=0; VENT_PWM=0; } if(set != 0) settings();//вход в настройки } //return 0; }  
    • Автор: sdkdenis
      Возник вопрос теории интерпретатора кода микропроцессора микроконтроллером
      Возьмём к примеру, всеми любимый КР580ИК80, (опустим сейчас споры зачем, не хватит скорости и т.д.), интересна теория построения такой «Виртуальной машины».
      В моём понимании алгоритм такой:
      1-      В памяти микроконтроллера создаётся массив с адресами подпрограмм кодов процессора (в нашем случае КР580ИК80);
      2-      Ячейки массива имеют названия идентичные соответствующим командам процессора
      3-      Микроконтроллер выставляет на определённых портах (допустим порт А и В) адрес извлекаемой из внешней памяти команды программы;
      4-      Считывает данные с порта (допустим С);
      5-      Выбирает ячейку массива с именем идентичным считанному значению из порта С;
      6-      Переходит к подпрограмме по адресу записанному в соответствующей ячейке массива;
      7-      В процессе выполнения подпрограммы происходят соответствующие действия и увеличение (или иное изменение) счетчика команд;
      8-      Процесс повторяется с шага 3.
      Так вот если и вправду алгоритм построения данного решения соответствует описанному выше, то у меня возникает вопрос, неужели микроконтроллеру на каждую команду процессора приходится перечёсывать массив ища соответствие, или есть иной путь прямого перехода к соответствующей подпрограмме?
      Возможно я неправильно понимаю реализацию интерпретатора кода микропроцессора микроконтроллером?
    • Автор: KushlaVR
      Здраствуйте. Возникла необходимовсть управления несколькими устройствами разных производителей с помощю одного елемента управления.
      В качестве управлялки нужно использовать Sony RM-X6. и сенсорний монитор с виходом формата NEC (на дисплее есть кнопки и когда в их нажымать - транслирується команда)
      Управление осуществляєтся с помощю устройства (которое мне нежно разработать). С протоколом NEC - разобратся получилось (есть куча примеров).
      А вот протокол Sony rm-X6 темный ящик. Такое ощущение что ето обичний UART...
      Значит вопрос собственно такой:
      1) Помогите распознать что за протокол?
      2) Помогите составить алгоритм по распознанию (контроллер Atmega8 тактовая частота внутреннего генератора 8МГц)
      3)Возможнор ктото уже работал с ним, и готов поделится примерами...
      П.С.
      Усилографа нет... Снял сигнал с помощю звуковой карточки (в формате waw). Результат можна посмотреть вот тут:
      drive.google.com/folderview?id=0B-SmX6iwS8HeT3NYSXlYQzJMY2M&usp=sharing
      (извините, waw не могу прикрепить к теме, потому разшарил папку. Если у модераторов есть возможность, то прикрепите, буду благодарен)
      Спасибо всем за внимание и помощь....
  • Сообщения

    • Крашер, читал. Причем еще давно как-то наткнулся на неё. Помогла другой усилитель оживить. А тут что-то засада. Транзисторы 100 процентов живые.  Ок, завтра уже буду паять цепь обратной связи, сегодня уже поздно. Кстати, вот такой вопрос. Транзистор TR306 который 2sa988 имеет h21 196, хотя по даташиту стандартное значение 500 (в среднем). Это может играть роль?
    • Пробитый переход /обрыв/  и закрытый транзистор... покажут идентичную картинку. У вас пошла "цепная реакция".  Недоустранили причину. Трабл по цепочке - повыбивает всё... до чего "доянется".  Вы статью по ссылке от Доктора внимательно читали? 
    • Оставьте Вы его в покое. Можете вообще закоротить. Это всего лишь двухполюсник смещения и термокомпенсатор.
    • Да, всё верно, нужно подкрутить или, если недостаточно будет, изменить номиналы резисторов. Обычно ещё есть функция "выставить ноль", при помощи замыкания некоторых выводов на плате. На этой, к примеру, A и B. Ну это так, для размышлений(если ноль "уйдёт", можно попробовать через резистор замкнуть диагностические пятаки). По принципу, выключил - замкнул - включил - выключил, разомкнул, ноль выставлен, готово!
    • По дифкаскаду все ок, я выше схему с текущими напряжениями выложил, гляньте если не лень. так нагляднее будет   Спасибо, Finn32, за подсказки. Завтра уже буду восстанавливать обратную связь и проверять сопротивления в этой цепи. Т.е. из ее отсутствия не будет держаться ноль и баланс напряжений на TR314? Извините за возможно глупые вопросы, я в электронике недавно и хочется разобраться
    • Может. Ноль на выходе нечему держать. Смотрите дифкаскад. Нет.
    • Транзисторы усе проверены и даже подобраны. Если восстановлю ОС на базу TR304, то туда полетит -50в через R316 и R314, правильно? А приходить должен как-бы ноль? Это не чревато потерей транзистора?