Sari la conținut

Wattmetru cu PIC


pisica matache
 Share

Postări Recomandate

//Conexiuni LCD
sbit 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 variabile
unsigned char ch, ADCx;
unsigned int Tensiune, Curent;
unsigned long V, A, Pw;
unsigned short current_duty1,current_duty2;
//Functie principala
void main() {
	 INTCON = 0;													 // Dezactivare intreruperi
	 TRISA = 0x03;											 // RA0, RA1 setate ca intrari
	 TRISB.F0=1;
	 TRISB.F1=1;
	 TRISC.F7=1;					  //intrari pentru push-butoane
	 TRISC.F6=1;
   
   
	 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,2,"Afisaj Digital");		   // Mesaj initial 1, prima linie
	 Lcd_Out(2,5,"Multiplu");							   // Mesaj initial 1 linia 2
	 Delay_ms(3000);
	 Lcd_Cmd(_LCD_CLEAR);								   // Stergere ecran
	 Lcd_Out(1,1,"100V; 50A; 5000W");			   // Mesaj initial 2, prima linie
	 Lcd_Out(2,5,"Giongiu");								 // Mesaj initial 2, linia 2
	 Delay_ms(3000);
	 Lcd_Cmd(_LCD_CLEAR);
	 PWM1_Init(15000);							    // f=15 KHz	 !!!!!!!!!!!!!!
	 current_duty1 = 0;
	 PWM1_Start();								    // start PWM1
	 PWM1_Set_Duty(current_duty1);    // setare factor de umplere
	 PWM1_Init(15000);							    // f=15 KHz	 !!!!!!!!!!!!!!
	 current_duty2 = 0;
	 PWM2_Start();								    // start PWM1
	 PWM2_Set_Duty(current_duty2);    // setare factor de umplere
	  while (1) {
	 
	   //control pwm
				   if (Button(&PORTB, 0, 1, 1)) {
				   current_duty1 = current_duty1--;	    //scade pwm1
				   delay_ms(100);
					   }
				   if (Button(&PORTB, 1, 1, 1)) {
				   current_duty1 = current_duty1++; //creste pwm1
				   delay_ms(100);
					  }
				    PWM1_Set_Duty(current_duty1);
				   if (Button(&PORTC, 7, 1, 1)) {
				   current_duty2 = current_duty2--;	    //scade pwm2
				   delay_ms(100);
					   }
				   if (Button(&PORTC, 6, 1, 1)) {
				   current_duty2 = current_duty2++; //creste pwm2
				   delay_ms(100);
					    }
				   PWM2_Set_Duty(current_duty2);

				    //Achizitie ADC
				    Tensiune = 0;
				    Curent = 0;
				    for (ADCx=0; ADCx<10; ADCx++) {
				    Tensiune += ADC_Read(0);				 // Achizitie ADC pentru tensiune
				    Curent += ADC_Read(1);			 // Achizitie ADC pentru curent
				    Delay_ms(10);
				    }
				    //Tensiune
				    Tensiune = Tensiune/ADCx;			   // Alocare valoare tensiune
				    V = (long)Tensiune*1000;				 // Converteste rezultat in milivolti
				    V = V/1023;									   // 0...1023 => 0...1000mV
				    ch = V/1000;									 // Extrage sute 100.00
				    Lcd_Chr(1,1,48+ch);					   // Afisare rezultat in format ASCII linia 1, coloana 1
				    ch = (V/100) % 10;						 // Extrage zeci 010.00
				    Lcd_Chr_CP(48+ch);						 // Afiseaza rezultat in format ASCII
				    ch = (V/10) % 10;							   // Extrage unitati 001.00
				    Lcd_Chr_CP(48+ch);						 // Afiseaza rezultat in format ASCII
				    Lcd_Chr_CP('.');								 // Afiseaza caracter '.'
				    ch = (V/1) % 10;								 // Extrage sutimi  000.10
				    Lcd_Chr_CP(48+ch);
				    ch = V % 10;									 // Extrage zecimi  000.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*5000;				  // Convertire rezultat in milivolti
				    A = A/1023;									   // 0..1023 => 0-5000mV
				    ch = A/1000;									 // Extragere zeci 10.00
				    Lcd_Chr(1,9,48+ch);					   // Scrie rezultatul in format ASCII linia 1, coloana 9
				    ch = (A/100) % 10;						 // Extragere unitati 01.00
				    Lcd_Chr_CP(48+ch);						 // Scrie rezultatul in format ASCII
				    Lcd_Chr_CP('.');
				    ch = (A/10) %10;								 // Extragere sutimi 00.10
				    Lcd_Chr_CP(48+ch);						 // Scrie rezultatul in format ASCII
				    ch = A % 10;									 // Extragere zecimi 00.01
				    Lcd_Chr_CP(48+ch);
				    Lcd_Chr_CP('A');								 // Afisare caracter 'A' la final
				    Delay_ms(10);
				    //Putere
				    Pw = V*A/1000;							 // Seteaza valoare Putere
				    ch = Pw/1000;								   // Extrage mii 1000
				    Lcd_Chr(2,1,48+ch);					   // Scrie rezultatul in format ASCII linia 2, coloana 1
				    ch = (Pw/100) % 10;					   // Extrage sute 0100
				    Lcd_Chr_CP(48+ch);
				    ch = (Pw/10) %10;							   // Extrage zeci 0010
				    Lcd_Chr_CP(48+ch);
				    ch = Pw % 10;								   // Extrage unitati 0001
				    Lcd_Chr_CP(48+ch);
				    Lcd_Chr_CP('W');								 // Afiseaza "W" la sfarsit
				    Delay_ms(10);
	  }
}

