Sari la conținut
ELFORUM - Forumul electronistilor

Incubator full-option!


wolfei

Postări Recomandate

Multumesc inca o data pentru raspunsuri!...Intr-adevar...INTF si RBIF trebuiau sterse in interiorul if{} si tr sa si citesc din portB.

Dar totusi nu merge cum trebuie...Am facut eu un alt proiectel, doar ca sa vad daca merg intreruperile si in general merg bine dar cateodata apas pe buton si nimic...abia a 2-a a 3-a oara imi ia intreruperea.

E si mai grav in proiectul meu principal...imi merge intreruperea pe TMR0=>motorul merge o data inainte si o data inapoi=>dar cand apas pe buton sa se opreasca din mers...nimic :sparge:

Pentru controlul L293D am folosit tutorialul asta: http://www.8051projects.net/dc-motor-interfacing/l293d-interfacing-with-microcontroller.php

Cand apas pe buton ar trebui sa trimit la L293D 0 pe fiecare pin, dar trimit tot ca sa mearga inainte sau inapoi, nu are nici un efect cand apas pe buton.Si am observat ca daca apas pe butoane la un moment dat trimite 1 pe cele 3 linii...

 

 

volatile int intoarce,count;bit   sInainte,sInapoi;void interrupt isr(void) //este apelata cand este generata o intrerupere{  char cPortB;  if(T0IF)//intreruperea este generata de timer0 ?   {      count++;      if(count==152)  //de test , ar trebui sa seteze "intoarce" la 10 sec		{          intoarce=1;         count=0;      	}      T0IF=0;//am procesat intreruperea, resetam flag-ul pentru a se putea apela din nou   }if(INTF)		{				if(sInainte)		sInainte = 0;		else 		sInainte = 1;		INTF = 0;		}if(RBIF)		{		if(sInapoi)		sInapoi = 0;		else 		sInapoi = 1;		cPortB = PORTB;		RBIF = 0;		}}void main(void){float temp_uscat,temp_umed,umid,dif,dif1;int temp,dir=0,rest=0;long count;   		initializari();   	DelayUs(20);   	InitUSART();   	TRISB = 0xFF;   	TRISC = 0x80;	TRISD = 0x00;	while(1){	temp_umed=temp_umf();	DelayUs(250);	temp_uscat=temp_usf();	DelayUs(250);	dif=temp_uscat-temp_umed;	dif1=dif/100;	DelayUs(250);	temp=temp_uscat/100;						if (temp < 38)							//daca temperatura scade sub 38 grade			 RD7=1;							// pornesc rezistenta de nichelina				else 			 RD7=0;											TransmitUSARTC(" \n1.Temperatura uscata este : ");				afisfloat(temp_uscat);				DelayUs(250);								TransmitUSARTC("\n 2.Temperatura umeda este : ");				afisfloat(temp_umed);			    DelayUs(250);				TransmitUSARTC("\n 3.Diferenta este : ");				afisfloat(dif);				DelayUs(250);  if ((dif1 < 5)  || (dif1 > 7)) umid=0;							// umiditatea se alege in functie 	else if ((dif1 >= 5) && (dif1 < 5.5 )) umid=70;				// de diferenta dintre 			else if((dif1 >= 5.5 ) && (dif1 < 6)) 	umid=65;		// cele doua temperaturi				else if((dif1 >= 6) && (dif1 < 6.5)) umid=62;						else umid=60;				TransmitUSARTC("\n 4.Umiditatea este : ");				afisare_usart(umid);				TransmitUSARTC("  %");TransmitUSART(0xd);					DelayUs(250);				TransmitUSARTC("\n");		if(intoarce)		{	  	intoarce=0;		dir+=1;			rest=dir%2;			if(rest)  //daca dir impar merge inainte			{	      		RD0=1;			//comanda de mers inainte			RD1=0;			RD2=1;//enable L293D				if (sInainte)				{				RD0=0;		//comanda de oprire				RD1=0;				RD2=0;//disable L293D				}			}			else			//daca dir par merge inapoi				{				RD0=0;		//comanda de oprire				RD1=1;				RD2=1;//enable L293D					if(sInapoi)					{					RD0=0;		//comanda mers inapoi					RD1=0;					RD2=0;//disable L293D					}				}	  //DelayMs(1000);   		} 				 //DelayMs(1000);   DelayMs(1000);   DelayMs(1000); //delay ca sa mearga mai lent pe terminal afisarea } }

http://img189.imageshack.us/img189/3701/13990514.jpg

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

Top autori în acest subiect

  • wolfei

    18

  • Liviu M

    10

  • puiu

    6

  • Eugen_B

    5

Top autori în acest subiect

Hm, e greu asa, de la distanta.

 

Singurele observatii/idei pe care le am sunt:

