Liviu M Postat Septembrie 3, 2013 Partajează Postat Septembrie 3, 2013 Pune 2 de = if (PORTD.F1=0) {Adicaif (PORTD.F1==0) {. Cu unul singur, intai ii dai lui F1 valoarea 0 si dupa aia evalueaza if-ul. O metoda sa nu-ti mai scape e sa faci testul invers if (0==PORTD.F1) {, pentru ca daca uiti un = nu se compileaza. Expresiaif (0=PORTD.F1) { da eroare de compilare. Link spre comentariu
Marian Postat Septembrie 3, 2013 Autor Partajează Postat Septembrie 3, 2013 Pff ce bleg am fost, mi-e rusine cand ma gandesc ca m-am impotmolit la ceva atat de banal... Multumesc mult, intr-adevar asta era baiul, am mutat portul de semnalizare a prezentei retelei pe RA4, am observat ca si acesta are pe intrare un schmith trigger deci ar merge, si intr-adevar proteuz zice ca ar fi ok, si astfel las celelalte porturi pentru ce mai este nevoie. Link spre comentariu
Marian Postat Septembrie 3, 2013 Autor Partajează Postat Septembrie 3, 2013 Nu mai pot edita anterior asa ca postez in continuare si cer scuze pentru dublu post... Am zis eu ca rezolv problema buclei if de unul singur dar nu sunt in stare din cate vad... //Declarare variabileunsigned char ch, ADCx;unsigned int VcaMed, VcaRms, VccBAT, AccBAT, VccSMPS;unsigned long VR, VB, AB, VS;void main() { INTCON = 0; TRISA = 0xFF; Lcd_Init(); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR); Delay_ms(1000); Lcd_Out(1,4,"Afisaj UPS"); Lcd_Out(2,6,"Marian"); Delay_ms(3000); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,1,"B"); Lcd_Out(2,1,"B"); while (1) { //Achizitie ADC VcaMed = 0; VccBAT = 0; AccBAT = 0; VccSMPS = 0; for (ADCx=0; ADCx<36; ADCx++) { VcaMed += ADC_Read(0); VccSMPS += ADC_Read(1); VccBAT += ADC_Read(2); AccBAT += ADC_Read(3); Delay_ms(1); } if (PORTA.F4 == 0) { Lcd_Out(1,9,"RETEA"); //Retea VcaMed = VcaMed/ADCx; VcaRms = VcaMed*1.4142; VR = (long)VcaRms*2600; VR = VR/1023; ch = VR/1000; Lcd_Chr(2,9,48+ch); ch = (VR/100) % 10; Lcd_Chr_CP(48+ch); ch = (VR/10) % 10; Lcd_Chr_CP(48+ch); LCD_Chr_CP('V'); Delay_ms(10); } else { Lcd_Out(1,9,"SMPS "); //Convertor VccSMPS = VccSMPS/ADCx; VS = (long)VccSMPS*3500; VS = VS/1023; ch = VS/1000; Lcd_Chr(2,9,48+ch); ch = (VS/100) % 10; Lcd_Chr_CP(48+ch); ch = (VS/10) % 10; Lcd_Chr_CP(48+ch); LCD_Chr_CP('V'); Delay_ms(10); } Teoretic din punctul meu de vedere ideea ar fi simpla, la 0 pe pinul RA4 se executa doar partea de cod din if citindu-se si afisandu-se tensiunea retelei, in timp ce la 1 pe pinul RA4, se ignora partea de cod de la if si se executa doar cea de la else, deci citirea tensiunii de pe AN1 si afisarea in consecinta, asta teoretic, penca practic nu este asa... n-am mai testat practic ci doar in proteus, si dupa mesajul initial uC-ul se reseteaza singur, habar n-am de ce... si mai derutant este faptul ca ambele citiri sunt scrise corect, adica daca comentez pe oricare din ele atunci cealalta merge ok... ceva tot eu gresesc asta e clar, dar ce anume? Link spre comentariu
Liviu M Postat Septembrie 3, 2013 Partajează Postat Septembrie 3, 2013 Eu nu vad nimic gresit acolo.Cel mult cam multe socoteli cu numere mari (multa memorie).Incearca sa comentezi din ele (comentezi si din if si din else) pana cand merge (daca merrge).Daca incepe sa mearga, il ajuti cat poti la calcule (calculezi tu cat e 2600/1023 si foloisesti rezultatul la VR). Link spre comentariu
Mircea Postat Septembrie 3, 2013 Partajează Postat Septembrie 3, 2013 ...Cel mult cam multe socoteli cu numere mari (multa memorie)... (calculezi tu cat e 2600/1023 si folosesti rezultatul la VR). Mariane, esti cam rasfatat de lucrezi numai cu PIC-uri cu memorie multa. Ia sa te vad cum era sa ai un pricajit de PIC cu 1024 program si 64 ram si sa te zbati sa-l faci sa mearga . Link spre comentariu
Mircea Postat Septembrie 4, 2013 Partajează Postat Septembrie 4, 2013 Marian, la mine merge sqrt(x). Apoi si sqrt(2) * sqrt(3). Interesant este ca este limitat la 5 decimale (trunchiere fara rotunjire - eu as fi vrut sa fie un gen de round up, dar nu este), nu scria in help. Uite aici: Si codul care ocupa 80% din 4kB de ROM. Un exemplu de ce sa nu folosesti FloattoStr . Un singur FloattoStr si gata 35% din ROM. ' * Test configuration:' MCU: PIC16F690' Oscillator: INTOSC 2 MHz' Ext. Modules: -' *program LCD' Declarations sectiondim x,y,res as floatdim txtX as char[16] txtY as char[16] txtZ as char[16]' Lcd module connectionsdim LCD_RS as sbit at RA0_bit LCD_EN as sbit at RA1_bit LCD_D4 as sbit at RB4_bit LCD_D5 as sbit at RB5_bit LCD_D6 as sbit at RB6_bit LCD_D7 as sbit at RB7_bit LCD_RS_Direction as sbit at TRISA0_bit LCD_EN_Direction as sbit at TRISA1_bit LCD_D4_Direction as sbit at TRISB4_bit LCD_D5_Direction as sbit at TRISB5_bit LCD_D6_Direction as sbit at TRISB6_bit LCD_D7_Direction as sbit at TRISB7_bit' End Lcd module connections' Set-up the PICsub procedure InitMain() OPTION_REG = 0x80 ' Pull-up disabled PORTB INTCON = 0x00 ' No INT OSCCON = 0x56 ' 2MHz clock CM1CON0 = 0x00 ' No COMP C1 CM2CON0 = 0x00 ' No COMP C2 CM2CON1 = 0x00 ' No COMP C2 SRCON = 0x00 ' No SR latch ANSEL = 0x00 ' No AN I/Os ANSELH = 0x00 ' No AN I/Os TRISA = 0x3C ' A2-A5 inputs, A0-A1 outputs WPUA = 0x00 ' Pull-up disabled IOCA = 0x00 ' IOC disabled TRISB = 0x00 ' All outputs WPUB = 0x00 ' Pull-up disabled IOCB = 0x00 ' IOC disabled TRISC = 0x00 ' All outputs PORTA = 0x00 ' Clear PORTA PORTB = 0x00 ' Clear PORTB PORTC = 0x00 ' Clear PORTCend sub' Main programMain: InitMain() Lcd_Init() ' Initialize Lcd Lcd_Cmd(_LCD_CLEAR) ' Clear display Lcd_Cmd(_LCD_CURSOR_OFF) ' Cursor offLCD: Lcd_Out(1,1,"Test functie SQRT pt") Lcd_Out(2,1,"Marian @ Elforum ") Delay_ms(3000) Lcd_Cmd(_LCD_CLEAR) ' Clear display x = sqrt(2) y = sqrt(3) FloatToStr(x, txtX) FloatToStr(y, txtY) Lcd_Out(1,1,"sqrt(2)=") Lcd_Out(1,9,txtX) Lcd_Out(2,1,"sqrt(3)=") Lcd_Out(2,9,txtY) Delay_ms(3000) Lcd_Cmd(_LCD_CLEAR) ' Clear display res = sqrt(2) * sqrt(3) FloatToStr(res, txtZ) Lcd_Out(1,1,"res=sqrt(2)*sqrt(3)") Lcd_Out(2,1,"res=") Lcd_Out(2,5,txtZ) Delay_ms(3000) Lcd_Cmd(_LCD_CLEAR) ' Clear display goto LCD end. Link spre comentariu
Marian Postat Septembrie 4, 2013 Autor Partajează Postat Septembrie 4, 2013 Mda, am gasit problema, mergand pe ideea lui@Liviu M cum ca s-ar ocupa prea multa memorie m-am uitat la ce spune compilatorul dupa built, si am observat ca se trece putin de 2000 de cuvinte si mi-am amintit de limitarea compilatorului in versiune free la maxim 2000, credeam ca am reusit sa-l cracuiesc ca nu-mi da eroare la compilare dar nici programul nu merge, mai aveam cateva functii adaugate si am comentat una din ele ca sa raman sub 2000 si intr-adevar nu e nimic gresit acolo, bucla if/else functioneaza asa cum trebuie si cum am dorit eu, probabil ca tot compilatorul este si motivul pentru care sqrt nu merge la mine, dar asta n-ar fi o problema, merge inmultit direct cu cifra de interes. Codul integral arata momentan cam asa ( destul de simplu, stiu ): //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 VcaMed, VcaRms, VccBAT, AccBAT, VccSMPS;unsigned long VR, VB, AB, VS;void main() { INTCON = 0; TRISA = 0xFF; Lcd_Init(); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR); Delay_ms(1000); Lcd_Out(1,4,"Afisaj UPS"); Lcd_Out(2,6,"Marian"); Delay_ms(3000); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,1,"B"); Lcd_Out(2,1,"B"); while (1) { //Achizitie ADC VcaMed = 0; VccBAT = 0; AccBAT = 0; VccSMPS = 0; for (ADCx=0; ADCx<36; ADCx++) { VcaMed += ADC_Read(0); VccSMPS += ADC_Read(1); VccBAT += ADC_Read(2); AccBAT += ADC_Read(3); Delay_ms(1); } if (PORTA.F4 == 0) { Lcd_Out(1,9,"RETEA"); //Retea VcaMed = VcaMed/ADCx; VcaRms = VcaMed*1.4142; VR = (long)VcaRms*2600; VR = VR/1023; ch = VR/1000; Lcd_Chr(2,9,48+ch); ch = (VR/100) % 10; Lcd_Chr_CP(48+ch); ch = (VR/10) % 10; Lcd_Chr_CP(48+ch); LCD_Chr_CP('V'); Delay_ms(10); } else { Lcd_Out(1,9,"SMPS "); //Convertor VccSMPS = VccSMPS/ADCx; VS = (long)VccSMPS*3500; VS = VS/1023; ch = VS/1000; Lcd_Chr(2,9,48+ch); ch = (VS/100) % 10; Lcd_Chr_CP(48+ch); ch = (VS/10) % 10; Lcd_Chr_CP(48+ch); LCD_Chr_CP('V'); Delay_ms(10); } //Acumulator-Tensiune VccBAT = VccBAT/ADCx; VB = (long)VccBAT*2000; VB = VB/1023; ch = VB/1000; Lcd_Chr(1,2,48+ch); ch = (VB/100) % 10; Lcd_Chr_CP(48+ch); Lcd_Chr_CP('.'); ch = (VB/10) % 10; Lcd_Chr_CP(48+ch); ch = VB % 10; Lcd_Chr_CP(48+ch); LCD_Chr_CP('V'); Delay_ms(10); //Acumulator-Curent de incarcare AccBAT = AccBAT/ADCx; AB = (long)AccBAT*500; AB = AB/1023; ch = AB/1000; Lcd_Chr(2,2,48+ch); ch = (AB/100) % 10; Lcd_Chr_CP(48+ch); Lcd_Chr_CP('.'); ch = (AB/10) % 10; Lcd_Chr_CP(48+ch); ch = AB % 10; Lcd_Chr_CP(48+ch); LCD_Chr_CP('A'); Delay_ms(10); } } Am in afara de citirea si afisarea tensiunii la retea si respectiv convertor din acea bucla, tensiunea de pe acumulator si curentul de incarcare al acestuia, ar mai trebui sa mai adaug cateva chestii minore prin bucla aia if/else si cred ca ar cam fi gata, cum este acum vad ca mi-ar zice compilatorul ca se foloseste 21% din RAM si 26% din ROM ( PIC16F877A ), acuma tre sa vad cum fac cu amaratu asta de compilator ca l-am mai cracuit eu in trecut... PS: @thunderer stiu ca uC-ul asta face totul simplu, de asta l-am si ales, ca nu am experienta voastra in optimizarea de coduri si am zis deci sa nu imi bat capul cu limitari, daca tot il am, atunci de ce sa nu-l folosesc... pe parcurs va veni si experienta si atunci inevitabil si optimizari, programe mai scurte, mai compacte... etc... sper Link spre comentariu
Liviu M Postat Septembrie 4, 2013 Partajează Postat Septembrie 4, 2013 Cred ca te-ar ajuta daca definesti o functie de afisare care sa afiseze valorile citite, functie pe care s-o folosesti in locul a 4 blocuri de afisare. Programul ar arata cam asa (am pastrat din programul tau numai partile care-mi trebuiau pentru exemplificare, trebuie sa "adaptezi" tot programul). //Declarare variabileunsigned char ch, ADCx;unsigned int VcaMed, VcaRms, VccBAT, AccBAT, VccSMPS;unsigned long VR, VB, AB, VS;void afisareDate(int , unsigned char , unsigned char , unsigned char ); //declari functiavoid main() {... if (PORTA.F4 == 0) { Lcd_Out(1,9,"RETEA"); //Retea VcaMed = VcaMed/ADCx; VcaRms = VcaMed*1.4142; VR = (long)VcaRms*2600; VR = VR/1023; afisareDate(VR, 'V', 2, 9); //folosesti functia }...}//--------------------------------------------------------------------// Functie pentru afisarea unei valori (cu unitatile de masura aferenter) la coordonate date//--------------------------------------void afisareDate(int valoare, unsigned char unitateMasura, unsigned char linie, unsigned char coloana) { unsigned char ch; ch = valoare/1000; Lcd_Chr(linie,coloana,ch + '0'); ch = (valoare/100) % 10; Lcd_Chr_CP(ch + '0'); ch = (valoare/10) % 10; Lcd_Chr_CP(ch + '0'); ch = valoare % 10; Lcd_Chr_CP(ch + '0'); LCD_Chr_CP(unitateMasura); Delay_ms(10); } Link spre comentariu
Marian Postat Septembrie 4, 2013 Autor Partajează Postat Septembrie 4, 2013 Interesanta chestie, si-mi amintesc ca am citit undeva de asta, dar daca am inteles eu bine este valabil atunci cand ai 2 sau mai multe blocuri de cod identice care se repeta, in situatia asta se declara o noua functie si doar se apeleaza in locul necesar fara a mai fi necesar rescrierea acelui cod integral, insa din cele 4 blocuri la mine 3 sunt usor diferite unul de altul deci nu cred ca merge... adica de exemplu afisarea tensiunii pentru retea se face in urma calcularii valorii rms din media extrasa a semnalului de pe intrare, in timp ce afisarea tensiunii de la iesirea convertorului se face prin achizitie simpla fara acel Rms devreme ce este vorba despre tensiune continua; ambele afiseaza pe lcd valoarea exprimata in 3 numere intregi fara zecimale ( n-am ce face cu zecimalele aici ), in timp ce afisarea tensiunii de pe acumulator si a curentului de incarcare al acestuia se face cu 2 numere intregi si 2 zecimale, aici zecimalele sunt importante in ambele cazuri. Deci avand in vedere diferentele astea, se mai poate declara o functie universala pentru toate 4 blocurile? Link spre comentariu
Liviu M Postat Septembrie 4, 2013 Partajează Postat Septembrie 4, 2013 Eu am bagat in functie doar afisarea. Calculele le faci ca pana acum. In exemplul pe care l-am pus anterior, VR e calculat ca inainte, valoarea obtinuta fiind folosita de functia de afisare ca parametru.Singura modificare pe care am facut-o - la tensiuni tu nu afisezi unitatile. Functia mea afiseaza toate cifrele. Daca vrei chiar ca la tine se complica putin functia, da' tot cred ca merita. Link spre comentariu
Marian Postat Septembrie 4, 2013 Autor Partajează Postat Septembrie 4, 2013 Pai nu e vorba de ce vreau eu, la tensiunile mari am nevoie doar de sute, zeci si unitati, adica fara zecimale ( adica numere intregi, fara zecimale sau cum le mai zice ), la cat de mult variaza reteaua zecimalele ar fi intr-o modificare foarte rapida si constanta, apoi nu cred ca am spatiu si pentru zecimale... in schimb la tensiunea si curentul de incarcare pe acumulator chiar este nevoie de zecimale... Link spre comentariu
Liviu M Postat Septembrie 4, 2013 Partajează Postat Septembrie 4, 2013 Acum ar trebui sa afiseze ca la tine. ----------------------------------------------------------------// Functie pentru afisarea unei valori (cu unitatile de masura aferenter) la coordonate date//--------------------------------------void afisareDate(int valoare, unsigned char unitateMasura, unsigned char linie, unsigned char coloana) { unsigned char ch; ch = valoare/1000; Lcd_Chr(linie,coloana,ch + '0'); ch = (valoare/100) % 10; Lcd_Chr_CP(ch + '0'); ch = (valoare/10) % 10; Lcd_Chr_CP(ch + '0'); if(unitateMasura == 'A') { ch = valoare % 10; Lcd_Chr_CP(ch + '0'); } LCD_Chr_CP(unitateMasura); Delay_ms(10); } Link spre comentariu
Marian Postat Septembrie 6, 2013 Autor Partajează Postat Septembrie 6, 2013 Revin cu codul finalizat si testat cu succes atat in proteus cat si practic, sunt multumit de rezultat astfel incat acesta este: /* Afisaj Digital pentru UPS - Afisare tensiune acumulator in gama 0-20V cu sistem de protectie la supradescarcare constand in blocarea convertorului la detectarea tensiunii de 10,75V pe acumulator si afisarea pe LCD a unui mesaj de avertizare precum si avertizare sonora, reluarea functionarii normale a UPS-ului putandu-se face doar dupa resetarea microcontroller-ului. - Afisare curent de incarcare acumulator in gama 0-5A. - Afisare mod de lucru RETEA sau SMPS si a tensiunilor respective. - Microcontroller PIC16F877A. - Cristal 4Mhz. - LCD alfanumeric 2x16. - Autor Marian. - Septembrie 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 VcaMed, VcaRms, VccBAT, AccBAT, VccSMPS, ProtB;unsigned long VR, VB, AB, VS;void main() { INTCON = 0; //Dezactivare intreruperi TRISA = 0xFF; //Portul A setat pe intrare TRISD = 0; //Portul D setat pe iesire PORTD = 0; //Resetare port D Lcd_Init(); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR); Delay_ms(1000); Lcd_Out(1,4,"Afisaj UPS"); //Mesaj initial prima linie Lcd_Out(2,6,"Marian"); //Mesaj initial linia a 2-a Delay_ms(3000); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,1,"B"); Lcd_Out(2,1,"B"); while (1) { //Achizitie ADC VcaMed = 0; VccBAT = 0; AccBAT = 0; VccSMPS = 0; for (ADCx=0; ADCx<36; ADCx++) { VcaMed += ADC_Read(0); //Citeste tensiune retea pe AN0 VccSMPS += ADC_Read(1); //Citeste tensiune SMPS pe AN1 VccBAT += ADC_Read(2); //Citeste tensiune acumulator pe AN2 AccBAT += ADC_Read(3); //Citeste curent incarcare pe AN3 Delay_ms(1); } if (PORTA.F4 == 0) { //Daca RA4 este 0 afiseaza prezenta Lcd_Out(1,9,"RETEA"); //retea si tensiunea detectata //Retea VcaMed = VcaMed/ADCx; //Extragerea valorii medii VcaRms = VcaMed*1.4142; //Alocarea valorii RMS VR = (long)VcaRms*1840; //Seteaza gama de afisaj VR = VR/1023; ch = VR/1000; //Extrage 100 Lcd_Chr(2,9,48+ch); ch = (VR/100) % 10; //Extrage 010 Lcd_Chr_CP(48+ch); ch = (VR/10) % 10; //Extrage 001 Lcd_Chr_CP(48+ch); LCD_Chr_CP('V'); Delay_ms(10); } else { //Daca RA4 este 1 afiseaza prezenta Lcd_Out(1,9,"SMPS "); //SMPS si tensiunea detectata //Convertor VccSMPS = VccSMPS/ADCx; //Aloca valoarea tensiunii de afisat VS = (long)VccSMPS*3500; //Seteaza gama de afisaj VS = VS/1023; ch = VS/1000; //Extrage 100 Lcd_Chr(2,9,48+ch); ch = (VS/100) % 10; //Extrage 010 Lcd_Chr_CP(48+ch); ch = (VS/10) % 10; //Extrage 001 Lcd_Chr_CP(48+ch); LCD_Chr_CP('V'); Delay_ms(10); } //Acumulator-Tensiune VccBAT = VccBAT/ADCx; //Aloca valoarea tensiunii de afisare VB = (long)VccBAT*2000; //Seteaza gama de afisare VB = VB/1023; ch = VB/1000; //Extrage 10.00 Lcd_Chr(1,2,48+ch); ch = (VB/100) % 10; //Extrage 01.00 Lcd_Chr_CP(48+ch); Lcd_Chr_CP('.'); ch = (VB/10) % 10; //Extrage 00.10 Lcd_Chr_CP(48+ch); ch = VB % 10; //Extrage 00.01 Lcd_Chr_CP(48+ch); LCD_Chr_CP('V'); Delay_ms(10); //Acumulator-Curent de incarcare AccBAT = AccBAT/ADCx; //Aloca valoarea de afisat AB = (long)AccBAT*500; //Seteaza gama de afisare AB = AB/1023; ch = AB/1000; //Extrage 10.00 Lcd_Chr(2,2,48+ch); ch = (AB/100) % 10; //Extrage 01.00 Lcd_Chr_CP(48+ch); Lcd_Chr_CP('.'); ch = (AB/10) % 10; //Extrage 00.10 Lcd_Chr_CP(48+ch); ch = AB % 10; //Extrage 00.01 Lcd_Chr_CP(48+ch); LCD_Chr_CP('A'); Delay_ms(10); //Protectie descarcare acumulator ProtB = ADC_Read(2); //Aloca portul de detectie al protectiei if (ProtB < 550) { //Aloca pragul de detectie si verifica valoarea PORTD.F0 = 1; //Activeaza RD0 Lcd_Cmd(_LCD_CLEAR); //Sterge ecranul Lcd_Out(1,4,"PROTECTIE!"); //Afiseaza avertisment Lcd_Out(2,1,"SUPRADESCARCARE!"); do { Sound_Init(&PORTD, 1); //Blocare uC in bucla continua Sound_Play(700, 400); //Si activare avertisment sonor } while (1); } else { PORTD.F0 = 0; } }} Mai jos atasez link catre schema completa a afisajului digital, mai urmeaza ceva retusuri la schema convertorului si apoi conceptia placilor, inca n-am decis daca va fi totul pe o singura placa sau ma voi axa pe ceva module separate, ramane de vazut, oricum e doar un detaliu. Deci iata schema la afisaj: http://img827.imageshack.us/img827/9365/vmo8.png Incarcarea acumulatorului se face de la un traf de retea unde voi avea dupa redresare si filtrare acel LD1084 ( un regulator in stilul LM317, diferentele constant in capabilitatile de curent-5A, si LDO ), tensiunea de incarcare va putea fi ajustata cu ajutorul unui potentiometru pe panou, curentul l-am limitat eu activ la aproximativ 4,4A cu ajutorul acelui shunt si npn, de pe shunt citesc cu un AO inversor si caderea de tensiune pentru monitorizarea digitala a curentului de incarcare, am ales acel 741 pentru posibilitatea de reglare a offset-ului ca astfel sa am o precizie cat mai buna a indicatiei. Fiecare intrare a uC este protejata cu BZX55C5V1. Protectia acumulatorului la descarcare profunda se face prin activarea RD0 la detectarea a aproximativ 10,7V pe acumulator, fapt care prin acea dioda aduce ceva mai mult de 4V in pinul 4 al TL494, evident blocand SMPS-ul, microcontroller-ul isi va intrerupe activitatea normala si va afisa un mesaj de avertisment activand in acelasi timp si buzzer-ul, reluarea activitatii normale a UPS-ului putandu-se face doar dupa resetarea uC de la un buton care deasemenea va fi pe panou. SI cam atat, voi reveni cu noutati cand le voi avea, pentru moment multumiri tuturor pentru sfaturi/sugestii. Toate cele bune. Link spre comentariu
Marian Postat Octombrie 24, 2013 Autor Partajează Postat Octombrie 24, 2013 Salutari. Lucrez la un proiect propriu de amplificator audio ceva mai performant pentru uz personal, si doresc sa-l dotez cu un afisaj digital cu care sa monitorizez temperatura radiatorului etajelor finale si sa-mi puna stop pe alimentarea de putere la atingerea unui prag ales, am un LCD 1x16, mic dar suficient pentru ce am nevoie, si am cateva PIC mai mici, am incercat initial cu PIC16F1503 dar programatorul nu-l suporta, am zis sa merg pe PIC16F84A, numai ca aista nu are ADC... am trecut la PIC18F13K22 si la asta nu reusesc nici macar sa initializez LCD-ul, verificandu-i mai atent pdf-ul constat ca mi-am cam prin urechile ( ca un inceparet la lucrul cu uC ce sunt ), cel mai probabil trebuiesc ceva comenzi suplimentare declarate in functia principala sau poate config-ul tre ajustat desi la asta n-am modificat nimic. Am dorit ca intai sa initializez LCD-ul si deci codul ( foarte scurt ) este asta: //LCD Connectionssbit LCD_RS at RC0_bit;sbit LCD_EN at RC1_bit;sbit LCD_D4 at RC2_bit;sbit LCD_D5 at RC7_bit;sbit LCD_D6 at RC6_bit;sbit LCD_D7 at RC3_bit;sbit LCD_RS_Direction at TRISC0_bit;sbit LCD_EN_Direction at TRISC1_bit;sbit LCD_D4_Direction at TRISC2_bit;sbit LCD_D5_Direction at TRISC7_bit;sbit LCD_D6_Direction at TRISC6_bit;sbit LCD_D7_Direction at TRISC3_bit;void main() { INTCON = 0; Lcd_Init(); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR); Delay_ms(1000); Lcd_Out(1,1,"MP100.V2"); } Ca si oscilator la proba practica pe breadboard am folosit un cristal de 4 Mhz ( la configuratie este selectat HS oscilator si frecventa de 4 Mhz ), am verificat si in proteus si problema este aceeasi, LCD-ul nu indica nimic. Sunt convins ca greseala imi apartine, cum deasemenea sunt convins ca este una de nub, dar lipsa de experienta cu ele isi spune cuvantul, as mai avea niste PIC16F877 dar nu as vrea sa folosesc ditamai uC-ul pentru un singur canal de ADC si un LCD 1x16, deci m-as bucura tare mult sa mearga asta, alternativa ar mai putea fi niste uC-uri SMD numai ca nici de programat nu sunt sigur ca se poate cu pickit2 ce am eu, asa ceva... Asadar apreciez mult orice sugestie sau critica sau observatie, sau orice va indurati sa postati ca si raspuns. Toate cele bune. Link spre comentariu
Vlad Mihai Postat Octombrie 24, 2013 Partajează Postat Octombrie 24, 2013 incerca conexiune cu LCD asa sbit LCD_RS at latRC0_bit;sbit LCD_EN at latRC1_bit;sbit LCD_D4 at latRC2_bit;sbit LCD_D5 at latRC7_bit;sbit LCD_D6 at latRC6_bit;sbit LCD_D7 at latRC3_bit; 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