Форум

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

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

В сети

Пользователей: 45
Из них просматривают:
Аналоги: 20. Даташиты: 6. Инструкции: 1. Новости: 6. Форум: 12.
Участников: 2
Гостей: 43

Google , Яндекс , далее...
Рекорд 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
Не в сети
А что в железе то не так?



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


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

Разное

Интересно

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