Sabbah писал(а):
Подскажи какие разделы в прошивке правились, хочу 3.0 тоже подправить.
В файле types.h описываем новую структуру
Код:
//--------------------------------------------------
typedef struct IR_Tx_Buffer_Cursor {
uint8_t byte_pos; //номен байта в буфере передатчика
uint8_t bit_mask;//битовая маска для получения текущего бита
uint16_t bits_for_tx;//сколько бит нужно ещё передать
} tir_tx_buffer_cursor;
Заводим новую переменную в файле global_variables.c
Код:
volatile tir_tx_buffer_cursor ir_tx_buffer_cursor; //курсор передающего ИК буфера
И экспортируем её в файле ltag_ascetic.h а так же переменную-буфер передатчика (просто в предыдущих прошивках я её объявил, но не экспортировал - косяк)
Код:
extern volatile tir_tx_buffer_cursor ir_tx_buffer_cursor; //курсор передающего ИК буфера
extern volatile uint8_t tx_buffer[TX_BUFFER_SIZE]; //Буффер ИК-передатчика
Удаляем из файлов global_variables.c и ltag_ascetic.h все объявления переменной
Код:
volatile union data_packet_union data_packet; //В этой переменной будем формировать пакет данных для отправки через IR
Или просто закомментируйте эти строки - теперь через эту переменную не работаем, будем работать непосредственно с буферои ИК передатчика.
Так же закомментируйте в вункции init_var() в файле ltag_ascetic.c эти строки
Код:
//data_packet.packet.header = IR_START; //Устанавливаем заголовку (старт биту) необходимую длительность
//data_packet.packet.end_of_data = 0; //0 - это указание передатчику, что данных для передачи больше нет
или удалите их
Теперь переписываем функции в файле ltag_ascetic.с
Код:
/**************************************************************************************
* Установка идентификатора игрока
* в качестве аргумента функции указывается идентификационный номер игрока (от 1 до 127)
* в результате выполнения функции в глобальной переменной data_packet.player_id
* будут соответствующим образом инициированы data_packet.player_id.(bit_0 ... bit_7)
***************************************************************************************/
void set_player_id(uint8_t ID){
tx_buffer[0]= ID;
tx_buffer[0] &=~(1<<7);//седьмой бит в выстреле всегда равен "0"
}
/**************************************************************************************
* Установка идентификатора (цвета) команды
* в качестве аргумента функции указывается идентификационный номер (цвет) команды (от 0 до 3)
* в результате выполнения функции в глобальной переменной data_packet.team_id
* будут соответствующим образом инициированы data_packet.team_id.(bit_0 и bit_1)
***************************************************************************************/
void set_team_color(tteam_color color){
tx_buffer[1] &=~((1<<7)|(1<<6));//обнуляем два старших бита
tx_buffer[1] |=(color <<6);//устанавливаем 6 и 7 биты в соответствии с цветом команды
}
/**************************************************************************************
* Установка установка мощьности нашего оружия (наносимый урон)
* в качестве аргумента функции указывается наносимый урон
* в результате выполнения функции в глобальной переменной data_packet.damage
* будут соответствующим образом инициированы data_packet.damage.(bit_0 и bit_3)
***************************************************************************************/
void set_gun_damage(tgun_damage damage){
tx_buffer[1] &=~((1<<5)|(1<<4)|(1<<3)|(1<<2));//обнуляем биты урона
tx_buffer[1] |=(damage << 2);
}
Так же в этом файле добавим функцию "курсор-домой"
Код:
void ir_tx_cursor_home(void){//устанавливаем курсор в начало буфера
ir_tx_buffer_cursor.byte_pos = 0;
ir_tx_buffer_cursor.bit_mask = (1<<7);
ir_pulse_counter = IR_START; //передадим заголовоке
ir_space_counter = IR_SPACE;// и заголовок
}
и не забываем задеклалрировать ей в файле ltag_ascetic.h
Код:
void ir_tx_cursor_home(void);//устанавливаем курсор в начало буфера
и меняем функцию передачи пакета
Код:
/**************************************************************************************
* Функця производит "выстрел"
* устанавлвает курсор на позицию начала блока данных data_packet.data[0]
* и разрешает передачу данных
* функция возвращает управление только после отправки всех данных
***************************************************************************************/
void send_ir_package(void){ //Отправляем пакет ("стреляем")
//ir_pulse_counter=IR_START;
//cursor_position = 0; //Курсор - на начало блока данных
ir_tx_cursor_home();//Курсор - на начало буфера
ir_tx_buffer_cursor.bits_for_tx=14;//"выстрел" состоит из 14 бит
ir_transmitter_on = true; //Разрешаем передачу
TIMSK |= _BV(OCIE2); // Разрешаем прерывания по захвату/сравнению
FIRE_LED_ON;
//while (ir_transmitter_on); //Ждем, пока пакет отправиться
}
Ну и самое главное - переписываем прерывание в файле isr.c
Код:
/**************************************************************************************
* Обработчик прерываний таймера
***************************************************************************************/
ISR(TIMER2_COMP_vect){
//timer1++;
static volatile uint8_t prt;
prt = TSOP_IN&TSOP_PIN;
if (prt==0) //На ножке ИК-приемника низкий уровень сигнала (пойман сигнал несущей)
{
// PORTA &= ~(1 << 0); //включаем вспомогательный светодиод
low_level_counter++;//Увеличиваем счетчик длительности низкоуровнего сигнала на ножке ИК-приемника
// // if (chit_detected_counter < (IR_ZERO*1000)) chit_detected_counter++;
// // if (chit_detected_counter >= (IR_ZERO*1000)) chit_detected=true;
}
else //На ножке ИК-приемника высокий уровень сигнала (пойман сигнал несущей)
{
// PORTA |=(1<<0); //выключаем вспомогательный светодиод
// // chit_detected_counter = 0;
// // if (chit_detected) chit_detected=false;
high_level_counter++;///Увеличиваем счетчик длительности высокоуровнего сигнала на ножке ИК-приемника
if((start_bit_received)&&(high_level_counter > IR_ZERO*8)/*&&(bit_in_rx_buff>=13)*/)
{//Фиксируем окончание приема по таймауту
start_bit_received = false; //отменяем прием
if (bit_in_rx_buff>=13) rx_event = RX_COMPLETE; //Генерим событие "принят пакет"
else rx_event = RX_ERROR; //генерируем событие - "ошибка приёма"
receiver_on = false;//выключаем приемник
if (ir_transmitter_on==false) TIMSK &=~_BV(OCIE2); //если передача не ведётся - выключаем прерывания
}
if((high_level_counter > IR_ZERO*8)&&(ir_transmitter_on==false))
{
receiver_on = false;//выключаем приемник
TIMSK &=~_BV(OCIE2);
}
}
if (ir_transmitter_on==true)
{//Если передача разрешена
if (ir_pulse_counter > 0) //необходимая длительность пачки импульсов
{ //ещё не достигнута, "мигаем" дальше
IR_LED_INVERT; //необходимая длительность пачки
ir_pulse_counter--;
}
else //пачка импульсов была отправлена,
{
IR_LED_OFF; //тушим ИК-диод
if ( ir_space_counter > 0) //проверим, выдержан ли промежуток между импульсами
{ //нет, промежуток не выдержан
IR_LED_OFF; //тушим ИК-диод
ir_space_counter--; //уменьшаем обратный счетчик паузы на один "тик"
}
else //Пакет импульсов и промежуток между битами переданы
{ //нужно формировать следующую пачку (передаваемый бит)
if (ir_tx_buffer_cursor.bits_for_tx>0) //если указатель указывает не на пустую ячейку
{
if(ir_tx_buffer_cursor.bit_mask == 0)//все биты текущего байта уже переданы
{
ir_tx_buffer_cursor.byte_pos++;//переходим к следующему байту
ir_tx_buffer_cursor.bit_mask = (1<<7); //старший бит уходит первым
}
if (tx_buffer[ir_tx_buffer_cursor.byte_pos]&ir_tx_buffer_cursor.bit_mask)//если текущий бит равен "1"
{
ir_pulse_counter = IR_ONE;//отправим "1" (помигаем 1200 микросекунд)
}
else //текущий бит равен "0"
{
ir_pulse_counter = IR_ZERO;//отправим "0" (помигаем 600 микросекунд)
}
ir_space_counter = IR_SPACE; //и про паузу не забудем
ir_tx_buffer_cursor.bit_mask = (ir_tx_buffer_cursor.bit_mask >> 1); //следующий бит
ir_tx_buffer_cursor.bits_for_tx--; //уменьшаем количество оставшихся бит
// ir_pulse_counter =data_packet.data[cursor_position++] ; //передадим импульс указанной длительностью
}
else //Все данные переданы (элемент, на который ссылается указатель, равен 0)
{
ir_transmitter_on=false; //выключаем передатчик
// display_bullets_update();
FIRE_LED_OFF;
display_bullets_update_now++;
// если
if (!receiver_on) //если нет приема пакета
{
TIMSK &=~_BV(OCIE2); // Запрещаем прерывания по захвату/сравнению
}
//TIMSK |= _BV(OCIE2);
}
}
}
}
else {//Если передача запрещена
}
}
А можно просто подменить файл isr.c
Вроде бы все...
![Озадачен :?](./images/smilies/icon_e_confused.gif)