LTagKirov писал(а):
Pingvin писал(а):
RX_DATA_COMPLITE;//приняты 16 бит данных или команда
Есть команды с более чем двумя байтами и есть режим клонирования, может быть сразу подумать о возможности дальнейшей реализации. Ограничив сейчас 16битами, будет трудно сделать клонирование потом.
http://www.lasertagparts.com/mtformat-2.htmЗЫ. Зачем нужно клонирование непонимаю (ниразу не видел в живую - LW неподдерживает ?), но народ просит как жутко нужную
Не вопрос - узнаем, сколько бит занимает пакет "клонирование" и добавим ещё одно событие - RX_CLONE_COMPLETE
Можем сделать это прямо сейчас - спасибо!
Мы не ограничиваем себя 16 битами!
У нас буфер на 64 бита и можем увеличить как хотим!
Это просто идентификация пакета по его длинне и дополнительный контроль, не более.
Ну что же, добавим еще событие
Цитата:
///---------------------------------------------------------------------//
//Определим перечисляемый тип для событий ИК-приемника
enum Rx_Event {
NOT_EVENT, //нет событий
RX_COMPLETE, //принят пакет из 14 бит ("выстрел")
RX_ERROR, //ошибка приема пакета
RX_DATA_COMPLETE,//приняты 16 бит данных или команда
RX_CLONING_DATA_COMPLETE//принята структура для клонирования
};
typedef enum Rx_Event trx_event;
Теперь открываем файл isr.c, находим место, где у нас генерируются события ИК-приемника и меням
Цитата:
if (bit_in_rx_buff==14) rx_event = RX_COMPLETE; //Генерим событие "принят пакет"
else rx_event = RX_ERROR; //генерируем событие - "ошибка приёма"
на
Цитата:
switch(bit_in_rx_buff)
{
case 14:
{
rx_event = RX_COMPLETE;//Генерим событие "принят пакет выстрела"
break;
}
case 16:
{
rx_event = RX_DATA_COMPLETE;//Генерим событие "приняты два бита данных или команда"
break;
}
default: rx_event = RX_ERROR; //генерируем событие - "ошибка приёма"
}
Теперь компилируем, прошиваем девайс и смотрим - не потеряла ли наша прошивка работоспособность!
Не потеряла - поражения по прежнему фиксируются.
Ну теперь событие мы имеем, нужно его обработать в главном цикле прошивки.
Открываем файл ltag_ascetic.c и находим такой кусок кода
Цитата:
switch(rx_event)//выясним, какое именно событие произошло
{
case RX_COMPLETE: //получен пакет
{
// cli();
/*********************************************************
WOUND_LED_ON; //включаем вспомогательный светодиод
timer1=0;
while(timer1 < 35000);
WOUND_LED_OFF; //выключаем вспомогательный светодиод
************************************************************/
Этот switch проверяет, какое же событие произошло.
Цитата:
case RX_COMPLETE: //получен пакет
{
То что в фигурных скобках после этой строки выполняется при условии, что rx_event==RX_COMPLETE
А тут мы обрабатываем ошибку приема - просто мигаем светодиодом "пустая обойма"
Цитата:
case RX_ERROR: //ошибка приема
{
// cli();
BULLETS_OUT_LED_ON;
timer1=0;
while(timer1 < 35000);
BULLETS_OUT_LED_OFF;
rx_event = NOT_EVENT;
// sei();
break;
}
А можем добавить звук пролитевшей мимо пули и воспроизвести - дойдем и до этого.
А если никакого события нет, то ничего и не делаем
Цитата:
case NOT_EVENT: //ошибка приема
{
// cli();
// rx_event = NOT_EVENT;
// sei();
break;
}
Одна тонкость - после обработки события мы должны присвоить переменной rx_event значение NOT_EVENT.
Иначе обработчик будет вызываться бесконечно, даже если новых событий не наступило в действительности.
Ну что, добавим новый case на случай приема команды?
Нет ничего проще!
Перед case NOT_EVEN: вставим
Цитата:
case RX_DATA_COMPLETE:
{
//тут разместим код обработчика команды
rx_event = NOT_EVENT;// и не забудем сбросить событие!
break;
}
Все - можем писать код обработки команды!
Но прежде чем писать обработку команды, неплохо бы придумать для команды структуру, с которой нам было бы удобно работать. Да и не работать же нам с буфером приемника напрямую - это чревато!
Ведь пока мы обрабатываем команду, может прилететь новый пакет и затереть нашу команду, а мы об этом даже не узнаем, ведь это все сделает прерывание.