Sari la conținut
ELFORUM - Forumul electronistilor

Problema rutina intreruperi Attiny13


Vizitator biwak

Postări Recomandate

Vizitator biwak

Sunt mai la inceput cu programarea microcontrolerelor. Am incercat sa inteleg cum functioneaza intreruperile insa intampin unele probleme:- nu pot seta intreruperea sa se execute pe frontul low sau high al butonului.am inteles ca bitii ISC01, ISC00 seteaza acest lucru insa nu reusesc. intreruperea se executa pentru orice schimbare a starii pinului de intrare ( in cazul meu PCIN3), si cand apas si cand las de buton, inclusiv la spike'uri pe alimentare generate de pistolul de lipit. -doresc ca cu ajutorul unei intreruperi sa comut ledul de pe on pe off (adica apasand o data pe buton sa se aprinda, apasand inca o data sa se stinga). Cum fac asta? Pot transmite o variabila din functia intrerupere catre functia main?Cam asa arata codul meu:#include #include int main (void){ PCMSK |= (1<

Link spre comentariu
  • Răspunsuri 5
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • stefan_k

    3

  • nana

    1

Top autori în acest subiect

Pot transmite o variabila din functia intrerupere catre functia main?

Desigur. Declara-ti o variabila globala, aceasta va putea fi modificata atat in intrerupere cat si citita in functia main. Ca sa nu ai surprize cauzate de optimizarea compilatorului, aceasta variabila trebuie declarata "volatile". Cum am zis, variabila globala. Exemplu:
#include ...volatile uint8_t flag;int main(void){...  if (flag) {...}}...
Pentru inceput, arunca o privire si aici: http://www.nongnu.org/avr-libc/user-manual/FAQ.html
Link spre comentariu
Vizitator biwak

am modificat insa tot nu merge. cum definesc o variabila booleana in C? cu o complementez?#include #include volatile uint8_t flag;int main (void){ PCMSK |= (1<

Link spre comentariu

am modificat insa tot nu merge. cum definesc o variabila booleana in C? cu o complementez?

Legat de restul programului nu am timp sa ma uit acum in datasheet exact ce faci, dar iti pot raspunde legat de limbaj. - unitatea cea mai mica pe care o poti declara e octetul; nu poti declara "un bit" ca sa ai "variabila booleana", si nici nu lucreaza ca alte limbaje in care declari "boolean" dar practic ai tot un octet. De aceea am zis sa folosesti uint8_t, asta e "unitatea uzuala de lucru". - vezi operatorii logici si pe biti, de ex http://en.wikipedia.org/wiki/Operators_ ... _operators - practic pt tine se poate rezolva asa:flag = !flag; // operator logic, trateaza tot octetul (il neaga)flag = ~flag; // operator pe bit, neaga fiecare bit din octet. astfel din 0x00 va deveni 0xff si inversflag = flag ^ 0xff; // XOR pe biti; din 0x00 devine 0xff si inversflag = flag ^ 0x01; // la fel XOR pe biti, dar din 0x00 devine 0x01 si invers, practic pt tine cele doua sunt echivalenteultimel doua se mai pot scrie si:flag ^= 0xff;flag ^= 0x01;Pentru ce vrei tu, toate cele de mai sus fac cam acelasi lucru.
Link spre comentariu

PORTB = 0x01; //LED on else PORTB = 0x00; //LED off

Acum m-am uitat peste attiny13, vad ca e din ala castrat cu putini pini; in cazul tau int3 se afla tot pe portb. Nu e bine sa faci atribuirea direct pe tot portul, in felul acesta poti afecta valoarea portului; chiar nu stiu cum se va comporta, dar corect e sa faci asa ceva:Pentru a pune ON pe bitul ZERO al lui portB:PORTB |= 0x01; (sau PORTB = PORTB | 0x01;)Pentru a pun OFF pe acelasi bit:PORTB &= ~(0x01);sau chiar: PORTB = PORTB & 0x11111110;In felul acesta va afecta doar bitul dorit, si nu tot portul.De asemenea sper ca led-ul ti-e pe bitul zero (PB0).In loc de 0x01 poti sa scrii si 0b00000001 - daca ti-e mai clar sa scrii valoarea booleana decat cea hexa.
Link spre comentariu

1 la mana : variabile booleene in C nu exzista, C-ul trateaza conditile de adevar in felul urmator orice e parametru de conditionare intr-o functie de conditionare(if, while, do wile,etc.) este interpretat in modu urmator ce este 0 este fals si orice este diferit de 0 este adevarat.

2 daca ai fi citit ce scrie in descrierea librariei interrupts din avr-gcc ai fi observat ca se foloseste functia ISR(intrerrupt service rutine) cu vectorul de intrerupere PCINT0_vect. eu nustiu de unde ai scoso tu pe asta (vector de intrerupere)SIG_PCINT ia pune mana pe datasheetul la chip si vezi ce vectori de intrerupere mai exact la pagina 44. SI 3 ti-ar fi sarit in ochii daca ai fi cautat in libraria avr-gcc ca nu exzista o asemenea intrerupere.

3 ar trebui sa activezi si intreruperile in registur GIMSK;

file:///C:/WinAVR-20090313/doc/avr-libc/avr-libc-user-manual/group__avr__interrupts.html

 

deci cam asa trebuie sa arate codu tau:{ :bataie

#include <avr/interrupt.h>#include <util/delay.h>#define F_CPU 4000000ULISR(PCINT0_vect){PORTB = 0; //LED off 1s_delay_ms(1000);}int main (void){PCMSK = (1<<PCINT3); // tell pin change mask to listen to pin2MCUCR = (1<<ISC01);// setez activarea intreruperii pe front descrescatorGIMSK = (1<<INT0)|(1<<PCIE); // enable PCINT interrupt in the general interrupt masksei(); // Enable all interruptsDDRB = (1<<DDB1);while (1) {PORTB = (1<<PB1); //LED on}}
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări