Также не работает((( Спасибо огромное за отклики и помощь!!! Задача следующая: Передача данных по 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%. Уже было проверено с другими.
Код реализацииSLAVE: // Сначала инициализация
// 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(); // приходит подтверждение
Дальше идет событие. Сейчас проверял. Получается так как будто он зависает в режиме приема. Потому что если приходит подтверждение, то должен гореть светодиод
Заранее благодарен. Очень надеюсь на Вашу помощь.
|