- in isr, la inceput, ar fi bine sa dezactivezi intreruperile, altfel se poate intampla sa-ti vina intreruperi noi pe parcursul tratarii unei intreruperi deja venite, caz in care poti avea surprize.

 

void interrupt isr(void) //este apelata cand este generata o intrerupere{   char cPortB;   di();      if(T0IF)//intreruperea este generata de timer0 ?   {...   }...   ei();}

- dupa cum ziceam, RBIF vine de cate ori unul din pinii RB3..RB7 isi schimba starea. Asta inseamna si cand apesi butonul, si cand ii dai drumul. Daca nu inhibi cumva una din directii, sunt sanse ca la o apasare de buton sa-l modifici pe sInapoi de 2 ori la o singura apasare si astfel sa-ti anulezi comanda.

O idee de "reparare" ar fi sa incearci sa testezi si valoarea portului folosit pentru buton si sa modifici sInapoi numai cand RBx e 0 (sau 1, depinde cum e la tine legat).

   if(RBIF && (RBx == 0))   {          if(sInapoi)             sInapoi = 0;          else             sInapoi = 1;         cPortB = PORTB;         RBIF = 0;   }

LE Atata timp cat sInapoi e bit, asra se scrie mai simplu:

   if(RBIF && (RBx == 0))   {         sInapoi ^= 1; // sau sInapoi++;         cPortB = PORTB;         RBIF = 0;   }

LE Inca o idee inainte de culcare: lasa l293-ul tot timpul activ (leaga Enable la +5V), ca s-ar putea ca atunci cand il dezactivezi sa ramana iesirile cam in aer (treestate?), cu efecte necunoscute.

Link spre comentariu

Ms pt raspunsuri...dar nu prea vrea sa mearga.. :sparge: :sparge: :sparge:

Daca pun di() si ei() imi da erori in proteus "Stack underflow executing RETFIE instruction".

EU trimit "1" la RB4 cand apas butonul. Daca pun in conditie

if(RBIF && ( RB4 == 1 ))
nu imi mai afiseaza pe seriala decat cand apas pe buton.

Daca pun in conditie

if(RBIF && ( RB4 == 0 ))
imi da la iesirea L293D niste tensuni tare ciudate...nu e bun...

O bucatica de cood asa de simplu si nu reusesc sa ii dau de cap.

Care e prioritatea in tratarea intreruperilor?! Ma gandesc sa nu fie legat de asta..

Link spre comentariu

1. La PIC-urile din familia 16 toate intreruperile es duc la aceasi adresa deci din punct de vedere hard nu se face nici-o prioritate. Prioritatea se face numai soft ca si salvarea registrilor principali.

Link spre comentariu

1. La PIC-urile din familia 16 toate intreruperile es duc la aceasi adresa deci din punct de vedere hard nu se face nici-o prioritate. Prioritatea se face numai soft ca si salvarea registrilor principali.

Da, am mai citit un pic pe net si am vazut ca nu pot seta nici un bit nimic..doar la 18f este high si low priority...Imi poti explica putin cum se poate face prioritizare in soft?
Link spre comentariu

1. Prioritizarea prin soft este facuta prin ordinea care verifici biti care au oferit intreruperea respectiva. La PIC-urile 18 sunt doua intreruperi la alta adresa si anume la 8 si parca la 18 adresele sunt scrise in Hexa in timp ce la PIC din familia 16 este la adresa 4.

Link spre comentariu

S-ar putea ca probleme sa ai si din cauza ca nu faci nici un fel de "filtrare" a butonului (debouncing).Daca butonul nu e prea stralucit, sunt sanse sa dea, iarasi, mai multe comenzi care, de data asta nu se mai anuleaza reciproc.Daca vrei sa vezi daca prioritatea intreruperilor e de vina, deactiveza restul intreruperilor si vezi daca motorul se invarte cum vrei tu cand apesi pe buton.

Link spre comentariu

Am sa incerc in seara asta sa pun fiecare intrerupere in parte sa vad daca reusesc sa mai gasesc ceva...Inca o intrebare...pentru comanda unui ventilator la 5V de la uC, ce este mai indicat sa folosesc ca switch: un simplu TB 547, un FET cum e 2SJ48 sau un darlington cum e TP120? Am vazut ca merg toate, dar ma intrebam in cazul asta care ar fi mai indicat?

Link spre comentariu
  • 4 luni mai târziu...

Am facut o pauza, dar as vrea sa termin proiectul in sfarsit...

Am incercat sa fac un ceas cum mi-a sugerat puiu ...nu stiu sigur daca e bine facut...astept o parere :da

Insa am vreo cateva dileme la care as avea nevoie de ceva ajutor:

-in caz ca se ia curentul uC se restarteaza?...adik incepe sa ia zilele de la 0 (perioada totala de incubatie e de 21 zile din care doar in primele 18 trebuie intoarse ouale), deoarece eu am un contor care cand ajunge la 18 zile opreste motorul care intoarce ouale

-Daca se ia curentul pot sa observ asta cumva?

-Ceva sugestii despre cum as putea sa trec peste obstacolul cu electricitatea?

-Mi s-a cerut sa fac un meniu ca sa aleg intre perioade de incubatie pt diferite pasari, deci mi-ar mai trebui un buton...cum e mai bine: sa il pun pe un port I/O si sa numar de cate ori apas sau pot sa il pun pe unul din pinii RBx si sa citesc o alta intrerupere?...si daca e varianta b cum citesc o a doua intrerupere de acest gen?

-Am incercat sa fac prioritizarea intreruperilor in soft facand verificarea pt intreruperile de pe pinii RB0 si RB7 mai la inceput...dar tot nu merge...nu stiu daca e bine facuta...astept si aici o parere...

-Am incercat sa fac fiecare intrerupere in parte: doar pt INTF a mers, doar pt RBIF tr sa tin butonul apasat ca sa se simta altfel nu merge si impreuna cu T0IF nu merge deloc...asadar va rog sa aruncati o privire peste intrruperile astea deoarece nu stiu ce nu merge...

Atasez codul si schema in proteus.

Va multumesc in avans :limb:

 

http://imageshack.us/photo/my-images/89/incv.jpg/

Link spre comentariu

M-am uitat putinn prin cod si:

Hi-Tech recomanda definirea variabilelor care pot fi modificate in isr ca volatile.

Any SFR which can be modified by hardware or which drives hardware is qualified as

volatile, and any variables which may be modified by interrupt routines should use

this qualifier as well. For example:

La tine e cazul cu

bit   sInainte=0,sInapoi=0;
.

 

Pentru ca flagurile de intrerupere sunt setate intotdeauna (chiar si atunci cand intreruperea respectiva e dezactivata si nu se genereaza intrerupere), eu am avut la un moment dat ceva efecte interesante cand, in isr, am testat numai flagurile. La tine nu cred ca e cazul (eu comentasem o parte din cod, sa testez ceva), da' cred ca ar fi bine ca in loc de:

if(INTF)	{	if(sInainte)		sInainte = 0;			else 			sInainte = 1;		INTF = 0;	}

sa testezi

if(INTF && INTE){    sInainte ^= 1;   INTF = 0;}
(repet, e vorba de "good practice")

Altfel, nu ma prind de ce nu merg impreuna cele 2 intreruperi (RB0 si RB7..RB4).

Referitor la intrebarea "ce se intampla cand se ia curentul" - raspunsul e: o ia de la capat "ca nou". Ca sa "tina minte" unde a ramas, trebuie sa salvezi din cand in cand variabila pentru zi in eeprom (de exemplu de fiecare data cand se incrementeaza ziua) si sa o citesti la inceputul programului.

Eu am o situatie asemanatoare intr-un proiect si am facut cam asa (folosesc tot picc, asa ca poate te ajuta codul asta):

- chiar la inceput i-am zis compilatorului despre EEPROM

__EEPROM_DATA(2, 190, 2, 186, I2C_ADDR, 0, 0, 0);         /*0..3 - pH limits, 4 - adresa senzorului conectat pe i2c*/
- in main(), in partea de initializare, am citit eepromul in variabile:

ucComBuf[8] = eeprom_read(ucEePhAddress);         // citeste bytes pragurilor  de pH din eeprom   ucComBuf[8+1] = eeprom_read(ucEePhAddress+1);   ucComBuf[8+2] = eeprom_read(ucEePhAddress+2);   ucComBuf[8+3] = eeprom_read(ucEePhAddress+3);
- cand a fost cazul, am rescris eepromul:

eeprom_write(ucEePhAddress,ucComBuf[8]);       /*salveaza tinta de pH in EEPROM si refoloseste-o dupa reset*/	       eeprom_write(ucEePhAddress+1,ucComBuf[8+1]);	       eeprom_write(ucEePhAddress+2,ucComBuf[8+2]);	       eeprom_write(ucEePhAddress+3,ucComBuf[8+3]);
Inca o intrerupere pe pinii RB7..RB4 (pentru butonul de meniu) nu mai poti genera, ca toti pinii RB7..RB4 genereaza aceeasi intrerupere. Cel mult poti face un test suplimentar () sa vezi care din intrarile R7..R4 a generat intreruperea si sa actionezi ca atare.

 

if(RBIF&&RBIE ){   cPortB = PORTB;   if(cPortB && =0xII)  // testezi bitul pentru sInapoi   {      sInapoi ^= 1;   }   if(cPortB && =0xMM)  // testezi bitul pentru meniu	   {      MeniuActiv = 1;   }   RBIF = 0;}
Alte idei deocamdata nu mai am. Daca-mi mai vin, mai scriu.
Link spre comentariu
  • 9 luni mai târziu...

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