Форум

Радиолюбительский форум.

Если у Вас возникли вопросы, задавайте их на форуме.

В сети

Пользователей: 199
Из них просматривают:
Аналоги: 77. Даташиты: 61. Инструкции: 2. Новости: 10. Остальное: 5. Программы: 2. Профиль пользователя: 9. Расчёты: 4. Теги: 1. Торрент: 1. Форум: 26. Чат: 1.
Участников: 3
Гостей: 196

Google , grom , Яндекс , далее...
Рекорд 2375 человек онлайн установлен 26.12.2015.

Партнёры


Партнёры

Новые объявления

В настоящее время нет объявлений.

Просмотр этой темы: 

 1 анонимных пользователей
atmega(USART)
Главный Технолог
Зарегистрирован:
01.07.2011 19:44
Из: Тольятти
Сообщений: 305
Не в сети
Здравствуйте.
Использую USART для общения 2 мег. Нужно объеденить RX и TX в одну линию.

Задача следующая:
Передача данных по USART. RX и TX объединены в одну
Есть устройство(именуемое SLAVE), которое всегда находится в режиме приема, как только данные приходят оно отправляет ответ.
Есть второе устройство(именуемое MASTER), которое всегда находится в режиме передачи, как только данные отправлены оно ожидает ответ, в качестве подтверждения.
Есть специальный протокол обмена между ними:
Из MASTER в SLAVE:

Формат пакета:

[Const1] [Data] [-Data] [Const2] [CS]

где
Const1 = 0x0F
Const2 = 0x15

Data - один байт пересылаемых данных.
-Data - инвертированный предыдущий байт.
CS - контрольная сумма, вычисляемая как сумма четырех
предыдущих байт по "исключающему ИЛИ". При всех операциях
старшие биты 5,6,7 не учитываются (обнуляются).

Команда 00, 01, 02, 03 - номер включаемого режима.
(максимально до 07, но реально будет использоваться 3 или 4).

Команда 08 - запрос текущего режима.

Ответ SLAVE:
Формат пакета

[Const3] [Data] [-Data] [Const4] [CS]

где
Const3 = 0x06
Const4 = 0x12

Data = 00, 01, 02, 03 ... 07 - текущий режим.


Примеры обменов.

MAS -> SLA SLA -> MAS
-------------- --------------
0F 00 1F 15 05 - 06 00 1F 12 0B включить! режим 0 - включен режим 0
0F 01 1E 15 05 - 06 01 1E 12 0B ... 1
0F 02 1D 15 05 - 06 02 1D 12 0B ... 2
0F 03 1C 15 05 - 06 03 1C 12 0B ... 3

0F 08 17 15 05 - 06 01 1E 12 0B какой режим включен? - включен режим 1

MASTER работает 100%. Уже было проверено с другими.

Код реализации MASTER:
// Сначала инициализация

// USART initialization
UCSR0A=0x00;
UCSR0B=0b00001000; // transmitter enable
UCSR0C=0b00000000; // 5 bit data transmit, no parity, 1 stop
UBRR0H = (unsigned char)(MYUBRR>>8);
UBRR0L = (unsigned char)MYUBRR;

//Функции обработки данных

unsigned char receive_BYTE (void)
{
// Wait until a byte has been received
while (!(UCSR0A & (1 << RXC0)));

return UDR0;
}

unsigned char receive_USART (void)
{
unsigned char cs=0;
pos=1;
do
{
USART_RX_buf[pos] = receive_BYTE();
USART_RX_buf[pos]&=0x1F;
if (pos != 5)cs^=USART_RX_buf[pos];
pos++;
} while (pos<6);
if ((USART_RX_buf[1]==0x06)&&(USART_RX_buf[4]==0x12))
{
if (cs == USART_RX_buf[5])
{
if (USART_RX_buf[3] == ((~(USART_RX_buf[2]))&0x1F))
{
UCSR0B &= ~(1<<4); //RX
DDRD &=~(1<<0);
PORTD &=~(1<<0);
UCSR0B |= (1<<3); //TX
return USART_RX_buf[2];
}
}
}
UCSR0B &= ~(1<<4); //RX
DDRD &=~(1<<0);
PORTD &=~(1<<0);
UCSR0B |= (1<<3); //TX
return 0;
}

void send_USART (unsigned char data)
{
unsigned char cs=0;
pos=1;
if (data == economS) data=0x00;
do
{
while (!(UCSR0A & (1 << UDRE0)));
// Transmit data

if (pos == 1) {UDR0 = 0x0F;cs^=0x0F;}
if (pos == 2) {UDR0 = data&0x1F; cs^=(data&0x1F);}
if (pos == 3) {UDR0 = ((~data)&0x1F); cs^=((~data)&0x1F);}
if (pos == 4) {UDR0 = 0x15;cs^=0x15;}
if (pos == 5) UDR0=cs;
while (!(UCSR0A & (1 << TXC0)));
pos++;
}while (pos<6);
UCSR0B &= ~(1<<3); //TX
DDRD &=~(1<<1);
PORTD &=~(1<<1);
UCSR0B |= (1<<4); //RX
}

Далее просто:
send_USART(mode); // отправляет команду
u_dat=receive_USART(); // приходит подтверждение

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

Заранее благодарен.
Очень надеюсь на Вашу помощь.

Соединяю MASTER со SLAVE следующим образом:
питание SLAVE- 5В
питание MASTER - 3.3В.
На линии (RX и TX) ставлю преобразователь уровня на 3.3В(резистивный делитель напряжения), подтягиваю эту линию через 11кОм к 3.3В. RX и TX у мастера соединяю через 300 Ом между собой



Re: atmega(USART)
Модератор
Зарегистрирован:
26.01.2010 23:26
Из: Тирасполь
Сообщений: 3926
Не в сети
мусье понимает толк в извращениях...



Re: atmega(USART)
Главный Технолог
Зарегистрирован:
01.07.2011 19:44
Из: Тольятти
Сообщений: 305
Не в сети
Дело в том, что данные передает в сторону СЛЭЙВА и он даже все понимает. Но вот приема нету.
Как будто Он,либо в этом цикле:
while (!(UCSR0A & (1 << RXC0)));
// нету приема из-за косяка в подключении(описано выше) и он виснет в нем
либо в этом:
do
{
USART_RX_buf[pos] = receive_BYTE();
USART_RX_buf[pos]&=0x1F;
if (pos != 5)cs^=USART_RX_buf[pos];
pos++;
} while (pos<6);
//принимает не все нужные байты и виснет в цикле
Вероятность неправильного заполнеия исключена поотому, что у меня тогда загорелась бы ошибка. А он висит где-то!!!

Посмотрите, пожалуйста, код может там ошибка?
Или в схеме подключения, которую я описал?
Очень надеюсь на Вашу помощь!!!



Re: atmega(USART)
Модератор
Зарегистрирован:
26.01.2010 23:26
Из: Тирасполь
Сообщений: 3926
Не в сети
нарисуй



Re: atmega(USART)
Главный Технолог
Зарегистрирован:
01.07.2011 19:44
Из: Тольятти
Сообщений: 305
Не в сети
Всем спасибо!!! Но проблему я решил.
Просто надо было расставить заданной величины задержки в нужных местах и вуаля!!!)))



Re: atmega(USART)
Главный Технолог
Зарегистрирован:
01.07.2011 19:44
Из: Тольятти
Сообщений: 305
Не в сети
зарабатоло, но почему-то только один раз попробовал перепрошить и опять перестало. По компьютеру смотрел - отправляет правильно и правильно принимает(смотрел на дисплее), одновременно не получится посмотреть, потому что HYPER TERMINAL и компьютер порт не смогут обработать объединенные 2 линии(RX&TX) в одну.
Обрабаатываю не по прерыванию.
Скорость 4800, 5 бит, 1 стоп, без контроля четности.
Среда разработки AVR STUDIO 4.
Сначала отправляю данные потом жду подтверждения. Оно приходит(вижу на дисплее).И почему то он снова возвращается в начало(снова отправляет) - хотя цикла нет.
И вот пример:
if (programming_mode)
{
send_USART(sportS); //sport
_delay_ms(5);
temp=receive_USART();
USART_RX_buf[2]=0x00;
_delay_ms(5);
if (temp == sportS) // if sport
{
_delay_ms(5);
prepare_send(sport_send);
}
}
Последней команды:
prepare_send(sport_send); - не происходит, почему то после правильного принятия данных(receive_USART) обратно возвращается в начало условия(if programming).
Функции такие же как описаны выше, только задержки
Вот схема:

посмотрите, пожалуйста, может дело как я думаю в коде или оптимизации.
Надеюсь на Вашу помощь!

Прикреплённый файл:



jpg  1.JPG (240.63 KB)
6164_4fea8b1c361b1.jpg 1152X864 px



Re: atmega(USART)
Модератор
Зарегистрирован:
26.01.2010 23:26
Из: Тирасполь
Сообщений: 3926
Не в сети
Схема точно неправильная.



Re: atmega(USART)
Главный Технолог
Зарегистрирован:
01.07.2011 19:44
Из: Тольятти
Сообщений: 305
Не в сети
А как правильно тогда? Подскажите, пожалуйста.
Да кстати в код добавил щас перед отправкой данных еще 3 дамми байта. И изменил обработку приема.
Пока еще не тестировал.
А так еще есть идеи по поводу кода?
Вот код:
void send_USART (unsigned char data)
{
unsigned char cs=0;

UCSR0B &= ~(1<<4); //RX
DDRD &=~(1<<0);
PORTD &=~(1<<0);
UCSR0B |= (1<<3); //TX
//_delay_ms(5);

pos=1;
if (data == economS) data=0x00;
do
//for(pos=1;pos<6;pos++)
{
while (!(UCSR0A & (1 << UDRE0)));
// Transmit data
if (pos == 1) UDR0=0xAA;
if (pos == 2) UDR0=0xAA;
if (pos == 3) UDR0=0xAA;
if (pos == 4) {UDR0 = 0x0F;cs^=0x0F;}
if (pos == 5) {UDR0 = data&0x1F; cs^=(data&0x1F);}
if (pos == 6) {UDR0 = ((~data)&0x1F); cs^=((~data)&0x1F);}
if (pos == 7) {UDR0 = 0x15;cs^=0x15;}
if (pos == 8) UDR0=cs;
while (!(UCSR0A & (1 << TXC0)));
pos++;
}while (pos<9);
}

unsigned char receive_USART (void)
{
unsigned char cs=0;

UCSR0B &= ~(1<<3); //TX
DDRD &=~(1<<1);
PORTD &=~(1<<1);
UCSR0B |= (1<<4); //RX
//_delay_ms(5);

pos=1;
do
//for(pos=1;pos<6;pos++)
{
USART_RX_buf[pos] = receive_BYTE();
USART_RX_buf[pos]&=0x1F;
if (pos != 5)cs^=USART_RX_buf[pos];
if (USART_RX_buf[1]==0x06) pos++; else {cs=0x00; pos=1;}
if (pos == 2) pos++;
if (USART_RX_buf[3] == ((~(USART_RX_buf[2]))&0x1F)) pos++; else {cs=0x00;break;}
if (USART_RX_buf[4]==0x12) pos++; else {cs=0x00;break;}
if (cs == USART_RX_buf[5]) {pos++; return USART_RX_buf[2];}
// pos++;
} while (pos<6);
return 0xFF;
}



Re: atmega(USART)
Модератор
Зарегистрирован:
26.01.2010 23:26
Из: Тирасполь
Сообщений: 3926
Не в сети
слушай, какой такой нафик код, если железо с косяками. Правь железо, а потом уже с кодом играйся. могу сказать, что после каждого отосланного байта тебе придется сбрасывать все ошибки и очищать регистр приема на только что передававшей стороне.



Re: atmega(USART)
Главный Технолог
Зарегистрирован:
01.07.2011 19:44
Из: Тольятти
Сообщений: 305
Не в сети
А что в железе то не так?



Поиск по форуму


Расширенный поиск

Разное

Интересно

Полихлорвиниловые трубки легче натянуть на изолируемые предметы (отвертки, пинцеты, радиодетали), если на 15-20 мин поместить их в ацетон.