 Vladimir Ljaschko (06.05.2010 11:04, просмотров: 12036)
 Vladimir Ljaschko (06.05.2010 11:04, просмотров: 12036)
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;										// на переконфигурацию
	}						
}