RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
pierro
Открыл глаза
Сообщения: 66
Зарегистрирован: Вс фев 14, 2010 14:48:19
Откуда: Львов

RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Сообщение pierro »

Всем привет

Я уже в отчаянии, даже не знаю куда копать, но чувствую - проблема - что двумя пальцами щелкнуть.

Подключил к atmega8 lcd экран wh1602 (к порту D) - работаєт отлично. Кварц 12 мГц. Подключил TSOP1736 на преривание INT1 (так как INT0 уже занят екраном)- на микроконтроллер приходить импульсы. За основу реализация использую кусок кода (по всему инету он разбросан) взятого здесь Подобрал длинный и короткий интервалы.

atmega8
Изображение

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

//Временные пределы
#define TminShort 25 //короткий промежуток
#define TmaxShort 35

#define TminLong 75 //длинный промежуток
#define TmaxLong 90


С этим все хорошо, получаю 16 импульсов в совокупности.

Проблема.
Главной затик - здесь (3 дня уже "мозги на изнанку")

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

RC5_buffer [sct_bit] = !PIND.3;

- я всегда получаю 0. нету ни одного прерывания, где бы я получил высокий уровень.

Код, который я использую (много тестового кода, и много закомментировал( некоторый временно выкинул - чтобы не мешало)
Временно - таймер у меня бежит постоянно

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

#include <mega8.h>
#include <Stdlib.h>
#include <delay.h>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>

///////////////////
//Счетчик битов RC5
unsigned char sct_bit = 0, sct_bitMax = 0, iCountDEBUG = 0;

#define MAX_BUF_DEBUG 32
char sDebug[MAX_BUF_DEBUG];


//Буффер RC5
unsigned char RC5_buffer [16];


//Временные пределы
#define TminShort 25 //короткий промежуток
#define TmaxShort 35

#define TminLong 75 //длинный промежуток
#define TmaxLong 90


// Declare your global variables here
unsigned int g_iTime = 0;
char psBuff[16];

#define MAX_BUF 128
unsigned char g_inDelay[MAX_BUF]; //Буффер промежутков
unsigned char g_inDelayCount = 0;

//Флаг попадания в промежутки
unsigned char not_korr = 0;
//число в счетчике таймера
unsigned char Timer = 0;
//переменные кодов
unsigned char startbit2 = 0;
unsigned char trigger = 0;
unsigned int device = 0;
unsigned char command = 0;

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
    Timer = TCNT0; //запоминаем значение счетчика       /////////////////////////////////////
    TCNT0 = 0;     //обнуляем счетчик
    not_korr = 1;     

    if(g_inDelayCount < MAX_BUF-1)
    {
        g_inDelay[g_inDelayCount++] = Timer;         
    }


    if (0 == sct_bit)
    {
            RC5_buffer [sct_bit] = !PIND.3;//записываем в эл.массива
            sct_bit++;     
            not_korr = 0;
    }
    else
    {                 
                 
        if ((TminShort < Timer)&&( Timer < TmaxShort))   // проверка короткого промежутка
        {             
                RC5_buffer [sct_bit] = !PIND.3;
                sct_bit++;
                not_korr=0;
        }     
                   
        if ((TminLong < Timer)&&(Timer < TmaxLong))
        { // проверка длинного промежутка

            RC5_buffer [sct_bit] = !PIND.3;
            sct_bit++;
            not_korr = 0;     
        }
                                                 
        if (1 == not_korr)
        {             // если не попали ни в один из промежутков то
            char i = 0;
   
            MCUCR=0x00;
           
            TCNT0 = 0;
            sct_bit = 0;
            //очищаем буффер
            for (i=0; i<14; i++)
            {
                RC5_buffer [i] = 0;
            };
            //отправляем NO Correct takte (отправлять не обязательно - для себя...)
                                           
            // putsf ("T");   //---------->>>>>>>>>>>>>>
        };
     
                   
        if (sct_bit == 16)
        {        // если бит последний то
            sDebug[0] = '6';                 
            //TCCR0 = 0x00; //останавливаем таймер
            TCNT0=0;
            sct_bit = 0;
            //формируем из массива соответствующие коды
            startbit2 = RC5_buffer [1];
            trigger = RC5_buffer [2];
            device = 0;
            command = 0;       
            device = (RC5_buffer [3] << 4)|(RC5_buffer [4] << 3)|(RC5_buffer [5] << 2)|(RC5_buffer [6] << 1)|RC5_buffer [7];                   
            command = (RC5_buffer [8] << 5)|(RC5_buffer [9] << 4)|(RC5_buffer [10] << 3 )|(RC5_buffer [11] << 2)|(RC5_buffer [12] << 1)|RC5_buffer [13];
            for(v=0; v<16;v++)
            {
                sDebug[v+1] = RC5_buffer[v]?'+':'-';
            }     
             
            //отправляем по UART данные
            //printf ("StartBit2 %d  Trigger %d  Device %d  Command %d",startbit2, trigger, device, command); //------>>>>>>
                   
            switch(command)
            {
                case 16:    //отключаем паузу для громкости и не только...
                break;
                                   
                case 17:
                break;
                                   
                case 43:
                break;
                                   
                case 44:
                break;
                                   
                case 42:
                break;
                                   
                case 41:
                break;
                                   
                case 35:
                break;
                                   
                case 14:
                break;
                                                                       
                default:
                    delay_ms (385); //пауза не обязательно - чтобы реакция кнопок была помедленнее... 
            }   
                     
            // сбрасываем флаг прерывания по входу INT0
            //EIFR=0x40;
         
         
        }                                                               
    }   
}

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
     
}

void main(void)
{
int j = 10, i;
char tmp[16];

unsigned char k = 0, kk = 0;

sDebug[0] = '\0';
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTC=0x00;
DDRC=0x7F;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0b1000;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
TCCR0=0x04;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: On
GICR|=0x80;
MCUCR=0x04;
GIFR=0x80;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;


lcd_init(16); /* инициализация на 16 символов */

lcd_clear();        /* очистка дисплея */


g_inDelayCount = 0;
   
   
    j = 10;   

// Global enable interrupts
#asm("sei")

while (1)
      {                     

        lcd_clear(); 
                               
        lcd_gotoxy(0,0);
        lcd_puts(sDebug);               
        iCountDEBUG = 0;

        lcd_gotoxy(0,1); 
        lcd_putsf("v=");
        itoa(device, psBuff);
        lcd_puts(psBuff);
         
        lcd_putsf("m=");
        itoa(command, psBuff);
        lcd_puts(psBuff);   

        delay_ms(2000);
                 

              // для вивода буффера промежутков
        kk = 0;                         
        while(g_inDelayCount > 0)
        {           
            lcd_clear(); 
            sDebug[0] = '\0';             
                                             
            k = 0;
            while(g_inDelayCount > 0 && k < 4)
            {                                         
                g_inDelayCount--;
                itoa(g_inDelay[g_inDelayCount], psBuff);
                strcat(sDebug,psBuff);
                strcatf(sDebug,",");
                k++;
            }

            strcatf(sDebug,">");
            kk++;
            itoa(kk, psBuff);
            strcat(sDebug,psBuff);
            lcd_gotoxy(0,1);
            lcd_puts(sDebug);
           
            delay_ms(2000);
       
        }     

        delay_ms(2000);     
      };
}


Помогите пожалуйста, поки мозги не спалил окончательно :) (или уже спалил :oops: )
phanis
Вымогатель припоя
Сообщения: 513
Зарегистрирован: Сб фев 19, 2011 18:04:08
Откуда: Татарстан, пос. Актюбинский
Контактная информация:

Re: RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Сообщение phanis »

Я думаю если прерывание настроено по спаду, то это нормальное явление, при условии если считывать состояние пина сразу же после прерывания. будет 0.
Аватара пользователя
pierro
Открыл глаза
Сообщения: 66
Зарегистрирован: Вс фев 14, 2010 14:48:19
Откуда: Львов

Re: RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Сообщение pierro »

phanis писал(а):Я думаю если прерывание настроено по спаду, то это нормальное явление, при условии если считывать состояние пина сразу же после прерывания. будет 0.

Списибо за ответ. Но как раз дело в том, что преривание настроено на Any Change
Аватара пользователя
pierro
Открыл глаза
Сообщения: 66
Зарегистрирован: Вс фев 14, 2010 14:48:19
Откуда: Львов

Re: RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Сообщение pierro »

а может проблема в этом? а не знал как это сделать для atmega8(изначально оно было для attiny2313) и просто закомментировал его.

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

// сбрасываем флаг прерывания по входу INT0
//EIFR=0x40;


Может ли это влиять на преривание? и как "его" задать для atmega8?
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Сообщение Мастер Ломастер »

бог мой, сколько кода для приема и отображения RC5-команд :( прерывания, флаги... эта задача решается буквально в 20 строчек без прерываний и всего прочего...
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
pierro
Открыл глаза
Сообщения: 66
Зарегистрирован: Вс фев 14, 2010 14:48:19
Откуда: Львов

Re: RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Сообщение pierro »

Мастер Ломастер Буду благодарен за подсказку, как это сделать. "Я ведь еще только учусь!" (с) :)
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Сообщение Мастер Ломастер »

пользуйтесь трудами изгнанников этого форума :)
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
pierro
Открыл глаза
Сообщения: 66
Зарегистрирован: Вс фев 14, 2010 14:48:19
Откуда: Львов

Re: RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Сообщение pierro »

Мастер Ломастер Идею понял(отличная для простых вариантов). Но я это использовать не могу, так как в основном цикле у меня будет еще очень много чего.
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: RC5 и atmega8 и LCD (опять 25) что то с прерыванием?

Сообщение Мастер Ломастер »

всегда можно найти выход, если был вход :) можно или из основного цикла вынести лишнее "много чего", либо переделать алгоритм на асинхронный... согласитесь, что запустить в нужный момент таймер, который затем отщелкает по прерываниям 14 раз нужные биты - это ведь пустячок :)
битва с дураками проиграна, победители торжествуют. слава победителям!
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»