AVR PCINT prerušenia

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
Dumitru
Příspěvky: 65
Registrován: 11 pro 2015, 01:00

AVR PCINT prerušenia

#1 Příspěvek od Dumitru »

Dobrý deň PCINT prerušenia sa generuje pri zmene úrovne logického signálu z 1-0 alebo 0-1 a mne v hlave vrtaju tieto otazky
1. je možne aby sa mi program v ISR vykonal len pre zmenu z 1 do 0 ? teda zatlačím tlačítko vygeneruje sa prerušenie vykoná sa program v ISR a keď tlačítko pustím tak pre zmenu z 0 do 1 síce sa prerušenie vygeneruje ale program vo vnútri ISR to bude ignorovať

zatiaľ som to skušal obijsť pomocou 2 tlacidiel

Kód: Vybrat vše

ISR(PCINT1_vect)
{
    while (1)
    {
        if(!(PINC & (1<<PC2)))
        {
            i++;
            if(i>=10)
                i = 0;
            break;
        }
    }


}
tlačítkom PC1 sa generuje prerušenie raz keď ho zatlačím prechod z 1 do 0 a vnori sa do cyklusu while a teda keď PC1 pustím tak prechod z 0 do 1 by sa mal ignorovať teda prerušenie sa vykonáva tak nemôže byť znovu vygenerované ? alebo zle tomu rozumiem no a cyklus sa bude vykonávať dovtedy až kým nezatlačím tlačítko PC2 a inkrementuje sa mi i


Problém je v tom :D že moje úvahy asi su zle pretože mne to ani s dvoma tlačítkami nefunguje teda i sa inkrementuje aj pri prechode z 1 do 0 aj z 0 do 1

Uživatelský avatar
rob_brno
Příspěvky: 209
Registrován: 12 říj 2012, 02:00

#2 Příspěvek od rob_brno »

Budto použij int na pinech AVR 2 nebo 3, u kterých se dá nastavit na kterou hranu reagují nebo u toho pcint po vstupu do obsluhy int zkontroluj v jakém je pin stavu. Např. když je v jedničce, tak byl před int v nule a do obsluhy se vstupuje jako reakce na vzestupnou hranu.

Ale obecně není dobré navěsit výstup mech spínače-tlačítka(které generují zákmity) na vstup s interuptem.

Uživatelský avatar
Dumitru
Příspěvky: 65
Registrován: 11 pro 2015, 01:00

#3 Příspěvek od Dumitru »

Zakmity budú ošetrené schmittovym preklapacim obvodom len to testujem na vývojovej doske a tam tlačítka nemam zapojené na INT preto má zaujalo či sa dá aj pomocou PCINT to uskutočniť

Enkoder
Příspěvky: 12
Registrován: 29 bře 2016, 02:00

#4 Příspěvek od Enkoder »

nevim, zkus třeba v podprogramu přerušení hned na jeho začátku po jeho aktivaci (z 1 do 0) změnit reakci na hranu z 0 do 1 (vždycky nastavit na opačnou reakci, než na kterou se to přerušení právě vyvolalo), to se dělá asi v registru EICRA nebo EICRB

a do podprogramu přerušení dej podmínku:
IF (reakce z 1 do 0) potom // test v registrech EICRA nebo EICRB
proveď svůj kód
ELSE
neproveď nic

je mi divný, že chceš vyvolávat i přerušení z 0 do 1 a nechceš s tím nic provádět

zdržovat se v podprogramu přerušení smyčkou while asi nebude to pravé ořechové, ten má být co nejrychleji obsloužen a hurá pryč

Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 01:00

#5 Příspěvek od AB1 »

Jsi ve svém kódu docela blízko.
Zkus toto

Kód: Vybrat vše

ISR(PCINT1_vect) 
{ 
        if(!(PINC & (1<<PC1)))   // jestli je sestupná hrana
        { 
            i++; 
            if(i>=10) 
                i = 0; 
        } 
} 
Ale impulsy musí být čisté, s tlačítkem se může vyvolat víc přerušení za sebou na jedno stlačení.

Zákmity se v ISR dají ošetřit, ale za cenu že trvání ISR bude např 200 ms.
V některých programech to jde akceptovat.

Uživatelský avatar
Dumitru
Příspěvky: 65
Registrován: 11 pro 2015, 01:00

#6 Příspěvek od Dumitru »

ani tento kód nie je práve orechové robí to asi nasledujúce ak pred tým to počítalo 0 2 4 6 tak teraz to počíta 1 3 5 7 9 :) skúsim sa pozrieť na registri EICRA a EICRB

Uživatelský avatar
jiriS
Příspěvky: 609
Registrován: 14 led 2014, 01:00
Bydliště: Ašsko
Kontaktovat uživatele:

#7 Příspěvek od jiriS »

V datasheetu si najdi popis, lze využít většinou varianty přerušení vzestupnou, sestupnou hranou nebo změnou stavu.
Zákmity lze ošetřit buď čekací smyčkou (a kontrolou stavu), nebo po dobu zákmitů nepovolovat další přerušení. U mechanických talčítek to bývá cca 20ms (ale není to pravidlem). Zákmity Ti Schmittův obvod nezlikviduje.
Jirka

Uživatelský avatar
Dumitru
Příspěvky: 65
Registrován: 11 pro 2015, 01:00

#8 Příspěvek od Dumitru »

počkať počkať registri EICRA je pre INT0 alebo INT1 a to nie je môj prípad všade čo čítam sa to tak rieši len mne to nefunguje nejako

Uživatelský avatar
Dumitru
Příspěvky: 65
Registrován: 11 pro 2015, 01:00

#9 Příspěvek od Dumitru »

nakoniec som to vyriešil takto neviem či je to najsprávnejšie ale každopádne to funguje

Kód: Vybrat vše

#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "_74HC595.h"
static const uint8_t cislovky[] PROGMEM = {3,159,37,13,153,73,65,31,1,9};
volatile uint8_t i = 0;
void tlacitko_init(void)
{
    DDRC &=~((1<<PC1)|(1<<PC2)); // vstup
    PORTC |= (1<<PC1)|(1<<PC2); //pull - up
    PCICR = (1<<PCIE1);  // prerusenie
    PCMSK1 = (1<<PCINT9); // maska
    // PCIFR = (1<<PCIF1); // toto este neviem naco je
}
ISR(PCINT1_vect)
{
    if(!(PINC & (1<<PC1))) // z 1 do 0
    {
        i++;
        if(i>=10)
            i = 0;
        PCICR &=~(1<<PCIE1); // zruš prerušenia

    }
}
int main(void)
{

    sei();
    tlacitko_init();
    hc595_init();

    while(1)
    {
        if((PINC & (1<<PC1))) // z 0 do 1
            PCICR |= (1<<PCIE1); // prerušenie povoleno

        hc595_set(pgm_read_byte(&cislovky[i]));
    }
    return 0;
}
[/code]

Enkoder
Příspěvky: 12
Registrován: 29 bře 2016, 02:00

#10 Příspěvek od Enkoder »

Dumitru píše:počkať počkať registri EICRA je pre INT0 alebo INT1 a to nie je môj prípad všade čo čítam sa to tak rieši len mne to nefunguje nejako
Jo to jsem se spletl, omlouvám se, dej spíš na rady zkušenějších..

Uživatelský avatar
Dumitru
Příspěvky: 65
Registrován: 11 pro 2015, 01:00

#11 Příspěvek od Dumitru »

Dobrý deň neviete poradiť prečo na pre OCR1A prerušenie funguje a pre OCR1B nie ?

Na porte PB4 mam 500Hz aj na porte PB3 ak nastavím OCR1A = 3477 a OCR1B = 15999
Na porte PB4 mam 2.3kHz a aj na porte PB3 je 2.3kHz

Kód: Vybrat vše

void Timer1_CTC_init(void)
{
    TCCR1A = 0;
    TCCR1B = (1<<WGM12)|(1<<CS10);// wgms12 = CTC rezim kedze mame 16bitove registre nie je potrebne pouzit delicku
    TCNT1 = 0;
    OCR1B = 3477; //2.3kHz
    OCR1A = 15999; // 1ms (500Hz) zaciname od 0 (16000-1);
    TIMSK1 = (1<<OCIE1A)|(1<<OCIE1B); // povolime prerusenie
    

}
ISR(TIMER1_COMPA_vect)
{
    TickCounter++;
    PORTB ^= _BV(PB4);
}
ISR(TIMER1_COMPB_vect){
    PORTB ^= _BV(PB3);
}
int main(void)
{

    DDRB |= (1<<PB4)|(1<<PB3);
    PORTB |=(1<<PB4)|(1<<PB3);
    Timer1_CTC_init();
    sei();

    while(1)
    {
       

    }


    return 0;
}
Naposledy upravil(a) Dumitru dne 11 dub 2016, 20:12, celkem upraveno 1 x.

Uživatelský avatar
msar
Příspěvky: 253
Registrován: 22 dub 2006, 02:00
Bydliště: Hradec Králové

#12 Příspěvek od msar »

Hodnoty výstupů bych neměnil v obsluze přerušení, ale nastavil v TCCR1A změnu úrovně při compare match - bity COM1A0 a COM1B0 na 1 (platí pro ATmega8, nevím jaký používáš procesor)

Uživatelský avatar
Dumitru
Příspěvky: 65
Registrován: 11 pro 2015, 01:00

#13 Příspěvek od Dumitru »

Atmega328p ja ani nechcem meniť hodnotu vytupu v obsluhe to je len skúška či to funguje a je nastavene ok a ďalej môžem nato naväzovať program problém je že to nejde a nejde a neviem kde robím chybu :(

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#14 Příspěvek od lesana87 »

A co ti není jasné, že máš na obou výstupech stejnou frekvenci? Vždyť je to jeden čítač, tak nemůže mít dvě různé frekvence, jen dvě různé střídy nebo různou fázi. Koukni se na ty výstupy osciloskopem, budou navzájem posunuté.

Uživatelský avatar
Dumitru
Příspěvky: 65
Registrován: 11 pro 2015, 01:00

#15 Příspěvek od Dumitru »

A keď inicializujem Timer2 v tom istom kode tak to už by mohlo chodiť ved to je nezávisle či ?

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“