www.open-tager.ru

открытый лазертаг форум
Текущее время: 29 мар 2024, 02:18

Часовой пояс: UTC + 3 часа [ Летнее время ]


Реклама

Правила форума


В разделе запрещены - обсуждение оборудования не поддерживающего открытых протоколов, реклама и ссылки на готовые продукты лазертага, обсуждение политики производителей и самих производителей. Виден всем.



Начать новую тему Ответить на тему  [ Сообщений: 71 ]  На страницу 1, 2, 3, 4, 5 ... 8  След.
Автор Сообщение
СообщениеДобавлено: 21 сен 2011, 12:04 
Не в сети
Аксакал форума
Аватар пользователя

Зарегистрирован: 12 авг 2011, 16:55
Сообщений: 7514
Откуда: Барнаул, Алтайский край (не путать с республикой Алтай) :-)
Начал возиться с прошивкой.
Для начала попытался реализовать передачу пакета с данными (выстрел).
Единственное - так нигде и не нашёл, какие биты должны передаваться первыми - старшие или младшие?
Так что не исключено, что получился "зеркальный" Miles Tag. :(
Вот чего накропел:
файл types.h
Код:

#ifndef bool

                        #define bool unsigned char

                        #define true 1

                        #define false 0

#endif

//---------------------------------------------------------------------//

enum Team_Color {Red, Blue, Yellow, Green}; //Определим перечисляемый тип

typedef enum Team_Color tteam_color;            //для работы с цветом команды

/*
00 = Red
01 = Blue
10 = Yellow
11 = Green
*/

//---------------------------------------------------------------------//





//Определим перечисляемый тип
//для работы с "уроном"
enum GunDamage {   Damage_1, Damage_2, Damage_4, Damage_5,
            Damage_7, Damage_10, Damage_15, Damage_17,
            Damage_20, Damage_25, Damage_30, Damage_35,
            Damage_40, Damage_50, Damage_75, Damage_100};                            
typedef enum GunDamage tgun_damage;    

/*
0000 = 1
0001 = 2
0010 = 4
0011 = 5
0100 = 7
0101 = 10
0110 = 15
0111 = 17
1000 = 20
1001 = 25
1010 = 30
1011 = 35
1100 = 40
1101 = 50
1110 = 75
1111 = 100
*/

//---------------------------------------------------------------------//

//Определим структуру для хранения идентификатора игрока
//в ней будем хранить длительность импулсов  в "тиках" таймера (IR_ZERO или IR_ONE)
typedef struct PlayerID {
uint8_t bit_0; //Первый бит (всегда должен быть равен IR_ZERO)
uint8_t bit_1;
uint8_t bit_2;
uint8_t bit_3;
uint8_t bit_4;
uint8_t bit_5;
uint8_t bit_6;
uint8_t bit_7;//последний бит     
} tplayer_id;

/*
union player_id_union {
tplayer_id bits;
uint8_t data [8];
};
*/



//Определим структуру для хранения идентификатора (цвета) команды
//в ней будем хранить длительность импулсов в "тиках" таймера (IR_ZERO или IR_ONE)
typedef struct TeamID{
uint8_t bit_0;
uint8_t bit_1;
} tteam_id;
 


//Определим структуру для хранения урона
//в ней будем хранить длительность импулсов в "тиках" таймера (IR_ZERO или IR_ONE)
typedef struct Damage{
uint8_t bit_0;
uint8_t bit_1;
uint8_t bit_2;
uint8_t bit_3;

} tdamage;

//Теперь опишем структуру пакета данных
typedef struct DataPacket {
uint8_t header; //заголовок, всегда должен быть равен IR_START (1 Байт)
tplayer_id player_id; //после заголовка идет идентификатор игрока (8 Байт)
tteam_id team_id;     //Затем идентификатор команды (2 Байта)
tdamage damage;        //Ну и последним стоит "урон" (4 Байта)
uint8_t end_of_data;  //Метка, указывающая передатчику, что данных для отправки больше нет (всегда должна быть равна 0) (1 Байт)
} tdata_packet;



//---------------------------------------------------------------------//

union data_packet_union{
tdata_packet packet;
uint8_t data[16];
};




файл firmware.h

Код:
#include <avr/io.h>        /* Определяет имена для портов ввода-ывода               */
#include <util/delay.h>    /* Дает возможность формирования задержки                */
#include <avr/interrupt.h> /* Будем использовать прерывания */
#include "types.h"


#ifndef F_CPU                  //Этот параметр нужно задавать в свойствах проекта, если там не задан, задаем здесь
#define F_CPU 7372800            // Тактовая частота в Гц
#endif

#define IR_START_BIT_DURATION 2400   // Длительность Старт-Бита (в микросекундах)
#define IR_ONE_BIT_DURATION 1200   // Длительность Бита, соотретствующего единичке (в микросекундах)
#define IR_ZERO_BIT_DURATION 600   // Длительность Бита, соотретствующего нулю (в микросекундах)
#define IR_SPACE_DURATION 600      // Длительность Бита, соотретствующего интервалу между битами (в микросекундах)
#define IR_F0 36000               // Несущая частота ИК-приемника (f0)
#define IR_ZERO (IR_ZERO_BIT_DURATION*2*IR_F0)/1000000 //Длительность импулся, соответствующего биту = 0
                                         //выраженная в "тиках" таймера

#define IR_ONE (IR_ONE_BIT_DURATION*2*IR_F0)/1000000 //Длительность импулся, соответствующего биту = 1
                                         //выраженная в "тиках" таймера
#define IR_START (IR_START_BIT_DURATION*2*IR_F0)/1000000 //Длительность заголовка
                                          //выраженная в "тиках" таймера


#define IR_SPACE  (IR_SPACE_DURATION*2*IR_F0)/1000000 //Длительность интервала между передоваемыми битами
                                          //выраженная в "тиках" таймера



#define DEFAULT_PLAYER_ID 1       //Идентификатор игрока по умолчанию
#define DEFAULT_TEAM_COLOR Red      //Цвет команды по умолчанию (команда красных)



#define DEFAULT_DAMAGE Damage_1   //Урон по умолчанию (урон по умолчанию равен 1)




volatile static bool ir_transmitter_on;//флаг, разрешаюший (true) или запрещающий передачу данных через ИК-диод

//Декларируем наши функции
void init_timer2(void);          //Настройка таймера
void init_var(void);            //Присваиваем дефалтовые значения переменным
void send_ir_package(void);         //Отправляем подготовленный пакет (выстрел)
void set_player_id(uint8_t);      //Задаем игроку идентификатор
void set_team_color(tteam_color);   //Задаем цвет нашей команды
void set_gun_damage(tgun_damage);   //Задаем мощьность нашего оружия (урон)


//Глобальные переменные
volatile static int ir_pulse_counter; //Обратный счетчик "вспышек" ИК-диода
volatile static int ir_space_counter; //Обратный счетчик длительности выключенного состояния ИК-диода (пауза между битами)
static volatile uint8_t prt; //В эту переменную будем считывать состояние порта, на котором висит ИК-приемник
static volatile union data_packet_union  data_packet; //В этой переменной будем формировать пакет данных для отправки через IR
static volatile uint16_t timer1; //Используется как таймер для создания временных задержек (увеличивается на 1 после каждого прерываня таймера)
static volatile uint8_t cursor_position;//Эта переменная будет хранить индех элемента массива данных data_packet.data[x]
                              //который нужно передать следующим



файл ltagfirmware.c

Код:
#include "firmware.h"





int main (void) {                    // Начало выполнения программы, главная функция         
    DDRA |= (1 << 0)|(1<<5)|(1<<7); // Устанавливаем порт PORTA.1 как выход                 
   DDRD &=~(1<<2);             //настраиваем вывод INT0 как вход
   init_timer2();                   // Настраиваем таймер timer2
   init_var();                      //Задаём значения переменным
   sei();
while(1){
         send_ir_package();      //Производим "выстрел"
         //_delay_ms(1000);       // секундная задержка
         timer1=0;            //Сделаем паузу
         while(timer1 < 65000);   //Подождем, пока не произойдет 65000 прерываний таймера (чуть меньше секунды)
         PORTA ^= (1<<5);      //На этой ноге висит вспомогательный светодиод, просто меняет свое состояние в такт с выстрелами
}

return 0;                  /* Выход из программы, в данном случае останов который   */
                           /*  никогда не произойдет т.к. выше бесконечный цикл     */
} //end main




/**************************************************************************************
* Функция выполняет настройку таймера timer2
* Режим работы таймер - СТС (сброс при совпадении)
* тактирование - без делителя, с частотой кварца
* регист сравнения будет иметь такое значение, чтобы прерывания
* генерировались с удвоенной частотой несущей ИК-приемника
***************************************************************************************/


void init_timer2(void){
OCR2 = F_CPU/IR_F0/2-1;       //Прерывания будут генерироваться с частотой, вдвое большей, чем частота несущей
TCCR2 = _BV(CS20)|_BV(WGM21); // Режим работы таймер - СТС (сброс при совпадении)
                              // Тактирование с частотой резонвтора (7 372 800 Гц)
TIMSK |= _BV(OCIE2);          // Разрешаем прерывания по захвату/сравнению
}



void init_var(void){            //Задаём значения переменным
ir_transmitter_on=false;    //Запретим пока передачу данных (поскольку данные ещё не сформированны)
set_player_id(DEFAULT_PLAYER_ID);   //Устанавливаем идентификатор игрока
set_team_color(DEFAULT_TEAM_COLOR);   //Устанавливаем идентификатор (цвет) команды
set_gun_damage(DEFAULT_DAMAGE);      //Устанавливаем мощьность оружия (урон)
data_packet.packet.header = IR_START;      //Устанавливаем  заголовку (старт биту) необходимую длительность
data_packet.packet.end_of_data = 0;      //0 - это указание передатчику, что данных для передачи больше нет
cursor_position = 0; //Курсор - на начало блока данных
}




ISR(TIMER2_COMP_vect){

timer1++;
prt = PIND&(1<<2);  // опрашиваю приемник
if (prt==0) PORTA &= ~(1 << 0); // если ловит несущую, включаю диод (вспомогательный)
else  PORTA |=(1<<0);     // если не ловит несущую - тушу диод (вспомогательный)

if (ir_transmitter_on==true)
   {//Если передача разрешена

      if (ir_pulse_counter > 0)      //необходимая длительность пачки импульсов
      {                        //ещё не достигнута, "мигаем" дальше
         PORTA ^= (1<<7);           //необходимая длительность пачки
         ir_pulse_counter--;
      }
      else                     //пачка импульсов была отправлена,
      {
         PORTA &=~(1<<7);         //тушим ИК-диод
         if ( ir_space_counter > 0)   //проверим, выдержан ли промежуток между импульсами
         {                     //нет, промежуток не выдержан
         
               PORTA &=~(1<<7);   //тушим ИК-диод
               ir_space_counter--;   //уменьшаем обратный счетчик паузы на один "тик"      
         }
         else //Пакет импульсов и промежуток между битами переданы
         {    //нужно формировать следующую пачку (передаваемый бит)
            if (data_packet.data[cursor_position]!=0) //если указатель указывает не на пустую ячейку
            {
               ir_pulse_counter =data_packet.data[cursor_position++] ; //передадим импульс указанной длительностью
               ir_space_counter = IR_SPACE;      //и про паузу не забудем
            }
            else //Все данные переданы (элемент, на который ссылается указатель, равен 0)
            {
               ir_transmitter_on=false; //выключаем передатчик
            }         
         }            
      }




   }
else    {//Если передача запрещена

      }

}

/**************************************************************************************
* Функця производит "выстрел"
* устанавлвает курсор на позицию начала блока данных data_packet.data[0]
* и разрешает передачу данных
* функция возвращает управление  только после отправки всех данных
***************************************************************************************/


void send_ir_package(void){ //Отправляем пакет ("стреляем")
cursor_position = 0;       //Курсор - на начало блока данных
ir_transmitter_on = true;   //Разрешаем передачу
while (ir_transmitter_on);   //Ждем, пока пакет отправиться
}

/**************************************************************************************
* Установка идентификатора игрока
* в качестве аргумента функции указывается идентификационный номер игрока (от 1 до 127)
* в результате выполнения функции в глобальной переменной data_packet.player_id
* будут соответствующим образом инициированы  data_packet.player_id.(bit_0 ... bit_7)
***************************************************************************************/
void set_player_id(uint8_t ID){

uint8_t *p_id_bit;                      //указатель на биты структуры player_id
p_id_bit = &data_packet.packet.player_id.bit_7;    //указывает на 7 "бит" структуры
for (int i=0; i < 7; i++) {             //надо узнать значения 7 младших бит ID
ID = ID << 1;                         //сдвигаем влево на один бит
if (ID&(1<<7))                         //если старший бит = 1
   {
      *p_id_bit-- = IR_ONE;             //присваиваем соответствующее значение  data_packet.player_id.bit_x
   }
else
   {
      *p_id_bit-- = IR_ZERO;
   }

}

data_packet.packet.player_id.bit_0 = IR_ZERO; //согласно протоколу, этот "бит" должен быть равен 0

}



/**************************************************************************************
* Установка идентификатора (цвета) команды
* в качестве аргумента функции указывается идентификационный номер (цвет) команды (от 0 до 3)
* в результате выполнения функции в глобальной переменной data_packet.team_id
* будут соответствующим образом инициированы  data_packet.team_id.(bit_0 и bit_1)
***************************************************************************************/



void set_team_color(tteam_color  color){
switch(color){

      case Red : { //По протоколу 00 = Red
                  data_packet.packet.team_id.bit_0 = IR_ZERO;
                  data_packet.packet.team_id.bit_1 = IR_ZERO;
                  break;   
               }
      case Blue: { //По протоколу 01 = Blue
                  data_packet.packet.team_id.bit_0 = IR_ONE;
                  data_packet.packet.team_id.bit_1 = IR_ZERO;
                  break;   
               }
      case Yellow: { //По протоколу 10 = Yellow
                  data_packet.packet.team_id.bit_0 = IR_ZERO;
                  data_packet.packet.team_id.bit_1 = IR_ONE;
                  break;   
               }
      case Green: { //По протоколу 11 = Green
                  data_packet.packet.team_id.bit_0 = IR_ONE;
                  data_packet.packet.team_id.bit_1 = IR_ONE;
                  break;   
               }


         }




}




/**************************************************************************************
* Установка установка мощьности нашего оружия (наносимый урон)
* в качестве аргумента функции указывается наносимый урон
* в результате выполнения функции в глобальной переменной data_packet.damage
* будут соответствующим образом инициированы  data_packet.damage.(bit_0 и bit_3)
***************************************************************************************/


void set_gun_damage(tgun_damage damage){

switch(damage){
      case Damage_1:{  //По протоколу 0000 = 1
                  data_packet.packet.damage.bit_0 = IR_ZERO;
                  data_packet.packet.damage.bit_1 = IR_ZERO;
                  data_packet.packet.damage.bit_2 = IR_ZERO;
                  data_packet.packet.damage.bit_3 = IR_ZERO;
                  break;
                  }
      case Damage_2:{  //По протоколу 0001 = 2
                  data_packet.packet.damage.bit_0 = IR_ONE;
                  data_packet.packet.damage.bit_1 = IR_ZERO;
                  data_packet.packet.damage.bit_2 = IR_ZERO;
                  data_packet.packet.damage.bit_3 = IR_ZERO;
                  break;
                  }

      case Damage_4:{  //По протоколу 0010 = 4
                  data_packet.packet.damage.bit_0 = IR_ZERO;
                  data_packet.packet.damage.bit_1 = IR_ONE;
                  data_packet.packet.damage.bit_2 = IR_ZERO;
                  data_packet.packet.damage.bit_3 = IR_ZERO;
                  break;
                  }

      case Damage_5:{  //По протоколу 0011 = 5
                  data_packet.packet.damage.bit_0 = IR_ONE;
                  data_packet.packet.damage.bit_1 = IR_ONE;
                  data_packet.packet.damage.bit_2 = IR_ZERO;
                  data_packet.packet.damage.bit_3 = IR_ZERO;
                  break;
                  }
      case Damage_7:{  //По протоколу 0100 = 7
                  data_packet.packet.damage.bit_0 = IR_ZERO;
                  data_packet.packet.damage.bit_1 = IR_ZERO;
                  data_packet.packet.damage.bit_2 = IR_ONE;
                  data_packet.packet.damage.bit_3 = IR_ZERO;
                  break;
                  }
      case Damage_10:{  //По протоколу 0101 = 10
                  data_packet.packet.damage.bit_0 = IR_ONE;
                  data_packet.packet.damage.bit_1 = IR_ZERO;
                  data_packet.packet.damage.bit_2 = IR_ONE;
                  data_packet.packet.damage.bit_3 = IR_ZERO;
                  break;
                  }
      case Damage_15:{  //По протоколу 0110 = 15
                  data_packet.packet.damage.bit_0 = IR_ZERO;
                  data_packet.packet.damage.bit_1 = IR_ONE;
                  data_packet.packet.damage.bit_2 = IR_ONE;
                  data_packet.packet.damage.bit_3 = IR_ZERO;
                  break;
                  }
      case Damage_17:{  //По протоколу 0111 = 17
                  data_packet.packet.damage.bit_0 = IR_ONE;
                  data_packet.packet.damage.bit_1 = IR_ONE;
                  data_packet.packet.damage.bit_2 = IR_ONE;
                  data_packet.packet.damage.bit_3 = IR_ZERO;
                  break;
                  }
      case Damage_20:{  //По протоколу 1000 = 20
                  data_packet.packet.damage.bit_0 = IR_ZERO;
                  data_packet.packet.damage.bit_1 = IR_ZERO;
                  data_packet.packet.damage.bit_2 = IR_ZERO;
                  data_packet.packet.damage.bit_3 = IR_ONE;
                  break;
                  }

      case Damage_25:{  //По протоколу 1001 = 25
                  data_packet.packet.damage.bit_0 = IR_ONE;
                  data_packet.packet.damage.bit_1 = IR_ZERO;
                  data_packet.packet.damage.bit_2 = IR_ZERO;
                  data_packet.packet.damage.bit_3 = IR_ONE;
                  break;
                  }

      case Damage_30:{  //По протоколу 1010 = 30
                  data_packet.packet.damage.bit_0 = IR_ZERO;
                  data_packet.packet.damage.bit_1 = IR_ONE;
                  data_packet.packet.damage.bit_2 = IR_ZERO;
                  data_packet.packet.damage.bit_3 = IR_ONE;
                  break;
                  }
      case Damage_35:{  //По протоколу 1011 = 35
                  data_packet.packet.damage.bit_0 = IR_ONE;
                  data_packet.packet.damage.bit_1 = IR_ONE;
                  data_packet.packet.damage.bit_2 = IR_ZERO;
                  data_packet.packet.damage.bit_3 = IR_ONE;
                  break;
                  }

      case Damage_40:{  //По протоколу 1100 = 40
                  data_packet.packet.damage.bit_0 = IR_ZERO;
                  data_packet.packet.damage.bit_1 = IR_ZERO;
                  data_packet.packet.damage.bit_2 = IR_ONE;
                  data_packet.packet.damage.bit_3 = IR_ONE;
                  break;
                  }

      case Damage_50:{  //По протоколу 1101 = 50
                  data_packet.packet.damage.bit_0 = IR_ONE;
                  data_packet.packet.damage.bit_1 = IR_ZERO;
                  data_packet.packet.damage.bit_2 = IR_ONE;
                  data_packet.packet.damage.bit_3 = IR_ONE;
                  break;
                  }
      case Damage_75:{  //По протоколу 1110 = 75
                  data_packet.packet.damage.bit_0 = IR_ZERO;
                  data_packet.packet.damage.bit_1 = IR_ONE;
                  data_packet.packet.damage.bit_2 = IR_ONE;
                  data_packet.packet.damage.bit_3 = IR_ONE;
                  break;
                  }

      case Damage_100:{  //По протоколу 1111 = 100
                  data_packet.packet.damage.bit_0 = IR_ONE;
                  data_packet.packet.damage.bit_1 = IR_ONE;
                  data_packet.packet.damage.bit_2 = IR_ONE;
                  data_packet.packet.damage.bit_3 = IR_ONE;
                  break;
                  }



         }



}




Вопросы, замечания, пожелания?


У кого есть "камень" (Atmega16) под рукой, залейте, попробуйте, отпишитесь.
Жаль, осцилогрофа у меня нет.
И на реальном Милесе бы проверить, вдруг биты не в той последовательности передаются.
Сечас буду маны курить по поводу внешних прерываний.
Как прием организовать - пока не определился, есть пара вариантов, какой лучше - не знаю.

_________________
Ваше оружие становиться значительно эффективней, если его снять с предохранителя!


Последний раз редактировалось Pingvin 21 сен 2011, 12:51, всего редактировалось 1 раз.

Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 21 сен 2011, 12:35 
Не в сети
Местный

Зарегистрирован: 12 апр 2011, 15:01
Сообщений: 357
Откуда: СПб
куда заливать то? мк какой?
Какой компилятор?
Нужно поподробнее описать.

_________________
"шарик" - дура, луч - молодец


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 21 сен 2011, 12:57 
Не в сети
Аксакал форума
Аватар пользователя

Зарегистрирован: 12 авг 2011, 16:55
Сообщений: 7514
Откуда: Барнаул, Алтайский край (не путать с республикой Алтай) :-)
KorSar писал(а):
куда заливать то? мк какой?
Какой компилятор?
Нужно поподробнее описать.

Прошу прощения. :oops:

Камень - Atmega16
Компилятор - avr-gcc (WinAVR) под AVR-Studio 4.
Если кварц другой - укажите нужную частоту в свойствах проекта (или руками в хедере), все должно автоматом настроиться правильно.

_________________
Ваше оружие становиться значительно эффективней, если его снять с предохранителя!


Последний раз редактировалось Pingvin 22 сен 2011, 08:52, всего редактировалось 1 раз.

Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 21 сен 2011, 13:59 
Не в сети
Местный

Зарегистрирован: 13 июл 2011, 17:05
Сообщений: 475
Откуда: Perm
суровые свитчи, блин. и работа с битами отправки тож бескомпромиссная :)
в milesI передаются сначала старшие. возможно, что и в II тож старшие вперёд.

осциллографа нет, но вечером залью - выложу результат с логического анализатора.
[offtop]а почта дошла?[/offtop]


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 21 сен 2011, 22:58 
Не в сети
Местный

Зарегистрирован: 13 июл 2011, 17:05
Сообщений: 475
Откуда: Perm
работает. файл logicdata с анализатора (http://www.saleae.com/downloads/ ) выложил на http://thesimplestone.net/ltag_pingv.logicdata (на форум только картинки даёт закачать) - 0-й канал - pina.5, 1-й - pina.7. надо стрельнуть во что-нить, чтоб проверить :) если с софтинкой какие-то проблемы будут, могу выложить скриншотами.


Вложения:
ltag_pinv.gif
ltag_pinv.gif [ 8.63 KiB | Просмотров: 16002 ]
Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 22 сен 2011, 07:14 
Не в сети
Аксакал форума
Аватар пользователя

Зарегистрирован: 12 авг 2011, 16:55
Сообщений: 7514
Откуда: Барнаул, Алтайский край (не путать с республикой Алтай) :-)
tommy писал(а):
суровые свитчи, блин. и работа с битами отправки тож бескомпромиссная :)
в milesI передаются сначала старшие. возможно, что и в II тож старшие вперёд.

осциллографа нет, но вечером залью - выложу результат с логического анализатора.
[offtop]а почта дошла?[/offtop]

Почта дошла, спасибо, обязательно ознакомлюсь.
Пока бегло взглянул. А решение проблемы формирования задержек не NOP-ами я уже предлагал - это реализация параллельных потоков. Исходники выкладывал.
Пока один поток ожидает какого-либо события (или держит паузу), второй (третий, четвертый ...) спокойно делают свою работу. Ну это отдельная тема для обсуждения. :)


Переделал хедер и функцию set_player_id() под "правельный" милес (старшие биты уходят первыми):
теперь types.h выглядит так
Код:

#ifndef bool

                        #define bool unsigned char

                        #define true 1

                        #define false 0

#endif

//---------------------------------------------------------------------//

enum Team_Color {Red, Blue, Yellow, Green}; //Определим перечисляемый тип

typedef enum Team_Color tteam_color;            //для работы с цветом команды

/*
00 = Red
01 = Blue
10 = Yellow
11 = Green
*/

//---------------------------------------------------------------------//





//Определим перечисляемый тип
//для работы с "уроном"
enum GunDamage {   Damage_1, Damage_2, Damage_4, Damage_5,
            Damage_7, Damage_10, Damage_15, Damage_17,
            Damage_20, Damage_25, Damage_30, Damage_35,
            Damage_40, Damage_50, Damage_75, Damage_100};                            
typedef enum GunDamage tgun_damage;    

/*
0000 = 1
0001 = 2
0010 = 4
0011 = 5
0100 = 7
0101 = 10
0110 = 15
0111 = 17
1000 = 20
1001 = 25
1010 = 30
1011 = 35
1100 = 40
1101 = 50
1110 = 75
1111 = 100
*/

//---------------------------------------------------------------------//

//Определим структуру для хранения идентификатора игрока
//в ней будем хранить длительность импулсов  в "тиках" таймера (IR_ZERO или IR_ONE)
typedef struct PlayerID {
uint8_t bit_7;//последний бит (всегда должен быть равен IR_ZERO)
uint8_t bit_6;
uint8_t bit_5;
uint8_t bit_4;
uint8_t bit_3;
uint8_t bit_2;
uint8_t bit_1;
uint8_t bit_0;//Первый бит
} tplayer_id;

/*
union player_id_union {
tplayer_id bits;
uint8_t data [8];
};
*/



//Определим структуру для хранения идентификатора игрока
//в ней будем хранить длительность импулсов в "тиках" таймера (IR_ZERO или IR_ONE)
typedef struct TeamID{
uint8_t bit_1;
uint8_t bit_0;
} tteam_id;
 


//Определим структуру для хранения идентификатора игрока
//в ней будем хранить длительность импулсов в "тиках" таймера (IR_ZERO или IR_ONE)
typedef struct Damage{
uint8_t bit_3;
uint8_t bit_2;
uint8_t bit_1;
uint8_t bit_0;

} tdamage;

//Теперь опишем структуру пакета данных
typedef struct DataPacket {
uint8_t header; //заголовок, всегда должен быть равен IR_START (1 Байт)
tplayer_id player_id; //после заголовка идет идентификатор игрока (8 Байт)
tteam_id team_id;     //Затем идентификатор команды (2 Байта)
tdamage damage;        //Ну и последним стоит "урон" (4 Байта)
uint8_t end_of_data;  //Метка, указывающая передатчику, что данных для отправки больше нет (всегда должна быть равна 0) (1 Байт)
} tdata_packet;



//---------------------------------------------------------------------//

union data_packet_union{
tdata_packet packet;
uint8_t data[16];
};




А функция так
Код:
/**************************************************************************************
* Установка идентификатора игрока
* в качестве аргумента функции указывается идентификационный номер игрока (от 1 до 127)
* в результате выполнения функции в глобальной переменной data_packet.player_id
* будут соответствующим образом инициированы  data_packet.player_id.(bit_0 ... bit_7)
***************************************************************************************/
void set_player_id(uint8_t ID){

uint8_t *p_id_bit;                      //указатель на биты структуры player_id
p_id_bit = &data_packet.packet.player_id.bit_6;    //указывает на 6 "бит" структуры
for (int i=0; i < 7; i++) {             //надо узнать значения 7 младших бит ID
ID = ID << 1;                         //сдвигаем влево на один бит
if (ID&(1<<7))                         //если старший бит = 1
   {
      *p_id_bit++ = IR_ONE;             //присваиваем соответствующее значение  data_packet.player_id.bit_x
   }
else
   {
      *p_id_bit++ = IR_ZERO;
   }

}

data_packet.packet.player_id.bit_7 = IR_ZERO; //согласно протоколу, этот "бит" должен быть равен 0

}