Buna ziua, abia acum am vazut ca Marian a postat codul, am introdus si codul meu in codul lui, si le-am compilat pentru 4Mhz, am schimbat 2 butoane in noul cod pentru ca erau utilizate deja porturile pentru afisor, astfel pentru pwm1 vor fi pinii 20 si 21 si pentru pwm2 vor fi 18 si 17.

atasez arhiva cu tot ce trebuie si hexul.

 

aici e linkul cu arhiva, http://www.girlshare.ro/33004237.2 sper sa mearga.

Link spre post
Distribuie pe alte site-uri

Multumesc inca o data,pentru ajutor.Marian,Mihai,sper sa ma revansez cumva.

Chiar azi am ridicat de la posta,LCD-urile si PIC-urile.Vanzatorul a uitat sa-mi puna si cuarturile de 4Mhz,dar gasesc eu unul de proba.Urmeaza sa fac un cablaj de test,si apoi partea cea mai grea,programarea PIC-ului.

Spuneti-mi va rog,ce anume se incarca in PIC,ca sunt bata.HEX-ul daca am inteles bine?

Link spre post
Distribuie pe alte site-uri

Hex-ul(pwm.hex), daca nu gasesti de 4 Mhz, vezi de care ai si iti compilez pentru cuartul respectiv.

nu aveti bearboard, am vazut ca zgariati cablejele, e complicat asa. un bearboard din ala cu gaurele macar sa faceti test pentru pwm.

ce programator aveti?

Editat de Blue_man
Link spre post
Distribuie pe alte site-uri

am mai dat sfatul asta in alte posturi pe froumul asta:

- e mult mai simplu si mai eficient sa programati microcontrollerele direct pe placa cu aplicatia dvs. Astfel nu sunteti nevoit sa scoateti microcontollerul si sa-l introduceti in alta placa, nu veti avea probleme cu soclul (ca e lipit direct pe placa) - iar viteza iteratiilor cand scrieti software-ul e mult marita. (si de fapt va costa un conector in plus)

Al doilea sfat e sa folositi un cablu de programare de la fabricantul de MCU - nu veti avea bataie de cap, ca nu se potriveste cu PC-ul. cu mediul de programare sau driverele. - de multe ori hobbyistii is fac programatoarele avand senzatia ca au economisit 20 euro, dar pe termen lung pierd timp din cauza incompatibilitatii programatorului si in loc sa se concetreze la softul care-l scriu pentru MCU se concetreaza la cum sa faca sa mearga programatorul.

RR

Link spre post
Distribuie pe alte site-uri

Sunt total de acord cu partea cu programarea pe placa finala. Cat despre partea cu programatorul de la producator e alta poveste. Hobbyistii de cele mai multe ori nu prea au bani pentru asta si prefera ca bruma de care dispun sa o cheltuie pe piese (cazul meu). Nu cred ca se pierde prea mult timp pentru testarea si punerea la punct a programatorului. Eu folosesc pentru PIC16 un programatori serial JDM pe care il am inca din scoala (e facut cu oja). Singura problema este pentru utilizatorii de laptopuri care nu mai au port serial. Majoritatea placilor de baza (pentru desktop) au port COM functional, chiar daca nu e scos in spate. Deci daca aveti port COM se pot construi fara probleme programatoare de complexitate redusa (de exemplu cablul LVP - are vreo 5-6 rezistente). Timpul pierdut la programarea uC-ului (rata de transfer e mult mai mica pe COM) il consider total nerelevant (de ordinul secundelor) mai ales pentru cei care nu fac programare/testare ci doar construiesc un prototip cu soft la gata...

Link spre post
Distribuie pe alte site-uri

Buna seara postez schema finala, daca e ok se poate trece la optimizarea ei, gen adaugare control ventilator, buzzer, led, releu ca mai are vreo 4 pini digitali liberi.

http://www.girlshare.ro/33010769

La LCD trebuie reglat din semireglabil de contrast, s-ar putea sa nu afiseze nimic sau sa afiseze patratele, iar pe intrarile de citire curent si tensiune, pentru test sa se conecteze la +5V ambele si ar trebui sa indice maximul masurat, teoretic. sper sa nu fi facut greseli in schema, am verificat de 3 ori.

Editat de Blue_man
Link spre post
Distribuie pe alte site-uri

Azi am facut un cablaj de test,''zgariat'' si am testat jucaria.Dupa ce am facut cateva conexiuni la LCD,pe care in graba le uitasem,a functionat.Am testat atat voltmetru/ampermetru,cat si reglarea PWM.Desi aveam ceva indoieli in ce priveste liniaritatea convertorului,dupa ceva teste trebuie sa recunosc ca e foarte buna.E totusi un pic deranjant zeroul ce ramane in fata valorilor afisate,cat si viteza cam mare,cu care valorile afisate se schimba. De exemplu 7,88V sunt afisati 007,88V.Daca se pot stinge zerourile inutile,ar fi o traba,daca nu e bine si asa.

La reglarea PWM,am ramas iarasi placut surprins;pasii sunt de cca 0,4%,iar stabilitatea umplerii foarte buna.Am un multimetru ce masoara umplerea,am testat de mai multe ori de la zero la umplere maxima si invers.Am descoperit ca tinand un buton apasat,umplerea creste/scade,functie de butonul tinut apasat,lucru extrem de util la reglarea tensiunii/curentului.Altfel ar fi fost cam greu sa apesi un buton de n ori,sa cresti tensiunea de la 2V,sa zicem,la 30V. Totusi viteza de crestere/descrestere a umplerii,tinand butonul apasat,e cam mica,am cronometrat de la zero la umplere maxima,e nevoie de 100 secunde.Daca s-ar putea modifica softul,ca baleierea umplerii sa fie redusa cam la jumatate ar fi perfect.Ramane sa testez filtru care sa-mi faca din umplerea variabila,o tensiune continuua,ce va servi ca referinta sursei in comutatie reglabila.

post-25543-0-02269100-1385144669_thumb.jpg

Editat de pisica matache
Link spre post
Distribuie pe alte site-uri

Buna seara referitor la codul pentru pwm, cred ca pot face sa incrementeze de 2 ori atunci cand se apasa 1 buton, adica se apasa o data si se ia de 2 ori in soft, referitor la filtru eu de aici m-am inspirat http://digital-diy.com/swordfish-example/314-digital-to-analogue-conversion-dac-via-pwm.html .

Pana maine revin cu un cod nou ca sa testezi. sa inteleg ca ai gasit cuart de 4Mhz?

 

O sa rezolv si treaba cu zerourile alea deranjante, stiam un artificiu.

Link spre post
Distribuie pe alte site-uri

Mi-am facut o cafea si am rezolvat problemele care au fost amintite mai sus, la putere din ce vad nu se afiseaza cu virgula decat o valoare bruta rotunda, am scos zerouri, si la pwm se face imcrementarea dubla.

//Conexiuni LCD
sbit 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 variabile
unsigned char ch, ADCx;
unsigned int Tensiune, Curent;
unsigned long V, A, Pw;
unsigned short current_duty1,current_duty2;
//Functie principala
void main() {
	 INTCON = 0;													 // Dezactivare intreruperi
	 TRISA = 0x03;											 // RA0, RA1 setate ca intrari
	 TRISB.F0=1;
	 TRISB.F1=1;
	 TRISC.F7=1;					  //intrari pentru push-butoane
	 TRISC.F6=1;
   
   
	 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,2,"Afisaj Digital");		   // Mesaj initial 1, prima linie
	 Lcd_Out(2,5,"Multiplu");							   // Mesaj initial 1 linia 2
	 Delay_ms(3000);
	 Lcd_Cmd(_LCD_CLEAR);								   // Stergere ecran
	 Lcd_Out(1,1,"100V; 50A; 5000W");			   // Mesaj initial 2, prima linie
	 Lcd_Out(2,5,"Giongiu");								 // Mesaj initial 2, linia 2
	 Delay_ms(3000);
	 Lcd_Cmd(_LCD_CLEAR);
	 PWM1_Init(15000);							    // f=15 KHz	 !!!!!!!!!!!!!!
	 current_duty1 = 0;
	 PWM1_Start();								    // start PWM1
	 PWM1_Set_Duty(current_duty1);    // setare factor de umplere
	 PWM1_Init(15000);							    // f=15 KHz	 !!!!!!!!!!!!!!
	 current_duty2 = 0;
	 PWM2_Start();								    // start PWM1
	 PWM2_Set_Duty(current_duty2);    // setare factor de umplere
	  while (1) {
	 
	   //control pwm
				   if (Button(&PORTB, 0, 1, 1)) {
				   current_duty1 = current_duty1-2;	    //scade pwm1
				   delay_ms(100);
					   }
				   if (Button(&PORTB, 1, 1, 1)) {
				   current_duty1 = current_duty1+2; //creste pwm1
				   delay_ms(100);
					  }
				    PWM1_Set_Duty(current_duty1);
				   if (Button(&PORTC, 7, 1, 1)) {
				   current_duty2 = current_duty2-2;	    //scade pwm2
				   delay_ms(100);
					   }
				   if (Button(&PORTC, 6, 1, 1)) {
				   current_duty2 = current_duty2+2; //creste pwm2
				   delay_ms(100);
					    }
				   PWM2_Set_Duty(current_duty2);

				    //Achizitie ADC
				    Tensiune = 0;
				    Curent = 0;
				    for (ADCx=0; ADCx<10; ADCx++) {
				    Tensiune += ADC_Read(0);				 // Achizitie ADC pentru tensiune
				    Curent += ADC_Read(1);			 // Achizitie ADC pentru curent
				    Delay_ms(10);
				    }
				    //Tensiune
				    Tensiune = Tensiune/ADCx;			   // Alocare valoare tensiune
				    V = (long)Tensiune*1000;				 // Converteste rezultat in milivolti
				    V = V/1023;									   // 0...1023 => 0...1000mV
				    ch = V/1000;						  // Extrage sute 100.00
				    if (ch==0)
				    {
				    LCD_Chr(1,1, 32);			    // afisare  spatiu gol daca    digitul este  0
					 }
					  else
					  {
					  Lcd_Chr(1,1,48+ch);					   // Afisare rezultat in format ASCII linia 1, coloana 1
					    }
				    ch = (V/100) % 10;						 // Extrage zeci 010.00
					 if (ch==0){
					  LCD_Chr(1,2, 32);			    // afisare  spatiu gol daca    digitul este  0
					 } else
					 {
					  Lcd_Chr_CP(48+ch);						 // Afiseaza rezultat in format ASCII
					 }
				    ch = (V/10) % 10;							   // Extrage unitati 001.00
				    Lcd_Chr_CP(48+ch);						 // Afiseaza rezultat in format ASCII
				    Lcd_Chr_CP('.');								 // Afiseaza caracter '.'
				    ch = (V/1) % 10;								 // Extrage sutimi  000.10
				    Lcd_Chr_CP(48+ch);
				    ch = V % 10;									 // Extrage zecimi  000.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*5000;				  // Convertire rezultat in milivolti
				    A = A/1023;
				    ch = A/1000;									 // Extragere zeci 10.00
				    if (ch==0)  {
				    LCD_Chr(1,9, 32);			    // afisare  spatiu gol daca    digitul este  0
				    } else {
					  Lcd_Chr(1,9,48+ch);					   // Scrie rezultatul in format ASCII linia 1, coloana 9
				    }								    // 0..1023 => 0-5000mV
				    ch = (A/100) % 10;						 // Extragere unitati 01.00
				    Lcd_Chr_CP(48+ch);						 // Scrie rezultatul in format ASCII
				    Lcd_Chr_CP('.');
				    ch = (A/10) %10;								 // Extragere sutimi 00.10
				    Lcd_Chr_CP(48+ch);						 // Scrie rezultatul in format ASCII
				    ch = A % 10;									 // Extragere zecimi 00.01
				    Lcd_Chr_CP(48+ch);
				    Lcd_Chr_CP('A');								 // Afisare caracter 'A' la final
				    Delay_ms(10);
				    //Putere
				    Pw = V*A/1000;							 // Seteaza valoare Putere
				    ch = Pw/1000;
				    if (ch==0)  {
				    LCD_Chr(2,1, 32);			    // afisare  spatiu gol daca    digitul este  0
				    } else {
					  Lcd_Chr(2,1,48+ch);					   // Scrie rezultatul in format ASCII linia 1, coloana 9
				    }								    // 0..1023 => 0-5000mV
				    ch = (Pw/100) % 10;					   // Extrage sute 0100
					 if (ch==0)  {
				    LCD_Chr(2,2, 32);			    // afisare  spatiu gol daca    digitul este  0
				    } else {
						 Lcd_Chr_CP(48+ch);
				    }
				    ch = (Pw/10) %10;							   // Extrage zeci 0010
					 if (ch==0)  {
				    LCD_Chr(2,3, 32);			    // afisare  spatiu gol daca    digitul este  0
				    } else {
						 Lcd_Chr_CP(48+ch);
				    }
				    ch = Pw % 10;								   // Extrage unitati 0001
				    Lcd_Chr_CP(48+ch);
				    Lcd_Chr_CP('W');								 // Afiseaza "W" la sfarsit
				    Delay_ms(10);
	  }
}

 

 

Atasez fisierul hex pentru cuart de 4Mhz, acum sa testezi si sa revii cu noi intrebari sugestii.

http://www.girlshare.ro/33013615.8

Link spre post
Distribuie pe alte site-uri

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
 Share

  • Navigare recentă   0 membri

    Nici un utilizator înregistrat nu vede această pagină.


×
×
  • Creează nouă...

Informații Importante

Folosim cookie-uri și tehnologii asemănătoare pentru a-ți îmbunătăți experiența pe acest website, pentru a-ți oferi conținut și reclame personalizate și pentru a analiza traficul și audiența website-ului. Înainte de a continua navigarea pe www.tehnium-azi.ro te rugăm să fii de acord cu: Termeni de Utilizare.