Eugen_B Postat Ianuarie 5, 2011 Partajează Postat Ianuarie 5, 2011 Intreruperea nu are cum sa mearga pentru ca ai declarat count si intoarce local , deci la fiecare apelare va fi zero.count ori il pui "static int count" inauntru la isr , ori il declari global. intoarce e deja declarat global , sterge declararea din isr , numai sa pui declararea ( volatile int intoarce) inainte de isr. Link spre comentariu
Liviu M Postat Ianuarie 5, 2011 Partajează Postat Ianuarie 5, 2011 Referitor la codul asm, e scris pentru 16f84, asa ca sunt sanse mici sa functioneze nemodificat (cred eu, ca un necunoscator de asm ce sunt). Link spre comentariu
wolfei Postat Ianuarie 5, 2011 Autor Partajează Postat Ianuarie 5, 2011 Am pus dif int pt ca imi dadea o eroare la switch, initial era float si tot nu mergea.Dar tot nu inteleg ce ar putea sa fie gresit in bucatica aia de cod.Am sa modific si comentariile, am uitat de ele Multumesc pentru lamuriri, am sa fac dupa-amiaza modificarile la intreruperi. Link spre comentariu
Liviu M Postat Ianuarie 5, 2011 Partajează Postat Ianuarie 5, 2011 Da, comanda swich are ca argument un intreg, da' cum acum folosesti variabila sw in switch, poti face dif float. Nu inteleg ce nu intelegi. Tu compari un intreg (5, 6, 7...) cu 5.5 si te miri ca rezultatul e ori 5 ori 6. La partea cu asm poate te ajuta cineva care chiar il stie (sau il inveti tu, desi ma indoi ca o sa reusesti la noapte); asa cum e acum, insa, nu face decat sa incurce. Tu rezervi memorie/definesti 3 variabile (cu CBLOCK) de la adresa 0x10 fara sa faci vreun test daca acolo e deja ceva. Asta poate duce la multe si nebanuite probleme.Dupa aia ai probleme cu folosirea numelor pe care bucata de asm nu le stie pana nu incluzi as1687x.h. Cand insa incluzi asta, iti redefinesti unele denumiri folosite si de pic.h, rezultand alte probleme, de care habar n-am cum se scapa. Cel putin asa mi-a iesit mie cand am incercat sa compilez proiectul asta. Link spre comentariu
Liviu M Postat Ianuarie 5, 2011 Partajează Postat Ianuarie 5, 2011 Am reusit sa elimin o parte din erori incluzand (nu as...) in partea de assembler si folosind numele corecte pentru cativa registri/biti (TRIS_PORTB in loc de TRISB, de exemplu), da' m-am blocat la erorile gen Error [876] C:\prPic\incubator\incubator.c; 201. syntax error care se refera la CBLOCK (de exemplu).M-am uitat prin manualul de la picc si nu exista CBLOCK asta (in partea de assembler a picc-ului, desigur). In picc variabilele sunt definite cu DB (pentru bytes), DW (pentru words)...Asa ca eu sunt in ceata.LE Se pare ca pe vremuri era o "problema" cunoscuta; se pare ca a ramas la fel:http://forum.htsoft.com/all/showflat.ph ... #Post24185 Link spre comentariu
wolfei Postat Ianuarie 5, 2011 Autor Partajează Postat Ianuarie 5, 2011 Am modificat de atatea ori codul ala ca am si uitat de la ce am pornit...da e logic ca atunci cand compar dif cu 5.5 dif sa fie de tip float...initial asa era si nu a mers..de asta nu intelegeam...intre timp am rez azi problema...si cum era si logic era ceva super simplu pe care nu il vedeam.. Am modificat si pentru intreruperi merge acum!..cu toate ca mie mi se pare ca nu numara bine...de 3 ori numara 10 sec, aproximativ...si a patra oara numara mai putin...nu inteleg de ce..Am stabilit cu profu sa prezint joia viitoare...asa ca mai am o sapt sa fac 3 motoare...si sa pun totul pe un breadboard..Multumesc pentru interesul aratat!! Link spre comentariu
Liviu M Postat Ianuarie 5, 2011 Partajează Postat Ianuarie 5, 2011 Vesti bune, ai timp sa inveti assembler. Cat despre atentie... vii cu proiecte interesante. Link spre comentariu
wolfei Postat Ianuarie 8, 2011 Autor Partajează Postat Ianuarie 8, 2011 Okay...dupa ce am pierdut vreo 2 zile cu asm asta...m-am decis ca nu am timp sa il invat acu...asa ca o sa fac tot in C...pentru inclinarea rafturilor in sus si in jos o sa pun un motor DC si o sa o sa il opresc prin actionarea a 2 butoane care vor genera intreruperi.Si mai raman cele 2 ventilatoare, deci BLDC, unu in comanda pwm si unu care sa functioneze tot timpul la o viteza mare.Ceva sfaturi? Link spre comentariu
gabygaby Postat Ianuarie 8, 2011 Partajează Postat Ianuarie 8, 2011 Daca vrei ceva facut de atii arunca o privire aici http://startcd.narod.ru/ Este in rusa. Sunt trei scheme de incubatoare printre altele. Link spre comentariu
wolfei Postat Ianuarie 8, 2011 Autor Partajează Postat Ianuarie 8, 2011 Daca vrei ceva facut de atii arunca o privire aici http://startcd.narod.ru/ Este in rusa. Sunt trei scheme de incubatoare printre altele.Ms de informatie, eu cam stiu de vreau sa fac...mai tr doar sa pun in practica.Azi am pus pe breadboard cei 2 senzori de temp, un led care sa simuleze rezistenta de nichelina si am transmis si la calc.Mai am doar de facut motoarele.Intrebare: ca sa fac motorul DC sa se invarta in 2 sensuri tr o punte H, nu?Inca astept ceva sfaturi sau exemple de cod daca are cineva>Multumesc in avans! Link spre comentariu
puiu Postat Ianuarie 9, 2011 Partajează Postat Ianuarie 9, 2011 1. Intradever iti trebuie o punte H.2. Sunt PIC-uri care au comanda pentru motor in H, cele care au ECCP. Trebuie doar sa pui tranzistorii pentru forta. Link spre comentariu
Liviu M Postat Ianuarie 9, 2011 Partajează Postat Ianuarie 9, 2011 Cati pini mai ai liberi/disponibili pentru motoare? Link spre comentariu
wolfei Postat Ianuarie 9, 2011 Autor Partajează Postat Ianuarie 9, 2011 Mai am 6 pini din D si din B vreo 4...mai este loc M-am uitat un pic pe net si vreau sa folosesc un L293D pentru comanda motorului DC care sa intoarca ouale.. Link spre comentariu
wolfei Postat Ianuarie 9, 2011 Autor Partajează Postat Ianuarie 9, 2011 Am mai lucrat azi la motorul DC. Am folosit L293D.Ideea e urmatoarea: cand am intreruperea de la TMR0 pornesc motorul intr-o directie-inainte sau inapoi in fct de un contor. Motorul merge pana se genereaza o intrerupere pentru inainte de la INTF si pentru mers inapoi de la RBIF. Cateva intrebari: -pun in functia interrupt isr verificarea pt toate cele 3 intreruperi(TMR0,INTF,RBIF) ? -principial am pus bine intreruperile in main?...pt ca nu reusesc sa pornesc intreruperea pe INTF, desi am setat RBIE=1 -am mai facut un proiect doar cu motorul,pic-ul si butoanele de intrerupere..pe INTF semnaleaza intreruperea, dar pe RBIF nu...deci cred ca imi scapa ceva -dpdv al delay-ului si a altor probleme care mai pot interveni e fiabila ideea mea>? Atasez ultima varianta a codului si schema in proteus. Astept opinii si sfaturi!Multumesc in avans! #include <pic.h>__CONFIG(HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGEN & UNPROTECT );#include "delay.h"#include "stdlib.h"#include "delay.c"void initializari(void) { GIE=1; // initializeaza intreruperi globale INTE = 1; //init intreruperi ext RBIE=1; //init intreruperi RB7-RB4 ADCS1 = 0; //select Fosc/8 ADCS0 = 1; ADCON1=0; // A/D port configuration 0 ADFM = 1; //right justified result ADON=1; // porneste conversia A/D T0IE=1; TMR0=0; //initiere TMR0 T0CS=0; //clock intern T0SE=0; //numarare pe front crescator PSA=0; //utilizare prescaler PS0=1; PS1=1; //prescaler de 256 PS2=1; }unsigned int read_adc(unsigned char channel){ channel&=0x07; // trunchiem canalul la 3 biti ADCON0&=0xC5; //eliberam canalul curent ADCON0|=(channel<<3); // aplicam noul canal selectat DelayMs(10); ADGO=1; //initiem conversia pe canalul selectat while(ADGO)continue; return(((ADRESH&0x03)<<8)+ADRESL); // returneaza rezultat pe 10 biti}float temp_usf(void){ int i; float temp_an, temp, temp1; temp_an=0; for(i=0; i<4; i++) { temp_an =temp_an+read_adc(0); DelayMs(5); } temp_an=temp_an/4; temp =temp_an*((5.0*100.0)/1023.0); temp1=temp*100; return(temp1);}float temp_umf(void){ int i; float temp_an, temp,temp2; // double ; temp_an=0; for(i=0; i<4; i++) { temp_an =temp_an+read_adc(1); DelayMs(5); } temp_an=temp_an/4; temp =temp_an*((5.0*100.0)/1023.0); temp2=(temp-273.15)*100;return(temp2);}void InitUSART() //rutina de setare si initializare a modulului USART{// SPBRG=64; //19200 baud la 20 MHz SPBRG=25; //9600 baud la 4 MHz BRGH=1; //high speed SYNC=0; //modul asincron SPEN=1; //activare port serial TXIE=0; //dezactivare intrerupere USART la transmisie TX9=0; //transmisie pe 8 biti TXEN=1; //activare transmisie RCIE=0; //dezactivare intrerupere USART la receptie RX9=0; //receptie pe 8 biti CREN=1; //activare receptie}void TransmitUSART(unsigned char c) //Rutina de transmitere a unui octet la portul serial{ while(!TXIF); //asteapta sa se termine transmisia precedenta TXREG=c; //incarca si transmite noua valoare}void TransmitUSARTC(const char* c){ int i =0; while(c[i]!=0x0 && c[i]!=0xd) { TransmitUSART(c[i]); i++; }// TransmitUSART(0xd);}unsigned char ReceiveUSART() //Rutina pt receptia unui octet de la portul serial{ unsigned char c; while(!RCIF); //asteapta pana se incheie receptia c=RCREG; //octetul receptionat este preluat din RCREG return c; }void afisare_usart(unsigned int i) { int zeci,unitati; zeci = i/10 + 48; unitati = i%10 + 48; while(!TXIF); TXREG = zeci; DelayMs(5); while(!TXIF); TXREG = unitati; }void afisfloat(long i){ int nr1, nr2;nr1=i/100;nr2=i%100; if (nr2>0) { afisare_usart(nr1); TransmitUSARTC(","); afisare_usart(nr2); TransmitUSART(0xd); DelayUs(250); } else { afisare_usart(nr1); TransmitUSART(0xd); DelayUs(250); } }volatile int intoarce,count;bit sInainte,sInapoi;void interrupt isr(void) //este apelata cand este generata o intrerupere{ 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; } 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 { RD4=1; //comanda de mers inainte RD5=0; if (sInainte) { RD4=0; //comanda de oprire RD5=0; } } else //daca dir par merge inapoi { RD4=0; //comanda de oprire RD5=1; if(sInapoi) { RD4=0; //comanda mers inapoi RD5=0; } } //DelayMs(1000); } DelayMs(1000); DelayMs(1000); DelayMs(1000); //delay ca sa mearga mai lent pe terminal afisarea } } http://img413.imageshack.us/i/sc1ub.jpg/ Link spre comentariu
Liviu M Postat Ianuarie 9, 2011 Partajează Postat Ianuarie 9, 2011 -pun in functia interrupt isr verificarea pt toate cele 3 intreruperi(TMR0,INTF,RBIF) ? Eu cred ca da. -principial am pus bine intreruperile in main?...pt ca nu reusesc sa pornesc intreruperea pe INTF, desi am setat RBIE=1 -am mai facut un proiect doar cu motorul,pic-ul si butoanele de intrerupere..pe INTF semnaleaza intreruperea, dar pe RBIF nu...deci cred ca imi scapa ceva INTF e legat de INTE - intrerupere pe RB0; RBIE activeaza intreruperile pe pinii RB4..RB7 - cu semnalizarea pe RBIF. Ai grija si la flancul (crescator/descrescator) semnalului care genereaza intreruperea pe RB0- OPTION_RED -> INTEDG) Sa nu uiti ca RB4..RB7 genereaza intrerupere la modificarea starii. Adica si intr-un sens si in celalalt. Pe de alta parte, ca sa scapi de conditia care a generat intreruperea a.i. sa functioneze in continuare (altfel conditia de intrerupere persista si intreruperea se genereaza din nou desi poate nu e cazul), trebuie sa Theuser, in the Interrupt Service Routine, can clear the interrupt in the following manner: a) Any read or write of PORTB. This will end the mismatch condition. b) Clear flag bit RBIF. A mismatch condition will continue to set flag bit RBIF. Reading PORTB will end the mismatch condition and allow flag bit RBIF to be cleared. -dpdv al delay-ului si a altor probleme care mai pot interveni e fiabila ideea mea>? Atasez ultima varianta a codului si schema in proteus. void interrupt isr(void) //este apelata cand este generata o intrerupere{ if(T0IF)//intreruperea este generata de timer0 ? {... T0IF=0;//am procesat intreruperea, resetam flag-ul pentru a se putea apela din nou }if(INTF) {... } INTF = 0;if(RBIF) {... } RBIF = 0;} Nu stiu daca de aici se trage, da' INTF=0 trebuie pus in blocul if(INTF), iar RBIF = 0 blocul if(RBIF); dupa cum am mai scris i mai sus, in blocul if(RBIF) trebuie sa mai pui si o citire a PORTB void interrupt isr(void) //este apelata cand este generata o intrerupere{ char cPortB; if(INTF) {... INTF = 0; } if(RBIF) {... cPortB = PORTB; RBIF = 0; }} Link spre comentariu
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum