Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Мультипроцессорный обмен
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Oleg_IT
Начал работать с мультипроцессорным обменом, для начала использую два МК. Написал программку, работает, но как-то странно.
Передаю следующий массив
char BuffTx[] = {0x55,AdrTo,0x23,0xCC,0x**,0xAA};
0x55 – преамбула
AdrTo – число, адрес МК куда посылаю, девятый бит 1.
0xCC – конец массива. По приёму этого байта подчинённый МК ставит флаг «приём завешён»
0x**(любой байт) и 0xAA – конец передачи для мастера. 0xAA в UART не посылается, по нему ресетится UART. Но без 0x** байт 0xCC не передаётся. Не пойму почему.
BVU
Цитата(Oleg_IT @ Dec 16 2005, 11:54) *
Начал работать с мультипроцессорным обменом, для начала использую два МК. Написал программку, работает, но как-то странно.
Передаю следующий массив
char BuffTx[] = {0x55,AdrTo,0x23,0xCC,0x**,0xAA};
0x55 – преамбула
AdrTo – число, адрес МК куда посылаю, девятый бит 1.
0xCC – конец массива. По приёму этого байта подчинённый МК ставит флаг «приём завешён»
0x**(любой байт) и 0xAA – конец передачи для мастера. 0xAA в UART не посылается, по нему ресетится UART. Но без 0x** байт 0xCC не передаётся. Не пойму почему.

Может Ваш контроллер на стороне приема не успевет ('захлебывается') принять эту посылку. Во избежании такового необходима реализация процесса квитирования (подтверждение на готовность приема следующего байта). Она может быть реализована как аппаратная, так и программно, в зависимости от ресурсов и требований к Вашей системе.
Oleg_IT
Цитата
Может Ваш контроллер на стороне приема не успевет ('захлебывается') принять эту посылку. Во избежании такового необходима реализация процесса квитирования (подтверждение на готовность приема следующего байта). Она может быть реализована как аппаратная, так и программно, в зависимости от ресурсов и требований к Вашей системе.


Нет, успевает. Я не отметил, что для наглядности я поставил задержки между байтами, такие, что на глаз видно как они уходят и приходят. И остальные байты правильно идут
BVU
Цитата(Oleg_IT @ Dec 16 2005, 14:23) *
Цитата

Может Ваш контроллер на стороне приема не успевет ('захлебывается') принять эту посылку. Во избежании такового необходима реализация процесса квитирования (подтверждение на готовность приема следующего байта). Она может быть реализована как аппаратная, так и программно, в зависимости от ресурсов и требований к Вашей системе.


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

Это не то же самое о чем я говорил. Принимающая система должна дать разрешение на прием следующей информации, когда она готова к этому. Можете сделать такой эксперимент - попробуйте принимать байты и что приняли отсылать обратно. Возможно здесь Вы быстрее обнаружите свою ошибку (по всей видимости код...). sad.gif
andk
Судя по всему, проиходит вот это:
байт СС ложится в сдвиговый регистр передатчика(начинает выдвигаться), UART говорит - "я свободен", берется следующий байт для помещения в регистр данных передатчика - АА - догадываемся что конец и спокойно сбрасываем UART (кстати - как ?)
Вообще говоря, враги давно придумали и протокол и символы для терминала - в начале таблицы ASCII есть STX, ETX,DLE,ACK,NAK
Процесс выглядит так:
STX--DATA--ETX
Для приемника STX - всегда старт и ETX всегда стоп.
Для устранения коллизий с данными есть DLE - т.е. если в данных обнаруживается STX или ETX или DLE вставляется DLE.
Если хочешь, могу выложить сишный код с реализацией этого протокола.
Roma_te
Цитата(Oleg_IT @ Dec 16 2005, 12:54) *
Начал работать с мультипроцессорным обменом, для начала использую два МК. Написал программку, работает, но как-то странно.
Передаю следующий массив
char BuffTx[] = {0x55,AdrTo,0x23,0xCC,0x**,0xAA};
0x55 – преамбула
AdrTo – число, адрес МК куда посылаю, девятый бит 1.
0xCC – конец массива. По приёму этого байта подчинённый МК ставит флаг «приём завешён»
0x**(любой байт) и 0xAA – конец передачи для мастера. 0xAA в UART не посылается, по нему ресетится UART. Но без 0x** байт 0xCC не передаётся. Не пойму почему.


