Сообщение между МК

Тема в разделе "Микроконтроллеры AVR", создана пользователем DrProg, 16 дек 2015.

  1. DrProg

    DrProg Вечный нерд

    Задача такая: Есть Атмега8 (за главного), есть Аттини2313 (вспомогательный). Из Атмеги нужно периодически передавать данные в виде цифр от 0 до 9, Аттиней принимать их и совершать соответствующие действия.

    Проблема в том, что Аттиня не поддерживает аппаратные протоколы SPI и I2C (несмотря на то, что пины для этого как бы есть), а саофтверный UART, который я применял для связи между Атмегами в скромную память Аттини2313 просто не влазит. Воссоздавать упомянутые протоколы на низком уровне, тем более с обоих сторон, тем более без гарантий что влезет, я пока не готов.

    Напрашивается какое то простое решение, но оно не сформулируется. Может быть сделать свой упрощенный протокол обмена? Может быть есть готовое решение? Гуглование успехом не увенчалось. Нужна поддержка опытом.
     
    ИгорьК нравится это.
  2. Alex19

    Alex19 Гуру

    Я не работаю с данными AVR, поэтому мои размышления теоретические.

    Оба эти контролера имеют UART, с поддержкой прерываний. Сколько у Вас свободной памяти?
    Могу вытянуть из своей реализации (Multiwii + хорошие идеи из Arduino Serial), она для Atmega328p на прерываниях, кольцевом буфере, с передачей пакетов. Реализация должна быть идентична, может быть не большие различия в регистрах. Но это ближе к вечеру.

    Так же можно попробовать сделать реализацию на OneWire. Реализация мастера - http://chipenable.ru/index.php/prog...ioteka-dlya-raboty-s-1-wire-ustroystvami.html. Реализации слейва придется поискать.

    И прерываниях, то есть дергать ножками, таких реализаций еще не встречал (ни когда не искал).
     
  3. соединить 4 ноги, на них сделать параллельный интерфейс )
     
  4. Radius

    Radius Гик

    Можно вспомнить старый самосинхронизирующийся протокол когда битовый интервал делился на три части. Ноль передавался высоким уровнем занимающим первую треть, единица передавалась высоким уровнем занимающим первую и вторую треть битового интервала. Третья часть битового интервала всегда была низкого уровня. Далее ловим прерывание по переднему фронту и можно делать одно считывание посредине битового интервала, если низкий уровень то 0, если высокий то 1. Либо для повышения надежности делать три считывания на 1/6 , 1/2 и 5/6 битового интервала. комбинация 100 - означает 0, 110 - означает 1, все остальные комбинации считать ошибкой. Такой способ кодирования применялся в Синклере при записи программы на магнитную ленту.
     
    DrProg нравится это.
  5. DrProg

    DrProg Вечный нерд

    Во
    Вот интересно! Я тоже думал о подобном но по двум проводам - по первому ждем фронт, на втором при этом 0 или 1. Ваш вариант надо обдумать.
     
    ИгорьК нравится это.
  6. Onkel

    Onkel Гуру

    1 есть готовый протокол передачи последовательный, применяется в WS2811/2812, как-то он по науке называется - не помню. Посмотрите, если увеличить времена то потянет и тинька, тем более что кто-то (тоже с котом на аватарке) писал, что он научил тиньку генерить код для 2812.
    0 софт уарт (тем более вам ведь только на прием) нихрена (почти) не требует памяти - одно внешнее прерывание, один таймер и 10 строк кода на си. Таких в тиньку можно засунуть сотню. У меня софтовые один uart на прием и 4 на передачу занимают меньше ста байт.
     
  7. Airbus

    Airbus Радиохулиган Модератор

    А зачем софтовый UART когда там есть аппаратный USART? Точно такой же как и на Меге8 Можно так http://tinyurl.com/zx355jj Или так http://tinyurl.com/jgvsyeo Или так http://tinyurl.com/zsp7qtx
     
    Последнее редактирование: 16 дек 2015
  8. Airbus

    Airbus Радиохулиган Модератор

  9. DrProg

    DrProg Вечный нерд

    SPI не нужно уже, нужно UART причем можно только на прием. Чтобы можно было и с МК передать данные и с терминала вручную. На Attiny85 сделал без проблем, а тут минимизировал скетч донельзя, но с Serial код получается 1720 байт из 2048. Начинает работать, показывает цифру по умолчанию, но вешается при попытке принять данные. Я считаю, что памяти не хватает и он потому критует.

    Чем можно заменить прием данных по UART?
     
    ИгорьК нравится это.
  10. Onkel

    Onkel Гуру

    1720 из 2048 - не должен вешаться , я делаю прямо на 100%, не вешается.
    Имхо у вас где-то перебор с софтовым uart'ом, тем более вам принять -то один байт, у меня софтовые уарты занимают десяток на прием и чуть больше на передачу.
    Другой тип, вместо уарта - NZR протокол, который используют в ws2811/2812.
     
  11. Onkel

    Onkel Гуру

    может и старый, но живой. Это NZR протокол, применяется ныне в адресных светодиодах Ws2811/2812
     
  12. DrProg

    DrProg Вечный нерд

    Так, всем спасибо, собрав в кучу советы, ссылки и нарыв собственных, очередную высоту взял. Сделал чтение по UART на низком уровне непосредственно из регистров. Скетч теперь вместо 2Кб (который и не работал) весит 860 байт (вместе с процерурой вывода на индикатор) и работает на отличненько (без использования прерываний!). Для теста выводил числа на Attiny2313 через терминал.


    Найдено применение запасам 2313, упрощена аппаратная часть драйвера индикатора, получены бесценные знания и опыт.

    Если интересно, завтра выложу программу с комментариями, сегодня уже сил нет.
     
    ИгорьК нравится это.
  13. Alex19

    Alex19 Гуру

    После данного сообщения.
    Я подумал, что Вы не можете использовать аппаратный UART, поэтому не стал вытягивать и упрощать свою реализацию, надо будет тоже найти время привести ее в порядок и опубликовать.

    Рад, что у Вас все получилось, удачи!
     
  14. DrProg

    DrProg Вечный нерд

    Софтовый вариант тоже надо будет до ума довести, наверняка пригодится. Буду рад если поделитесь наработками.
     
    ИгорьК нравится это.
  15. Airbus

    Airbus Радиохулиган Модератор

    Было бы интересно!А если на Асме то 150 байт?Ничего сложного ведь нет?
    Ребята накуя вы Софтовый USART используете там где есть аппаратный?Я вот например не понимаю.Вот в Тини13 если всунуть то да есть смысл
     
  16. Onkel

    Onkel Гуру

    например (рельная задача) сонар - один для связи с компом, один для посылки команды мерять и получения ответа, один для управления мз3 плейером для обратной связи. итого 3 уарта, один можно без приема, только передача.
     
    DrProg нравится это.
  17. DrProg

    DrProg Вечный нерд

    1. На асме врядли будет намного короче, я почти не использовал библиотечные функции, настраивал порты и подавал в них данные примерно так:
    Код (C++):
      DDRB = 0b11111111;
      DDRD = 0b01111111;
        PORTD |= 0b00111100;
        PORTD &= ~(1 << (ii + 2));
        PORTB = segment[digit];
    Попробуйте, конечно, но там реально практически минимал.

    2. Причин несколько:
    - если нужно несколько UART портов, как заметили до меня,
    - ужать код в два-три раза по размеру и значительно ускорить его даже там, где возможности позволяют использовать стандартный Serial(),
    - извлечь из этого знания и умения, которые потом обязательно пригодятся.
     
    ИгорьК нравится это.
  18. Alex19

    Alex19 Гуру

    Не стал переписывать общую реализацию под Вас, так как Вы решили свою проблему. Начал опубликовать, подробнее тут, завтра поясню как все это работает и как настраивать.