WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение WiseLord »

А это точно байты? А то Вы код не показали, вдруг там на самом деле массив int-ов.
Реклама
Аватара пользователя
AntonChip
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Сб май 16, 2015 22:42:01
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение AntonChip »

Вот весь код
Спойлер

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "hd44780.h"
const unsigned char HEX[16] PROGMEM="0123456789ABCDEF";
unsigned char signal_time;
static unsigned char ir_ok,ir_decode_ok;
unsigned char ir_code[4];
unsigned char ir_signal[33];
// Прерывание по совпадению T1(каждые 560мкс)
ISR(TIMER1_COMPA_vect)
{
signal_time++; // Счетчик интервалов 
}
// Внешнее прерывание по INT0
ISR(INT0_vect)
{
static unsigned char i;
// Определяем начало приема посылки
if(signal_time > 9) // (4,5ms+562us)/560 = 9 
i = 0; // Выбираем первый интервал
ir_signal[i] = signal_time; // Записываем в буфер значения интервалов 
signal_time = 0; // Обнуляем счетчик интервалов
i++; // Следующий интервал 
if(i == 33) // Если все интервалы приняты
ir_ok = 1; // Устанавливаем флаг окончания приема сигнала 
}
// Функция декодирования сигнала
void ir_decode(void)
{ 
unsigned char k = 0;
unsigned char signal_length,value;
for(unsigned char i = 0; i < 4; i++) // Обработка байтов адреса или команды
  { 
  for(unsigned char j = 0; j < 8; j++) // Обработка 8-ми битов адреса или команды
    {
    k++;
    value = value >> 1; // Сдвигаем биты вправо
    signal_length = ir_signal[k]; // Выбираем следущее значение интервала
    if(signal_length > 4) // Если интервал больше (1,675ms+562us)/560 = 4
      value = value | 0x80; // Добавляем к старшему разряду единицу
    }
  ir_code[i] = value; // Запоминаем в буфере байт адреса или команды
  value = 0; // Обнуляем значение адреса или команды    
  } 
if((ir_code[0] == ~ir_code[1]) && (ir_code[2] == ~ir_code[3]))
{
ir_decode_ok = 1; // Устанавливаем флаг окончания декодирования сигнала
ir_ok = 0; // Сбрасываем флаг окончания приема сигнала
}
else ir_decode_ok = 0; // Сбрасываем флаг окончания декодирования сигнала
}
int main(void)
{
MCUCR |= (1 << ISC01); // Внешнее прерывание по заднему фронту
GICR |= (1 << INT0); // Разрешение внешнего прерывния по INT0
TCCR1B |= (1 << WGM12)|(1 << CS10); // Режим CTC, предделитель 1 
OCR1A = 279; // 1000000/2*(279+1) = 1786Hz(560us)
TIMSK |= (1 << OCIE1A); // Разрешаем прерывание по совпадению Т1 
lcd_init(); // Инициализация ЖК дисплея
sei(); // Глобально разрешаем прерывания
lcd_gotoxy(0, 0);
lcd_string("NEC PROTOCOL    ",16);
lcd_gotoxy(0, 1);
lcd_string("DECODER         ",16);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
lcd_clr(); // Очищаем дисплей
lcd_gotoxy(0, 0);
lcd_string("Adr: 00  Inv: 00",16);
lcd_gotoxy(0, 1);
lcd_string("Com: 00  Inv: 00",16);
while(1)
{
  if(ir_ok) ir_decode(); // Если сигнал принят, декодируем его
    if(ir_decode_ok) // Если обработка сигнала завершена, выводим данные на дисплей
    {
      lcd_gotoxy(5, 0);
      lcd_data(pgm_read_byte(HEX+ir_code[0]/16)); // Выводим данные в шестнадцатиричном виде
      lcd_data(pgm_read_byte(HEX+ir_code[0]%16));
      lcd_gotoxy(14, 0);
      lcd_data(pgm_read_byte(HEX+ir_code[1]/16));
      lcd_data(pgm_read_byte(HEX+ir_code[1]%16));
      lcd_gotoxy(5, 1);     
      lcd_data(pgm_read_byte(HEX+ir_code[2]/16));
      lcd_data(pgm_read_byte(HEX+ir_code[2]%16));
      lcd_gotoxy(14, 1);        
      lcd_data(pgm_read_byte(HEX+ir_code[3]/16));
      lcd_data(pgm_read_byte(HEX+ir_code[3]%16));
      ir_decode_ok = 0; // Сбрасываем флаг окончания декодирования сигнала
    }
   }
}
Последний раз редактировалось AntonChip Вт окт 20, 2015 05:17:50, всего редактировалось 2 раза.
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

почти со 100% уверенностью можно утверждать, что если вы выполните требование объявлять volatile все переменные, используемые и в прерываниях и в остальных местах программы одновременно - проблема исчезнет.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
AntonChip
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Сб май 16, 2015 22:42:01
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение AntonChip »

Нет, все равно не работает. Может еще как-нибудь можно сравнивать элементы массива
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

а как вы выяснили, что не работает именно оператор сравнения? вы уверены, что проблема именно в этом месте?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
hybroid
Друг Кота
Сообщения: 8007
Зарегистрирован: Вс ноя 14, 2010 19:24:26
Откуда: Лукалэнд

Re: WinAvr в вопросах и ответах

Сообщение hybroid »

AntonChip писал(а):Нет, все равно не работает.
Показывай исправленный код. Только под спойлер сверни его..
Реклама
Аватара пользователя
AntonChip
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Сб май 16, 2015 22:42:01
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение AntonChip »

ARV писал(а):а как вы выяснили, что не работает именно оператор сравнения? вы уверены, что проблема именно в этом месте?
Присвоил элементам массива заведомо правильные значения
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

присвоили значения - и что? как вы выяснили, что в других местах нет проблем?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
AntonChip
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Сб май 16, 2015 22:42:01
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение AntonChip »

ARV писал(а):присвоили значения - и что? как вы выяснили, что в других местах нет проблем?
Без функции проверки программа работает, но иногда на дисплей выводятся неверные значения команд, особенно когда пульт находится близко от фотоприемника
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

а вот я вижу, что в вашем коде совершенно все равно, срабатывает ваша проверка или нет - в главном цикле вывод никогда не будет осуществлен, т.к. ir_decode_ok у вас всегда равна нулю.

Код: Выделить всё

if((ir_code[0] == ~ir_code[1]) && (ir_code[2] == ~ir_code[3])){
   ir_decode_ok = 1; // Устанавливаем флаг окончания декодирования сигнала
   ir_ok = 0; // Сбрасываем флаг окончания приема сигнала
}
ir_decode_ok = 0; // Сбрасываем флаг окончания декодирования сигнала
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение Alexeyslav »

А не лучше ли сравнение с инверсией заменить на функцию XOR? если команда будет равна её инверсии, XOR выдаст все единички. Потом применить логическую функцию AND с такой же конструкцией проверки совпадения адреса. Если все нормально, результат будет равен 0xFF.
Аватара пользователя
hybroid
Друг Кота
Сообщения: 8007
Зарегистрирован: Вс ноя 14, 2010 19:24:26
Откуда: Лукалэнд

Re: WinAvr в вопросах и ответах

Сообщение hybroid »

Если после таких "замен" придётся поддерживать код кому-то другому, то другой будет сильно ругаться, с упоминаниями членов семьи первого программиста.
Это логически неверно. Я такие конструкции могу допускать лишь в случаях, когда нужна некоторая оптимизация скорости или размера кода. В данном случае нет необходимости :dont_know:
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

Re: WinAvr в вопросах и ответах

Сообщение Pnjom-Penb »

AntonChip писал(а):Господа, почему это условие не работает?
С переменной value алгоритм обходится несколько странно.
Как минимум, она неинициализирована на первом проходе цикла "for(unsigned char i = 0; i < 4; i++)":
...
unsigned char
signal_length,value;

....for(unsigned char i = 0; i < 4; i++) // Обработка байтов адреса или команды
....{
...........
........value = 0; // Обнуляем значение адреса или команды
....}
А кроме того, неясно, правильно ли устроен алгоритм на втором и последущих проходах этого цикла - ведь "value >>= 1;" будет давать 0 до тех пор, пока не сработает "value |= 0x80;" при "ir_signal[++k] > 4" - так и должно быть?

Во всяком случае, ir_code[0] содержит некую случайную величину, что вполне может обратить все условие в false.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

Pnjom-Penb писал(а):алгоритм обходится несколько странно
о том, что в коде топикстартера полно сомнительных мест и проблема может крыться совсем не там, где он ее ищет, я пытаюсь сказать уже не один раз.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
AntonChip
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Сб май 16, 2015 22:42:01
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение AntonChip »

ARV подскажите, а с этим кодом что не так, пишет Bad

Код: Выделить всё

#include <avr/io.h>
#include "hd44780.h"

unsigned char ir_code[]={0x00, 0xFF, 0x01, 0xFE};

int main(void)
{
lcd_init();

while(1)
{
  if((ir_code[0] == ~ir_code[1]) && (ir_code[2] == ~ir_code[3]))
  {
  lcd_gotoxy(0, 0);
  lcd_string("Good            ",16);
  }
  else
  {
  lcd_gotoxy(0, 0);
  lcd_string("Bad             ",16);
  }
}
}
Последний раз редактировалось AntonChip Вт окт 20, 2015 19:17:18, всего редактировалось 1 раз.
Аватара пользователя
hybroid
Друг Кота
Сообщения: 8007
Зарегистрирован: Вс ноя 14, 2010 19:24:26
Откуда: Лукалэнд

Re: WinAvr в вопросах и ответах

Сообщение hybroid »

Верно пишет. Вторая часть условия возвращает 0, поэтому общий результат условия в if() - тоже 0.
Код ВНЕЗАПНО обновился :)
Последний раз редактировалось hybroid Вт окт 20, 2015 20:29:39, всего редактировалось 1 раз.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

самое занятное, что почему он это пишет - я понимаю :) а вот как сделать, чтобы не писал - не понимаю.

и вообще, avr-gcc ведет себя странновато. по идее, оптимизатор должен лишнее выбрасывать, а он это делает только в свежей версии avr-gcc, а версия WinAVR порождает код с тупым сравнением...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
AntonChip
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Сб май 16, 2015 22:42:01
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение AntonChip »

hybroid писал(а):Верно пишет. Вторая часть условия возвращает 0, поэтому общий результат условия в if() - тоже 0.
Код ВНЕЗАПНО обновился :)
Извиняюсь, код подкорректировал
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

Re: WinAvr в вопросах и ответах

Сообщение Pnjom-Penb »

hybroid писал(а):Вторая часть условия возвращает 0, поэтому общий результат условия в if() - тоже 0.
Первая - тоже false.
ARV писал(а):... а вот как сделать, чтобы не писал - не понимаю.
Да посоветовать, не мудрствуя лукаво, прочесть описание унарной операции '~' и неявное приведение типов. ;)


ТС: если задать явное приведение типов "(unsigned char)", проверка пройдет.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

разобрался. все-таки внимательность - первое дело!
между (unsigned char)~c и ~(unsigned char)c большая разница! :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Ответить

Вернуться в «AVR»