Vladimir Ljaschko (06.05.2010 11:04, просмотров: 11239)
2 Mazur: пример автомата для реализации слэйва по интерфейсу RS485. static char slave_state;
enum //состояния автомата :
{ SerialDompUnconfigured=0, // неконфигурировано
SerialDompReceiving, // прием
SerialDompProcessing, // обработка
SerialDompAnswer, // подготовка ответа
SerialDompWaitTransmitting, // ожидание передачи
SerialDompTransmitting, // передача
SerialDompWaitReceiving // ожидание приема
};
void SlaveDompService(void)
{ char b;
switch (slave_state)
{ case SerialDompUnconfigured: // если неконфигурировано:
Uart0Init(UART0_BITRATE); // инициализация УАРТ
SET_RX_DIR(); // установка направления - прием
Uart0SetReceive(Uart0Receiving); // начало приема
slave_state = SerialDompReceiving; // переход в состояние приема
break;
case SerialDompReceiving: // если прием:
if (uart0.rx_status==Uart0Received) // УАРТ прием закончил?
slave_state = SerialDompProcessing; // переход на обработку
break;
case SerialDompProcessing: // если обработка
b = SlaveParserCommand(); // разбор команды
if (!b) // успешен?
{ SerialDompExecuteCommand(); // выполнить команду
if (slave_data.address!=BROADCAST_DU_ADDR) // адрес не общий?
slave_state=SerialDompAnswer; // на формирование ответа
else
{ uart0.timer=1; // адрес общий,
slave_state=SerialDompWaitReceiving; //опять на прием
}
}
else
{ if (b>parserWRONG_OBJECT1) //ошибка высшего уровня ?
{ slave_data.error=errSYNTAX; // да, ответить
slave_state=SerialDompAnswer;
}
else
{ slave_state = SerialDompWaitReceiving; // нет, на прием
uart0.timer = 1; // через 1 мс
}
}
break;
case SerialDompAnswer: //если подготовка ответа
SlaveDompPrepareAnswer(); // подготовить ответ
slave_state = SerialDompWaitTransmitting; // на ожидание передачи
uart0.timer=2; // тайм-аут ожидания
break;
case SerialDompWaitTransmitting:
if (!uart0.timer) // тайм-аут закончен
{ SET_TX_DIR(); //установка направления
slave_state = SerialDompTransmitting; // начало передачи
uart0.timer = UART0_MAX_TX_TIME; //тайм-аут передачи
Uart0SetTransmit(Uart0Transmitting); // УАРТ-передача
}
break;
case SerialDompTransmitting: //если передача
if (!uart0.timer) //таймаут закончен?
slave_state = SerialDompUnconfigured; // да, на переконфигурацию
if (uart0.tx_status==Uart0Transmitted) // передача закончена?
{ SET_RX_DIR(); // разворот на прием
uart0.timer=2; // тайм-аут ожидания приема
slave_state=SerialDompWaitReceiving; // на ожидание приема
}
break;
case SerialDompWaitReceiving: // ожидание приема
if (uart0.timer == 0) // закончено?
{ Uart0SetReceive(Uart0Receiving); // УАРТ - прием
slave_state = SerialDompReceiving; // автомат - на прием
}
break;
default:
slave_state = SerialDompUnconfigured; // неизвестное состояние -
break; // на переконфигурацию
}
}