www.open-tager.ru https://open-tager.ru/forum/ |
|
Прошивка. Реализация протокола Miles Tag II https://open-tager.ru/forum/viewtopic.php?f=5&t=293 |
Страница 1 из 8 |
Автор: | Pingvin [ 21 сен 2011, 12:04 ] |
Заголовок сообщения: | Прошивка. Реализация протокола Miles Tag II |
Начал возиться с прошивкой. Для начала попытался реализовать передачу пакета с данными (выстрел). Единственное - так нигде и не нашёл, какие биты должны передаваться первыми - старшие или младшие? Так что не исключено, что получился "зеркальный" 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) под рукой, залейте, попробуйте, отпишитесь. Жаль, осцилогрофа у меня нет. И на реальном Милесе бы проверить, вдруг биты не в той последовательности передаются. Сечас буду маны курить по поводу внешних прерываний. Как прием организовать - пока не определился, есть пара вариантов, какой лучше - не знаю. |
Автор: | KorSar [ 21 сен 2011, 12:35 ] |
Заголовок сообщения: | Re: Прошивка. Реализация протокола Miles Tag II |
куда заливать то? мк какой? Какой компилятор? Нужно поподробнее описать. |
Автор: | Pingvin [ 21 сен 2011, 12:57 ] |
Заголовок сообщения: | Re: Прошивка. Реализация протокола Miles Tag II |
KorSar писал(а): куда заливать то? мк какой? Какой компилятор? Нужно поподробнее описать. Прошу прощения. Камень - Atmega16 Компилятор - avr-gcc (WinAVR) под AVR-Studio 4. Если кварц другой - укажите нужную частоту в свойствах проекта (или руками в хедере), все должно автоматом настроиться правильно. |
Автор: | tommy [ 21 сен 2011, 13:59 ] |
Заголовок сообщения: | Re: Прошивка. Реализация протокола Miles Tag II |
суровые свитчи, блин. и работа с битами отправки тож бескомпромиссная в milesI передаются сначала старшие. возможно, что и в II тож старшие вперёд. осциллографа нет, но вечером залью - выложу результат с логического анализатора. [offtop]а почта дошла?[/offtop] |
Автор: | tommy [ 21 сен 2011, 22:58 ] | ||
Заголовок сообщения: | Re: Прошивка. Реализация протокола Miles Tag II | ||
работает. файл logicdata с анализатора (http://www.saleae.com/downloads/ ) выложил на http://thesimplestone.net/ltag_pingv.logicdata (на форум только картинки даёт закачать) - 0-й канал - pina.5, 1-й - pina.7. надо стрельнуть во что-нить, чтоб проверить если с софтинкой какие-то проблемы будут, могу выложить скриншотами.
|
Автор: | Pingvin [ 22 сен 2011, 07:14 ] |
Заголовок сообщения: | Re: Прошивка. Реализация протокола Miles Tag II |
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 игрока, цвета команды, урона, а то по дефолту везде почти нули получаются, не поймешь, правильно передаются биты или нет. |
Автор: | tommy [ 22 сен 2011, 09:59 ] |
Заголовок сообщения: | Re: Прошивка. Реализация протокола Miles Tag II |
а я тож не разбирался с эмулятором вечером таких же logicdata файликов могу наделать - на реальной железке посмотреть гораздо интересней. а выстрел NOP'ами, таймерами или ещё как - эт не так уж и важно. вот бы схемку, чтоб на ик 1-1.5А падало с питанием от пальчиковых батареек и чтоб под периферию место было и усилок где-нить на 8вт и чтоб разводилось потом на односторонней плате |
Автор: | jong73 [ 22 сен 2011, 10:53 ] |
Заголовок сообщения: | Re: Прошивка. Реализация протокола Miles Tag II |
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] как бы так. |
Автор: | Pingvin [ 22 сен 2011, 11:19 ] |
Заголовок сообщения: | Re: Прошивка. Реализация протокола Miles Tag II |
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) и т.д. Поясните. |
Автор: | Pingvin [ 22 сен 2011, 11:22 ] |
Заголовок сообщения: | Re: Прошивка. Реализация протокола Miles Tag II |
tommy писал(а): а я тож не разбирался с эмулятором вечером таких же logicdata файликов могу наделать - на реальной железке посмотреть гораздо интересней. а выстрел NOP'ами, таймерами или ещё как - эт не так уж и важно. вот бы схемку, чтоб на ик 1-1.5А падало с питанием от пальчиковых батареек и чтоб под периферию место было и усилок где-нить на 8вт и чтоб разводилось потом на односторонней плате Ничего не понимаю!(С) А как же Вы протестировали код? И как вы "рисуете" logicdata файлики? |
Страница 1 из 8 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |