Liviu M Postat Iulie 9, 2013 Partajează Postat Iulie 9, 2013 Se poate si cu else, se poate si fara. Numai ca bucata de cod postata e prea mica, trebuie vazut si restul (partea de functionare normala).Scrie-l cum ti se pare tie bine, testeaza si daca nu-ti merge cum vrei ne mai sfatuim. Link spre comentariu
Marian Postat Iulie 12, 2013 Autor Partajează Postat Iulie 12, 2013 Salutari. Revin proiectul despre care vorbeam in pagina anterioara, asa cum am spus sunt in lucru la o sursa simetrica de laborator pentru mine, dat fiind faptul ca am LCD 2x24 la dispozitie si un microcontroller destul de permisiv mi-am dorit ca sursa sa fie dotata cu un afisaj digital multiplu, voi avea Tensiune pe sarcina, Curentul de sarcina, Puterea livrata catre sarcina si temperatura radiatorului regulatoarelor de putere. Gama de masurare este 0-35Vcc, 0-6A si 0-100*C. Am dotat dispozitivul cu avertizari sonore si vizuale cu LED pentru atingerea pragurilor maxime de tensiune, respectiv curent, iar la atingerea unui prag presetat de temperatura pe radiator ( momentan 90*C dar valoarea finala va fi setata in urma testelor suplimentare pe sursa finalizata ) microcontroller-ul va decupla alimentarea trafului de putere prin intermediul unui BD139-16 ( terminatia 16 vine de la factor de amplificare mare ) si un releu cu bobina de 3V, totodata se va bloca rularea normala a programului dupa afisarea unui avertisment pe ecran, sursa nemaiputand fi folosita decat dupa resetarea uC de la intrerupatorul din pinul MCLR ( nu am prevazut debounce in soft ca nu stiu cum, sper sa nu fie necesar ca este nevoie doar de un impuls pentru o simpla resetare ). Asa cum probabil se subantelege, alimentarea partii digitale de control se face printr-un traf separat mai mic, vor fi de fapt 2 alimentari Vca separate galvanic intre ele, se va vedea in schema motivul, e un compromis usor de rezolvat ( pentru mine ) necesar datorita lipsei unui senzor de temperatura, pentru asta ma voi folosi de un BD139 in configuratie dioda ( baza legata la colector ) care va fi fixat pe radiator si alimentat de un generator de curent constant ( undeva pe la 13mA ), Vbe variaza in functie de temperatura carcasei si testele au relevat o variatie destul de liniara deci sunt multumit, el va comanda un AO inversor cu amplificare reglabila si referinta ajustabila la neinversoare, care AO va asigura variatia 0-5V necesara uC pentru variatia Vbe in functie de temperatura, am testat-o practic azi si sunt satisfacut de rezultate, calibrarea se poate face destul de usor ajustand amplificarea si eventual referinta, toata ideea partii de temperatura ii apartine lui @Smilex ( de fapt si partea de curent tot a lui este ) caruia ii multumesc mult si pe aceasta cale. Aceasta este schema: http://img713.imageshack.us/img713/2369/h2p.png Am modificat conexiunile la LCD in beneficiul proiectarii cablajului, tot in acest scop am ales si pinii unde se vor conecta ledurile, buzzer-ul si BD-ul pentru releu, si nu in ultimul rand si pinii unde se fac citirile V, A, si respectiv T, tot in beneficiul cablajului deoarece am ales dinainte o pozitionare pe placa pentru fiecare bloc din schema. Pentru protejarea intrarilor uC voi folosi zennere, am testat niste BZX si-si fac treaba foarte bine, fara a influenta masuratoarea/afisajul. Codul sursa pe care tocmai ce l-am scris si testat in proteus cu succes ar fi asta: /* Descriere: * Afisaj Digital Multiplu pentru Sursa de Laborator. * Afisare Tensiune 0-35Vcc; Curent 0-6A; Temperatura 0-100*C si Putere. * Protectii: * Avertizare sonora prin Buzzer si vizuala prin LED, la atingerea pragurilor limita Tensiune sau Curent. * Blocare sursa prin decuplarea alimentarii trafului principal de catre un releu, si afisare avertisment pe ecran la atingerea unui prag ales de temperatura. * Configuratie: * Microcontroller PIC16F876 * Oscilator XT 4.000 Mhz * LCD Alfanumeric 2x24 caractere * Autor: Marian. * Iul-2013*///Conexiuni LCDsbit LCD_RS at RB7_bit;sbit LCD_EN at RB6_bit;sbit LCD_D4 at RB5_bit;sbit LCD_D5 at RB4_bit;sbit LCD_D6 at RB3_bit;sbit LCD_D7 at RB2_bit;sbit LCD_RS_Direction at TRISB7_bit;sbit LCD_EN_Direction at TRISB6_bit;sbit LCD_D4_Direction at TRISB5_bit;sbit LCD_D5_Direction at TRISB4_bit;sbit LCD_D6_Direction at TRISB3_bit;sbit LCD_D7_Direction at TRISB2_bit;//Declarare variabileunsigned char ch, ADCx;unsigned int Tensiune, Curent, Temp, ProtU, ProtI, ProtT;unsigned long V, A, Pw, T;//Functie principalavoid main() { INTCON = 0; // Dezactivare intreruperi TRISA = 0x07; // RA0, RA1 si RA2 setate ca intrari TRISC = 0; // Portul C setat ca iesire PORTC = 0; // Resetare port C Lcd_Init(); // Initializare LCD Lcd_Cmd(_LCD_CURSOR_OFF); // Dezactivare cursor Lcd_Cmd(_LCD_CLEAR); // Stergere Ecran Delay_ms(1000); // Delay 1 secunda Lcd_Out(1,1,"SursaSimetricaLaborator"); // Mesaj initial 1, prima linie Lcd_Out(2,1,"Afisaj Digital Multiplu"); // Mesaj initial 1 linia 2 Delay_ms(3000); Lcd_Cmd(_LCD_CLEAR); // Stergere ecran Lcd_Out(1,4,"0-35V; 0-6A; 0-100C"); // Mesaj initial 2, prima linie Lcd_Out(2,8,"<By Marian>"); // Mesaj initial 2, linia 2 Delay_ms(3000); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,1,"U:"); // Afiseaza caracter "U" in prima linie, coloana 1 Lcd_Out(1,10,"T:"); // Afiseaza caracter "T", prima linie, coloana 10 Lcd_Out(1,19,"C"); // Afiseaza caracter "C", linia 1, coloana 19 Lcd_Out(2,1,"I:"); // Afiseaza caracter "I", linia 2, coloana 1 Lcd_Out(2,10,"P:"); // Afiseaza caracter "P", linia 2, coloana 10 while (1) { //Achizitie ADC Tensiune = 0; Curent = 0; Temp = 0; for (ADCx=0; ADCx<10; ADCx++) { Tensiune += ADC_Read(2); // Achizitie ADC pentru tensiune Curent += ADC_Read(1); // Achizitie ADC pentru curent Temp += ADC_Read(0); // Achizitie ADC pentru temperatura Delay_ms(10); } //Tensiune Tensiune = Tensiune/ADCx; // Alocare valoare tensiune V = (long)Tensiune*3500; // Converteste rezultat in milivolti V = V/1023; // 0...1023 => 0...3500mV ch = V/1000; // Extrage zeci 10.00 Lcd_Chr(1,3,48+ch); // Afisare rezultat in format ASCII ch = (V/100) % 10; // Extrage unitati 01.00 Lcd_Chr_CP(48+ch); // Afiseaza rezultat in format ASCII Lcd_Chr_CP('.'); // Afiseaza caracter '.' ch = (V/10) % 10; // Extrage sutimi 00.10 Lcd_Chr_CP(48+ch); ch = V % 10; // Extrage zecimi 00.01 Lcd_Chr_CP(48+ch); LCD_Chr_CP('V'); // Afiseaza caracter 'V' Delay_ms(10); //Curent Curent = Curent/ADCx; // Alocare valoare curent A = (long)Curent*600; // Convertire rezultat in milivolti A = A/1023; // 0..1023 => 0-600mV ch = A/1000; // Extragere zeci Lcd_Chr(2,3,48+ch); // Scrie rezultatul in format ASCII ch = (A/100) % 10; // Extragere unitati Lcd_Chr_CP(48+ch); // Scrie rezultatul in format ASCII Lcd_Chr_CP('.'); ch = (A/10) %10; // Extragere sutimi Lcd_Chr_CP(48+ch); // Scrie rezultatul in format ASCII ch = A % 10; // Extragere zecimi Lcd_Chr_CP(48+ch); Lcd_Chr_CP('A'); // Afisare caracter 'A' la final Delay_ms(10); //Temperatura Temp = Temp/ADCx; // Alocare valoare temperatura T = (long)Temp*1000; // Converteste rezultat in milivolti T = T/1023; // 0...1023 => 0...1000mV ch = T/1000; // Extrage sute 100.00 Lcd_Chr(1,12,48+ch); ch = (T/100) % 10; // Extrage zeci 010.00 Lcd_Chr_CP(48+ch); ch = (T/10) % 10; // Extrage unitati 001.00 Lcd_Chr_CP(48+ch); Lcd_Chr_CP('.'); ch = (T/1) % 10; // Extrage sutimi 000.10 Lcd_Chr_CP(48+ch); ch = T % 10; // Extrage zecimi 000.01 Lcd_Chr_CP(48+ch); Lcd_Chr_CP(223); // Afisare caracter "Grad" Delay_ms(10); //Putere Pw = V*A/1000; // Seteaza valoare Putere ch = Pw/1000; // Extrage sute Lcd_Chr(2,12,48+ch); ch = (Pw/100) % 10; // Extrage zeci Lcd_Chr_CP(48+ch); ch = (Pw/10) %10; // Extrage unitati Lcd_Chr_CP(48+ch); Lcd_Chr_CP('.'); ch = (Pw/1) % 10; // Extrage sutimi Lcd_Chr_CP(48+ch); ch = Pw % 10; // Extrage zecimi Lcd_Chr_CP(48+ch); Lcd_Chr_CP('W'); // Afiseaza "W" la sfarsit Delay_ms(10); //Protectii ProtU = ADC_Read(2); // Achizitie ADC pentru protectie Tensiune if (ProtU == 1023) { PORTC.F4 = 1; // Aprinde LED daca tensiunea este 35V Sound_Init(&PORTC, 3); // Initializare buzzer, Sound_Play(500, 1000); // si activare avertisment 500Hz, 1 secunda } else { PORTC.F4 = 0; // Resetare RC4 } ProtI = ADC_Read(1); // Ahizitie ADC pentru protectie Curent if (ProtI == 1023) { PORTC.F5 = 1; // Aprinde LED daca curentul este 6A Sound_Init(&PORTC, 3); // Initializare buzzer, Sound_Play(600, 500); // si activare avertisment 600Hz, 0,5 secunde } else { PORTC.F5 = 0; // Resetare RC5 } ProtT = ADC_Read(0); // Achizitie ADC pentru protectie temperatura if (ProtT > 920) { PORTC.F2 = 1; // Activeaza releu daca temperatura este 90*C Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,8,"PROTECTIE!"); // Afiseaza avertisment pe ecran Lcd_Out(2,5,"SUPRATEMPERATURA"); break; // Blocheaza rularea programului } else { PORTC.F2 = 0; // Resetare RC2 } }}Si aici link cu simularea: In principiu sunt multumit de rezultate, codul isi face treaba bine ( cel putin in simulator ), ramane sa-l testez si practic cand timpul o va permite, configuratia mi se pare ok deci per ansamblu un dispozitiv util zic eu. Orice comentarii sunt binevenite. Toate cele bune. Marian. Link spre comentariu
Liviu M Postat Iulie 12, 2013 Partajează Postat Iulie 12, 2013 break; // Blocheaza rularea programului Atentie, break nu are in cazul de fata nici o influenta.break se foloseste pentru intreruperea prematura a unei bucle. Cu alte cuvinte, in loc sa scriifor(i=0; i<10; i++){ if(n>5) //o conditie ipotetica in cazul careia ar trebui sa intrerupi bucla { i=10; //fortezi terminarea buclei } else //fara else programul continua cu ce e dupa blocul if pana se termina blocul for, dupa care retesteaza i { // ce aveai de facut in bucla }}poti scriefor(i=0; i<10; i++){ if(n>5) { break; //iese imediat din for, nu mai executa nimic din bucla, asa ca nu mai e nevoie de else } // ce aveai de facut in bucla}[/code]Acum sincer n-am idee daca si ce influenta ar putea avea break ala asupra buclei "mari" (while(1)). PS Pana la urma ai lasat protectia in forma originala, n-ai "comasat-o" cu masuratorile. Link spre comentariu
Marian Postat Iulie 12, 2013 Autor Partajează Postat Iulie 12, 2013 Pai break am observat ca opreste rularea normala, in sensul ca blocheaza softul in acea pozitie, este adevarat ca else de dupa este inutil si abea acum mi-am dat seama si va fi scos, dar fara break gandesc ca s-ar reveni la inceputul buclei, sau ma insel? o sa simulez si fara el sa vad ce se intampla ca eu doresc ca la detectarea acelui prag softul sa "inghete" in acel loc dupa comenzile alea, si momentan vad ca asta face...PS: Da, am lasat protectiile asa atat pentru ca spatiul total ocupat este oricum sub 50% cat si pentru ca nu am nici pe departe experienta ta, nu inteleg la fel de bine ca tine fineturile asa ca am preferat sa merg pe ceea ce inteleg...LE: am testat acuma si fara break, nu merge, ecranul arata ba acel avertisment ba masuratorile aternant si rapid, deci "break" ramane. Link spre comentariu
Liviu M Postat Iulie 12, 2013 Partajează Postat Iulie 12, 2013 break nu trebuie sa ramana asa. Nu stiu cum e cu simulatorul, da' ma astept ca in montajul fizic sa ai tot felul de efecte ciudate. Chiar si in simulator, faptul ca ti se blocheaza softul inseamna ca dupa un scurt trebuie sa resetezi scula. Daca asta e OK pentru tine, atunci lasa-l asa, da' eu ma gandeam ca programul trebuie sa ramana intr-o bucla in care sa aprinda led-uri si sa scrie mesaje de avertizare cat timp sunt probleme, urmand ca atunci cand ai inlaturat problema sa functioneze mai departe. //Protectii ProtU = ADC_Read(2); // Achizitie ADC pentru protectie Tensiune if (ProtU == 1023) { PORTC.F4 = 1; // Aprinde LED daca tensiunea este 35V Sound_Init(&PORTC, 3); // Initializare buzzer, Sound_Play(500, 1000); // si activare avertisment 500Hz, 1 secunda do { // asteapta pana se remediaza problema } while (ProtU == 1023); PORTC.F4 = 0; // Resetare RC4 } Link spre comentariu
Marian Postat Iulie 12, 2013 Autor Partajează Postat Iulie 12, 2013 LE: Am incercat cu do-while dar nu functioneaza asa cum mi-as dori, asa cum am zis eu vreau ca softul sa se blocheze unde pusesem acel break si in configuratia ce am postat-o exact asta face, ramane sa testez practic ca sa ma lamuresc daca e bine sau nu.PS: Protectia de curent sau tensiune nu influenteaza bucla unde se afla acel break, sunt separate, cand 1 din cele 2 intervin apar si avertizarile sonore si se aprind ledurile, dar functionarea programului nu este afectata, doar la detectarea pragului de temperatura intervine afisarea avertismentului pe ecran si blocarea rularii programului si vad ca exact asta face... Link spre comentariu
Liviu M Postat Iulie 12, 2013 Partajează Postat Iulie 12, 2013 Codul postat anterior era pe post de exemplu.Bineinteles ca daca-ti trebuie doar la temperatura il folosesti doar acolo.Ma rog, pana la urma fa programul cum iti functioneaza mai bine. Daca merge asa cum zici, foarte bine, foloseste-l asa. Numai ca daca se va comporta ciudat sa stii ca se pot trage si de la break-ul ala. Link spre comentariu
Marian Postat Iulie 12, 2013 Autor Partajează Postat Iulie 12, 2013 Ai avut dreptate ( mi se pare normal pana la urma ), break-ul nu avea ce sa caute acolo, am testat acum montajul si practic pe breadboard si cu "break" ecranul nici macar nu se initializa ( habar n-am de ce ), prin teste am ajuns la rezolvarea asta care vad ca face fix ce doresc eu: ProtT = ADC_Read(0); // Achizitie ADC pentru protectie temperatura if (ProtT > 920) { PORTC.F2 = 1; // Activeaza releu daca temperatura este mai mare de 90*C Lcd_Cmd(_LCD_CLEAR); // Sterge ecran Lcd_Out(1,8,"PROTECTIE!"); // Afisare mesaj avertisment, Lcd_Out(2,5,"SUPRATEMPERATURA"); // "protectie supratemperatura" do { } // Endless loop while (1); } else { PORTC.F2 = 0; } Am ceva dubii in privinta acelui 'else' dar nu cred ca mai modific ceva, nu de alta dar am tot sters si rescris uC-ul si nu vreau sa am surprize neplacute ca la 12F675, ar fi pur si simplu o tragedie sa pierd uC-ul asta, altul n-am de unde... Si un scurt filmulet cu testul ( scuze pentru calitatea foarte slaba dar este facut cu mobilul ), am micsorat putin pragurile de avertizare la tensiune la 34V si curent 5,8A. PS: Multumesc pentru observatii, fara interventia ta n-as fi corectat codul. Link spre comentariu
Liviu M Postat Iulie 12, 2013 Partajează Postat Iulie 12, 2013 Cu placere si felicitari pentru realizare! La mai multe (si la mai multi care sa-ti urmeze exemplul)! Link spre comentariu
Marian Postat Iulie 13, 2013 Autor Partajează Postat Iulie 13, 2013 Multumesc, si multumesc si pentru apreciere dar mai e tare mult pana sa pot afirma ca stiu sa scriu coduri... momentan nu pot spune decat ca am inteles, cu ajutorul tau evident, unele chestii elementare.Acum urmeaza sa proiectez un cablaj pe masura, si nu ma grabesc, vreau sa iasa ceva frumos si cat mai compact, cand va fi gata il voi atasa aici dimpreuna cu toate fisierele necesare oricui ar mai fi interesat. Link spre comentariu
Marian Postat Iulie 14, 2013 Autor Partajează Postat Iulie 14, 2013 Revin si cu cablajul pe care tocmai l-am finalizat, zilele urmatoare il voi verifica din nou pentru a fi sigur ca nu sunt greseli apoi urmeaza realizarea sa si dupa finalizarea proiectului voi posta totul la "Proiectul meu"/ Toate cele bune. Link spre comentariu
GeoMar Postat Iulie 14, 2013 Partajează Postat Iulie 14, 2013 Frumos pana aici, felicitarile mele, atat pentru soft, cat si pentru cablaj. Am reusit si eu adaptarea/modificarea softului pentru 16F877A.Urmeaza, in functie de timpul liber si terminarea unor proiecte deja demarate, realizarea/testarea LIVE, eventual ceva mici modificari soft/hardware, adaptate cerintelor/necesitatilor mele.Multumesc pentru soft. Link spre comentariu
Marian Postat Iulie 14, 2013 Autor Partajează Postat Iulie 14, 2013 Multumesc si eu pentru aprecieri, conteaza mult pentru mine.Saptamana asta o sa am si restul componentelor necesare pentru realizarea proiectului meu de sursa ( afisajul fiind evident doar o parte componenta a intregului ), problema o sa fie la realizarea practica a placilor, nu am ce-mi trebuie pentru motoda foto, iar la transfer ar trebui finisaje destul de pretentioase avand in vedere metoda de care ma folosesc, deci ramane de vazut ce fac si cum le fac... Link spre comentariu
GeoMar Postat Iulie 14, 2013 Partajează Postat Iulie 14, 2013 ... problema o sa fie la realizarea practica a placilor, nu am ce-mi trebuie pentru motoda foto, iar la transfer ar trebui finisaje destul de pretentioase avand in vedere metoda de care ma folosesc, deci ramane de vazut ce fac si cum le fac...Sincer, metoda foto este pretentioasa, dar si cea mai buna in regim DIY, se pot realiza cablaje aproximativ calitativ ca cele foto si cu transfer de toner.Momentan nu mai am solutiile necesare, te ajutam cu realizarea cablajelor. :jytuiyuDar pana sosesc componentele tale, poate procur si cele necesare pentru cablaje (nu promit) si incerc sa te ajut. Link spre comentariu
Marian Postat Iulie 15, 2013 Autor Partajează Postat Iulie 15, 2013 Revin cu cateva mici rectificari sugerate de @Smilex cu scopul de a renunta la unele strapuri ( erau cam multe ce-i drept ): Acum cred ca este ok si cel mai probabil asa va ramane. PS: Multumesc @GeoMar pentru oferta. 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