Просмотр этой темы:
1 анонимных пользователей
Главный Технолог
Зарегистрирован:
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 Ом между собой
Отправлено: 20.06.2012 23:24
|
|
Модератор
Зарегистрирован:
26.01.2010 23:26 Из: Тирасполь
Сообщений:
3926
|
мусье понимает толк в извращениях...
Отправлено: 21.06.2012 3:49
|
|
Главный Технолог
Зарегистрирован:
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); //принимает не все нужные байты и виснет в цикле Вероятность неправильного заполнеия исключена поотому, что у меня тогда загорелась бы ошибка. А он висит где-то!!! Посмотрите, пожалуйста, код может там ошибка? Или в схеме подключения, которую я описал? Очень надеюсь на Вашу помощь!!!
Отправлено: 21.06.2012 8:47
|
|
Модератор
Зарегистрирован:
26.01.2010 23:26 Из: Тирасполь
Сообщений:
3926
|
нарисуй
Отправлено: 21.06.2012 10:50
|
|
Главный Технолог
Зарегистрирован:
01.07.2011 19:44 Из: Тольятти
Сообщений:
305
|
Всем спасибо!!! Но проблему я решил.
Просто надо было расставить заданной величины задержки в нужных местах и вуаля!!!)))
Отправлено: 25.06.2012 9:50
|
|
Главный Технолог
Зарегистрирован:
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). Функции такие же как описаны выше, только задержки Вот схема: посмотрите, пожалуйста, может дело как я думаю в коде или оптимизации. Надеюсь на Вашу помощь! Прикреплённый файл: 1.JPG (240.63 KB)
Отправлено: 27.06.2012 8:25
|
|
Модератор
Зарегистрирован:
26.01.2010 23:26 Из: Тирасполь
Сообщений:
3926
|
Схема точно неправильная.
Отправлено: 27.06.2012 10:38
|
|
Главный Технолог
Зарегистрирован:
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; }
Отправлено: 27.06.2012 10:43
|
|
Модератор
Зарегистрирован:
26.01.2010 23:26 Из: Тирасполь
Сообщений:
3926
|
слушай, какой такой нафик код, если железо с косяками. Правь железо, а потом уже с кодом играйся. могу сказать, что после каждого отосланного байта тебе придется сбрасывать все ошибки и очищать регистр приема на только что передававшей стороне.
Отправлено: 27.06.2012 11:03
|
|
Главный Технолог
Зарегистрирован:
01.07.2011 19:44 Из: Тольятти
Сообщений:
305
|
А что в железе то не так?
Отправлено: 27.06.2012 11:05
|
|