Если не затруднит, исправьте исходники и проверьте на эмуляторе, пожалуйста, а то я пока с ним не разобрался. Как туда исходные данные заносить? Что они из себя представляют?
И побалуйтесь с различными значениями ID игрока, цвета команды, урона, а то по дефолту везде почти нули получаются, не поймешь, правильно передаются биты или нет. :)

_________________
Ваше оружие становиться значительно эффективней, если его снять с предохранителя!


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 22 сен 2011, 09:59 
Не в сети
Местный

Зарегистрирован: 13 июл 2011, 17:05
Сообщений: 475
Откуда: Perm
а я тож не разбирался с эмулятором :) вечером таких же logicdata файликов могу наделать - на реальной железке посмотреть гораздо интересней.

а выстрел NOP'ами, таймерами или ещё как - эт не так уж и важно. вот бы схемку, чтоб на ик 1-1.5А падало с питанием от пальчиковых батареек и чтоб под периферию место было и усилок где-нить на 8вт и чтоб разводилось потом на односторонней плате :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 22 сен 2011, 10:53 
Не в сети
Местный

Зарегистрирован: 09 июн 2011, 11:32
Сообщений: 366
Откуда: Шахты
tommy писал(а):
суровые свитчи, блин. и работа с битами отправки тож бескомпромиссная :)
в milesI передаются сначала старшие. возможно, что и в II тож старшие вперёд.


И бессмысленные. Гораздо проще работать с индексами массивов чем с enum и потом switch

GunDamage[16] = {1,2,4,5,7,10,15,17,20,25,30,35,40,50,75,100} индекс массива определяет уровень ущерба

можно и символьные имена добавить

enum GunDamage { Damage_1, Damage_2, Damage_4, Damage_5,
Damage_7, Damage_10, Damage_15, Damage_17,
Damage_20, Damage_25, Damage_30, Damage_35,
Damage_40, Damage_50, Damage_75, Damage_100 };

enum Team_Color {Red, Blue, Yellow, Green}; //Определим перечисляемый тип

и обращаться к массиву не по индексу а по нумерованному символьному имени. Тогда отпадает необходимость в длинных switch


В итоге подготовка даннах к выстрелу будет представлять из себя


unsigned char id_gamer // Номер игрока в команде
unsigned char bufer_ir_tx[2] // Буфер данных излучателя

// Процедура подготовки данных для выстрела
void load_tx_data( void )
{
bufer_ir_tx[0] = id_gamer;
bufer_ir_tx[1] = TeamColor;
bufer_ir_tx[1] = bufer_ir_tx[1] << 4;
bufer_ir_tx[1] += GunDamage[ Damage_10 ];
bufer_ir_tx[1] = bufer_ir_tx[1] << 2;
}


/*
Данные готовы можно отправлять указатель на буфер данных излучателя
и методом сдвига влево передаем сначало 8 бит даныых из масиива по индексу [0] а затем
6 байт из массива по индексу [1]
*/


Можно еще проще. Прямо ничего не формировать а при програмировании ( смене ) i_gamer и Team_Color + GunDamage просто занести в EEprom в виде двух байтов

eeprom unsigned char id_gamer = 01010101; // Игрок с номером 85 ( 0x55 )
eeprom unsigned char Team_Color + GunDamage = 10010100; // Цвет команды 2 ( желтые по твоей нумерации ) и ущерб составит 10% индекс массива [5]

как бы так.

_________________
Неважно откуда у тебя растут руки если они золотые.


Последний раз редактировалось jong73 22 сен 2011, 12:43, всего редактировалось 6 раз(а).

Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 22 сен 2011, 11:19 
Не в сети
Аксакал форума
Аватар пользователя

Зарегистрирован: 12 авг 2011, 16:55
Сообщений: 7514
Откуда: Барнаул, Алтайский край (не путать с республикой Алтай) :-)
jong73 писал(а):
tommy писал(а):
суровые свитчи, блин. и работа с битами отправки тож бескомпромиссная :)
в milesI передаются сначала старшие. возможно, что и в II тож старшие вперёд.


И бессмысленные. Гораздо проще работать с индексами массивов чем с enum и потом switch

GunDamage[16] = {1,2,4,5,7,10,15,17,20,25,30,35,40,50,75,100} индекс массива определяет уровень ущерба

можно и символьные имена добавить

enum GunDamage { Damage_1, Damage_2, Damage_4, Damage_5,
Damage_7, Damage_10, Damage_15, Damage_17,
Damage_20, Damage_25, Damage_30, Damage_35,
Damage_40, Damage_50, Damage_75, Damage_100 };

и обращаться к массиву не по индексу а по нумерованному символьному имени. Тогда отпадает необходимость в длинных switch


Рад, что подключились к обсуждению. :)
Конструктивная критика - это всегда на пользу.

Только я не понял, как тогда должна выглядеть функция set_gun_damage()?
Что передавать в качестве аргумента? Индекс? А что с ним дальше делать? Мне надо проинициировать соответствующим образом поля структуры пакета данных.
А символьные имена я и так определил.
Честно говоря, не понял, что Вы имели ввиду, когда написали, что без switch() можно обойтись. :?
Было бы можно, если уровень урона соответствовал фактическому содержимому переменной, однако урон=1 шифруется 0000 (бинарное значение - ноль), урон=5 шифруется 0011(бинарное значение - 3) и т.д.
Поясните.

_________________
Ваше оружие становиться значительно эффективней, если его снять с предохранителя!


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 22 сен 2011, 11:22 
Не в сети
Аксакал форума
Аватар пользователя

Зарегистрирован: 12 авг 2011, 16:55
Сообщений: 7514
Откуда: Барнаул, Алтайский край (не путать с республикой Алтай) :-)
tommy писал(а):
а я тож не разбирался с эмулятором :) вечером таких же logicdata файликов могу наделать - на реальной железке посмотреть гораздо интересней.

а выстрел NOP'ами, таймерами или ещё как - эт не так уж и важно. вот бы схемку, чтоб на ик 1-1.5А падало с питанием от пальчиковых батареек и чтоб под периферию место было и усилок где-нить на 8вт и чтоб разводилось потом на односторонней плате :)

Ничего не понимаю!(С) :?
А как же Вы протестировали код?
И как вы "рисуете" logicdata файлики?

_________________
Ваше оружие становиться значительно эффективней, если его снять с предохранителя!


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 71 ]  На страницу 1, 2, 3, 4, 5 ... 8  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB