Stránka 1 z 2
AVR PCINT prerušenia
Napsal: 30 bře 2016, 21:01
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

ž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
Napsal: 31 bře 2016, 08:17
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.
Napsal: 31 bře 2016, 10:15
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ť
Napsal: 31 bře 2016, 14:12
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č
Napsal: 31 bře 2016, 17:05
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.
Napsal: 31 bře 2016, 18:49
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
Napsal: 31 bře 2016, 19:20
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
Napsal: 31 bře 2016, 19:22
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
Napsal: 31 bře 2016, 19:50
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]
Napsal: 31 bře 2016, 20:13
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..
Napsal: 11 dub 2016, 16:24
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;
}
Napsal: 11 dub 2016, 17:01
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)
Napsal: 11 dub 2016, 17:13
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

Napsal: 11 dub 2016, 18:18
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é.
Napsal: 11 dub 2016, 20:14
od Dumitru
A keď inicializujem Timer2 v tom istom kode tak to už by mohlo chodiť ved to je nezávisle či ?