Ошибка явно программная. По-моему использование здесь режима мультипроцессорного обмена малоэффективно. Вы принимаете данные от предыдущего по кольцу контроллера, а передаете на последующий. Программа явно зацикливается. Я бы использовал префиксный байт (байт адреса) с использованием обычного асинхронного 8-ми битного режима. Дальше может быть 2 варианта.
1. Все контроллеры программируются одинаково. Кнопками адреса выбирается дальность отправки. 0 - цифра появляется на контроллере, с которого идет отправка, 1 - следующий справа (по кольцу), 2 - второй справа. Остальные адреса игнорируем. Контроллер, принимая нулевой адрес ничего не передает, индицирует введенную цифру. Если принимает по UART, отнимает от адреса 1. Если получится 0, дальше не передает, высвечивает результат, если 1 - передает по кольцу дальше, с адресом на 1 меньше.
Недостаток: относительная адресация.
2. Каждый контроллер имеет свой адрес и реагирует только на него. Все остальное так же, только отнимать ничего не нужно. Несуществующие адреса лучше отсечь еще на этапе ввода, т.к. иначе будет передаваться по кругу до бесконечности (у Вас нечто подобное происходит). Если контроллер принимает свой адрес - выводит цифру на индикатор, чужой - передает по кольцу.
И программа проще будет.
Пока же в Протеусе хаос, честно говоря, даже сомневаюсь - нажатая кнопка это 0, или 1? Часто два индикатора одновременно меняют значение.Добавлено (28.11.2016, 00:22)
---------------------------------------------
Посмотрел еще раз на схему - Вы наверное в одном байте и адрес и данные передаете? Точнее опишите используемый алгоритм. Я правильно понял, что код данных нужно по адресу передать с любого контроллера в любой контроллер, включая тот, с которого идет команда?