Не пойму что имелось в виду "без 0x** байт 0xCC не передаётся". Ведь судя по описанию 0x** следует после 0xCC. Вообще то я советую тренировки делать на на двух МК а на МК + ПК с терминалом. Тогда Вы оперативнее сможете вносить изменения в програму работы МК.
Oleg_IT
Цитата(andk @ Dec 16 2005, 14:56) *
Судя по всему, проиходит вот это:
байт СС ложится в сдвиговый регистр передатчика(начинает выдвигаться), UART говорит - "я свободен", берется следующий байт для помещения в регистр данных передатчика - АА - догадываемся что конец и спокойно сбрасываем UART (кстати - как ?)
Вообще говоря, враги давно придумали и протокол и символы для терминала - в начале таблицы ASCII есть STX, ETX,DLE,ACK,NAK
Процесс выглядит так:
STX--DATA--ETX
Для приемника STX - всегда старт и ETX всегда стоп.
Для устранения коллизий с данными есть DLE - т.е. если в данных обнаруживается STX или ETX или DLE вставляется DLE.
Если хочешь, могу выложить сишный код с реализацией этого протокола.


Если не сложно, то сбросьте код сюда iteris@yandex.ru

Байт 0xCC уходит, по прерыванию "я свободен" посылается байт 0x**, следующее прерывание "я свободен", программа видит байт 0xAA и сбрасываем UART так (переводя его на приём:
UBRRL = 5;
UCSRA = 0x01; // MPCM Bit set
UCSRB = 0x94;
UCSRC = 0xC6;
//XCK - Pin as input
DDRB &= 0xFE;

Цитата
Не пойму что имелось в виду "без 0x** байт 0xCC не передаётся".

Если я не передаю любой байт за 0xCC он на принимающий МК не приходит. Вообще создается впечатление, что очередной байт уходит только после записи в передатчик следующего байта.
Rash
Цитата
если не сложно, то сбросьте код сюда iteris@yandex.ru

не будь игоистом.

Цитата
Если хочешь, могу выложить сишный код с реализацией этого протокола.

Если не трудно выложи в этой теме код
Laptop
Цитата(Oleg_IT @ Dec 16 2005, 11:54) *
Начал работать с мультипроцессорным обменом, для начала использую два МК. Написал программку, работает, но как-то странно.
Передаю следующий массив
char BuffTx[] = {0x55,AdrTo,0x23,0xCC,0x**,0xAA};
0x55 – преамбула
AdrTo – число, адрес МК куда посылаю, девятый бит 1.
0xCC – конец массива. По приёму этого байта подчинённый МК ставит флаг «приём завешён»
0x**(любой байт) и 0xAA – конец передачи для мастера. 0xAA в UART не посылается, по нему ресетится UART. Но без 0x** байт 0xCC не передаётся. Не пойму почему.

Видимо ты проверяешь не "сдвиговый регистр пуст", а "буфер пуст". У AVR двойная буферизация, тебе нужно определять окончание передачи по прерыванию "сдвиговый регистр пуст".
В твоем случае происходит следующее:
0xCC успел передаться, начинается передача 0x**, ты натыкаешься на 0хАА и обрываешь передачу... у тебя хорошо если старт-бит успеет передаться...
Дождись окончания передачи и все будет в полном порядке.
Laptop
Кому интересно. Вот мой вариант. Внутри код для обработки погрызен.
SETB, CLRB, BIT макросы для установки, сброса и проверки бита в байте message.

#define analyse_it 7
#define first_ten 6
#define start_rec 5
unsigned char message = 0;
unsigned char mess_buf[387];
unsigned int index;


void message_process(void)
{
unsigned char c, lp;
int i;
c = _getchar(); /*printf(" %X%X ",c>>4,c&0x0F);*/
if (BIT(message,first_ten))
{
switch ©
{
case 0x10 : if (BIT(message,start_rec)) mess_buf[index++] = 0x10; break;
case 0x03 : SETB(message,analyse_it); CLRB(message,start_rec);
//.......................................................................
//здесь собственно обработка принятого в буфер

break;

default : if BIT(message,analyse_it)
{
/*restart receive*/
SETB(message,start_rec);
mess_buf[0] = c; index = 1;
}
}
CLRB(message,first_ten);
}
else
if (c == 0x10){ SETB(message,first_ten); }
else
if (BIT(message,start_rec)){ mess_buf[index++] = c; }
}
andk
Вот код.
Заточено под мои заморочки:
Отдельные выделеные буфера для передатчика и приемника.
Размер буферов - по 256 байт. Соответственно длины - char.
Реализован таймаут приема.
Реализована простейшая проверка целостности данных - ХОR.
Еще что-то, сейчас плохо помню.
Естественно, все это подкручивается в соответствии с необходимостью.
Oleg_IT
Цитата(Laptop @ Dec 18 2005, 19:51) *
Видимо ты проверяешь не "сдвиговый регистр пуст", а "буфер пуст". У AVR двойная буферизация, тебе нужно определять окончание передачи по прерыванию "сдвиговый регистр пуст".
В твоем случае происходит следующее:
0xCC успел передаться, начинается передача 0x**, ты натыкаешься на 0хАА и обрываешь передачу... у тебя хорошо если старт-бит успеет передаться...
Дождись окончания передачи и все будет в полном порядке.


Имеется два прерывания на передачу «Регистр данных USART пуст, UDRE» и «Передача завершена, TXC», "сдвиговый регистр пуст" имеется ввиду «Регистр данных USART пуст, UDRE»? Начал работать с UDRE, потом перешёл на TXC (естественно со сменой флагов инициализации) ситуация не изменилась.

Спасибо за код, разберусь, применю.

Товарищу или Господину назвавшему меня «не будь игоистом». Во первых не Игоист, а Эгоист. Не стоит сразу так о человеке, товарищ предложил поделиться кодом, я его попросил прислать его мне, без всякой задней мысли. Если кто хочет, может попросить выложить код. Давайте будем корректными друг к другу.
Laptop
Цитата(Oleg_IT @ Dec 19 2005, 09:00) *
Имеется два прерывания на передачу «Регистр данных USART пуст, UDRE» и «Передача завершена, TXC», "сдвиговый регистр пуст" имеется ввиду «Регистр данных USART пуст, UDRE»? Начал работать с UDRE, потом перешёл на TXC (естественно со сменой флагов инициализации) ситуация не изменилась.

Именно об этом и говорил... Странно...
Ты данные подсовываешь по "регистр данных пуст", а закрываешь передачу по "передача завершена"?
Нужно работать именно с двумя прерываниями, лучше именно с прерываниями, а не опросом флагов.
Реакция будет быстрее.
Если работаешь только по "передача завершена", то скорее всего попадаешь в логическую ловушку с отправкой...
Особенно если проверка на "передача завершена" стоит прямо после записи очередного байта на отправку.
Oleg_IT
Цитата(Laptop @ Dec 19 2005, 13:21) *
Именно об этом и говорил... Странно...
Ты данные подсовываешь по "регистр данных пуст", а закрываешь передачу по "передача завершена"?
Нужно работать именно с двумя прерываниями, лучше именно с прерываниями, а не опросом флагов.
Реакция будет быстрее.
Если работаешь только по "передача завершена", то скорее всего попадаешь в логическую ловушку с отправкой...
Особенно если проверка на "передача завершена" стоит прямо после записи очередного байта на отправку.


Всё же хочу докопаться, в чём я не прав.
Я работаю с одним прерыванием, просто пробовал с начало с одним работать потом с другим. Но последовательности действий не менял.
На стороне МК «мастер»:
1. Передаю байт «преамбула», девятый бит 0 (можно и без него).
2. По приходу прерывания, или UDRE или (но не И) TXC передаю адрес «Кому» с установленным в 1 девятым битом.
3. По приходу прерывания,… передаю N (у меня пока один) байт данных, девятый бит 0.
4. По приходу прерывания,… передаю байт 0xCC.
5. По приходу прерывания,… передаю любой байт.
6. По приходу прерывания,… и по обнаружения в передаваемом буфере байта 0xAA перевожу USART на приём, ни чего больше в USART не посылая.
На стороне подчинённого МК:
7. USART подчинённого МК настроен на мультипроцессорный обмен, т.е. стоит бит MPCM регистра UCSRA. Поэтому первый пришедший байт, байт адреса. Я это вижу на индикаторе, процесс передачи с задержкой и два байта преамбулы. Байты преамбулы не принимаются. Проверяю адрес, если правильный снимаю бит MPCM.
8. Принимаю байты данных.
9. По приёме байта 0xCC перевожу USART в исходное состояние, т.е. ставлю бит MPCM.
При удалении п.5 передача даёт сбой. Может, какие флажки по приходу прерывания снимать/ставить нужно? Вроде делаю всё как по учебнику.
andk
>6. По приходу прерывания,… и по обнаружения в передаваемом буфере >байта 0xAA перевожу USART на приём, ни чего больше в USART не >посылая.
Хорошо.
Сделай здесь просто запрещение прерывания от передатчика. Но сам передатчик не выключай.
В этом случае у тебя передача должна пройти.
Oleg_IT
Цитата(andk @ Dec 19 2005, 15:05) *
>6. По приходу прерывания,… и по обнаружения в передаваемом буфере >байта 0xAA перевожу USART на приём, ни чего больше в USART не >посылая.
Хорошо.
Сделай здесь просто запрещение прерывания от передатчика. Но сам передатчик не выключай.
В этом случае у тебя передача должна пройти.



Извиняюсь, а по какому событию мне тогда переводить USART в исходное состояние? По таймауту?
И потом, я считал, что если передача пошла она закончится, как бы я с регистрами не работал. Что, можно остановить передачу на пол байте?
Laptop
Вот кусочек моего исходника по мультипроцессорному обмену на RS485 (для slave). Все прекрасно работает. В данном случае пакеты фиксированной длины, контрольная сумма.
Проект для AVR 2313, кварц скорее всего на 8 МГц, проверь по значению делителя.
В определениях найдешь куда у меня подключалось управление драйвером.
Драйвер AD485, если склероз мне не изменяет.
И подправь исходник слегка, я не стал лишние файлы в архив класть.
Если надо могу и схему от проекта поискать...
andk
Цитата(Oleg_IT @ Dec 19 2005, 17:24) *
Цитата(andk @ Dec 19 2005, 15:05) *

>6. По приходу прерывания,… и по обнаружения в передаваемом буфере >байта 0xAA перевожу USART на приём, ни чего больше в USART не >посылая.
Хорошо.
Сделай здесь просто запрещение прерывания от передатчика. Но сам передатчик не выключай.
В этом случае у тебя передача должна пройти.



Извиняюсь, а по какому событию мне тогда переводить USART в исходное состояние? По таймауту?
И потом, я считал, что если передача пошла она закончится, как бы я с регистрами не работал. Что, можно остановить передачу на пол байте?

Я имел ввиду только один цикл и только для того что бы разобраться, почему не проходит передача.
Если после моего предложения передача прошла, значит ты просто не дожидаешься окончания передачи и тормозишь уарт на всем скаку.
Передачу конечно ты останавливаешь:
UBRRL = 5; <-- тут не нужно ничего писать, один раз при инициализации достаточно.
UCSRB = 0x94; <-- передатчик выкл и еще 9 тх бит в ноль.
UCSRC = 0xC6; <-- тоже что и в первой строчке
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.