Sari la conținut
ELFORUM - Forumul electronistilor

sursa cu pic


aetius

Postări Recomandate

//Conexiuni LCD
sbit LCD_RS at RB1_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB1_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

  //Declarare variabile
unsigned char ch, ADCx;
unsigned int Tensiune;
unsigned long V;
unsigned short  current_duty_1, current_duty_2 ;

void main()
 {
     ADCON0  = 0b00001101;
     ADCON1 = 0b00000000;
     CMCON = 0b00000111;             // Disable comparators
     CVRCON = 0;          //dezactivam referinta variabila de tensiune


     PORTA = 0b00001011;         // bitii 0 si 1 si 3 ai portului A sunt intrari analogice.
     TRISA = 0b00001011;        // bitii 0, 1, 3, ai portului A sunt intrari, bitii 2,3,5,6,7 sunt iesiri digitale
     TRISB = 0;         // designate PORTB pins as output
     PORTB = 0;          // set PORTB to 0
     TRISC = 0;           // designate PORTC pins as output
     PORTC = 0;          // set PORTC to 0
     TRISD = 1;
     PORTD = 0b11111111;

     Lcd_Init();
     ADC_Init();
     Lcd_Cmd(_LCD_CURSOR_OFF);
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Out(1,1,"Sursa digitala");
     Delay_ms(500);
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Out(1,1,"TENSIUNE:");

     {
      short current_duty_1  = 25; // initial value for current_duty_1
      short current_duty_2 = 25;  // initial value for current_duty_2

      PWM1_Init(5000);  //Initialize PWM1
      PWM2_Init(5000);  //Initialize PWM2

      PWM1_Start();  // start PWM1
      PWM2_Start();  // start PWM2

      PWM1_Set_Duty(current_duty_1); // Set current duty for PWM1
      PWM2_Set_Duty(current_duty_2); // Set current duty for PWM2
      }

  while (1)        // endless loop
  {

                //Achizitie ADC
         Tensiune = 0;
         for (ADCx=0; ADCx<10; ADCx++)
         {
          Tensiune += ADC_Read(0);
          Delay_ms(10);
         }
               //Tensiune
            Tensiune = Tensiune/ADCx;        // Alocare valoare tensiune
            V = (long)Tensiune*5000;         // Converteste rezultat in milivolti
            V = V/1023;                      // 0...1023 => 0...5000mV
            ch = V/1000;                     // Extrage zeci 10.0
            Lcd_Chr(1,10,48+ch);              // Afisare rezultat in format ASCII linia 1, coloana 1
            ch = (V/100) % 10;               // Extrage unitati 01.0
            Lcd_Chr_CP(48+ch);               // Afiseaza rezultat in format ASCII
            Lcd_Chr_CP('.');                 // Afiseaza caracter '.'
            ch = (V/10) % 10;                // Extrage sutimi 00.1
            Lcd_Chr_CP(48+ch);               // Afiseaza rezultat in format ASCII
            LCD_Chr_CP('V');                 // Afiseaza caracter 'V'
            Delay_ms(10);

     if (!RD0_bit)   // if button on RD0 pressed
     {
      Delay_ms(10);
      current_duty_1++;  // increment current_duty_1
      PWM1_Set_Duty(current_duty_1);  //Change the duty cycle
     }

    if (!RD1_bit)               // button on RD1 pressed
    {
      Delay_ms(10);
      current_duty_1--;  // decrement current_duty_1
      PWM1_Set_Duty(current_duty_1);
     }

    if (!RD2_bit)     // if button on RD2 pressed
    {
      Delay_ms(10);
      current_duty_2++;    // increment current_duty_2
      PWM2_Set_Duty(current_duty_2);
     }

    if (!RD3_bit)       //if button on RD3 pressed
    {
      Delay_ms(10);
      current_duty_2--;   // decrement current_duty_2
      PWM2_Set_Duty(current_duty_2);
     }

           if (!RD4_bit)       //if button on RD4 pressed
    {
      Delay_ms(10);
      current_duty_2 = 97;
      PWM2_Set_Duty(current_duty_2);
     }
     
             if (!RD5_bit)       //if button on RD5 pressed
    {
      Delay_ms(10);
      current_duty_2 = 245;
      PWM2_Set_Duty(current_duty_2);
     }
     
     Delay_ms(10);      // slow down change pace a little
  }
}

Incerc s-a fac o sursa digitala de la 0, cam greu cu programarea de aceia va cer ajutorul.

Unde at fi de umblat.

Am ajuns pina aici ,dar m-am impotmolit ...programul se misca mai greu cu liniile pt. voltmetru adaugate.

Tre s-a apas si de 2-3 ori pe buton ca s-a miste ceva...

Multumesc.

0.1.pdsprj 0.1.HEX

Link spre comentariu

Incearca sa reduci si/sau chiar sa scoti acele delay-uri... 10ms pare putin dar de ex. acolo unde faci masurarea tensiunii de 10 ori se ajunge la 100ms, care deja nu mai ii chiar asa putin.

Pe de alta parte, dupa ce ai constatat ca un buton e apasat, stai 10ms pt.ce? 

De regula se asteapta si se testeaza din nou daca butonul este apasat (debounce) dar daca nu faci asta, de ce astepti? 

Doar asa ca pareri, n-am "aprofundat"... :) 

Link spre comentariu

Buna ziua.

Nu ati specificat tipul picului, banuiala mea este ca folositi unul care stie PWM hard.

Lipseste si partea de initializare...

Dar, pornind de la 

Citat

Tre s-a apas si de 2-3 ori pe buton ca s-a miste ceva...

atunci ochiul iti fuge la partea de citire a butoanelor:

if (!RD4_bit)       //if button on RD4 pressed
    {
      Delay_ms(10)...
	}

Acolo ar trebui facut un "debouncing", care arata cam asa:

if(KRIGHT==0){
		Delay1KTCYx(10);
		if(KRIGHT==0){
			//do something...
			while(KRIGHT==0){;}
		}
	}

in traducere, daca apesi un buton, se asteapta un pic, apoi se verifica daca intr-adevar s-a apasat acel buton si n-a fost un spike, ceva, daca trece si de verificarea asta, atunci se executa codul dorit, iar in final, se ia o pauza pana cand ridici degetul de pe buton.

Pe partea de hard, bineineles, pinul este facut pullup printr-o rezistenta.

Asta, asa, la prima vedere. Oricum, cu un cod incomplet, fara a cunoaste picul si cate ceva pe partea de hard, cam asta ar fi. 

Spor.

Link spre comentariu

Nu am Proteus 8.7 si nu am reusit sa il instalez, poate imi dati un MP.

Totusi va rog sa postati schema ca sa o transcriu pentru Proteus 8.5.

In concluzie nu pot deschide fisierul, dar o simulare pe o schema improvizata cu blocuri cu codul original merge asa:

image.thumb.png.06e6e0ac84338df733cde6b79a36b333.png

- la o apasare poate sari chiar si 3-4 trepte de 0,1V, depinde cat de iute faci click pe buton;

- reglajul este intre 0V si 50V;

- daca se creste tensiunea din buton dupa 50V in loc sa se blocheze da 0V si apoi creste;

- daca tensiunea scade, dupa 0V sare brusc la 50V in loc sa se blocheze la 0V;

- tensiunea initiala este 02.5V si sare la un click "Up" la 0.00V si la "Down" sare intre 49.5 si 50V depinde de iuteala clicului.

 

@gsabac

Link spre comentariu
5 hours ago, Thunderer said:

E bine sa faci incrementarea duty-cycle cand ai tranzitie de la 0 la 1, adica cand iei degetul de pe buton.

Mikrobasic - RC6 este utilizat, functia Button face debouncing-ul. 
Daca aplicatia nu e sensibila la milisecunda, e OK sa folosesti Button.

oldstate, steps as byte

**************************

' Step change by encoder push-btn - incrementare
  if Button(PORTC, 6, 1, 1) then
     oldstate = 255
  end if
  if oldstate and Button(PORTC, 6, 1, 0) then ' la tranzitie din 0 in 1 
     oldstate = 0
     inc(steps)
  end if

in caz de overflow, nu vrei sa se reseteze la 0, ci sa stea la 255

  if steps > 255 then
     steps = 0
  end if


***************************

' Step change by encoder push-btn - decrementare
  if Button(PORTC, 6, 1, 1) then
     oldstate = 255
  end if
  if oldstate and Button(PORTC, 6, 1, 0) then
     oldstate = 0
     dec(steps)
  end if

in caz de overflow, nu vrei sa se reseteze la 255, ci sa stea la 0

  if steps < 0 then
     steps = 0
  end if

********************************

in MikroC:

*******************************

bit oldstate;

if (Button(&PORTC, 6, 1, 1)) {                   
      oldstate = 1;                              
    }
    if (oldstate && Button(&PORTC, 6, 1, 0)) {               
      oldstate = 0;
      steps++   SAU steps--   
	                           
    }

NB: Eu scriu in Basic, posibil sa fie greseli de sintaxa. Help-ul Mikro este bun, foloseste-l.

Editat de Thunderer
Link spre comentariu
Acum 11 ore, Thunderer a spus:

E bine sa faci incrementarea duty-cycle cand ai tranzitie de la 0 la 1, adica cand iei degetul de pe buton. 

Altfel o sa incrementeze cat timp butonul e apasat. 

O sa postez mai tarziu un cod pentru asta, daca e nevoie. 

Chiar de aceasta incrementare repetata rapid este nevoie, deoarece altfel te apuca "noaptea" pana schimbi tensiunea de la o valoare la alta.

Se poate rezolva cu o temporizare suplimentara la fiecare apasare apoi daca se mentine apasarea sa ruleze rapid. Procedeul este

 similar functionarii claviaturii sau reglajului unui ceas digital.

 

@gsabac

Link spre comentariu
Acum 3 ore, Thunderer a spus:

Dar 255 de pasi ca sa reglezi tensiunea pot fi oricum prea putini. 

De ce credeti asta? La o sursa de 25V, pasul ar fi de 0,1V(in cazul ideal), suficient cred eu pentru o sursa de alimentare. 

Probleme pot aparea atunci cand la incrementare tensiunea sa sara de ex. de la 16.4V la 16.6V, sau sa nu atinga 16.5V ramanand la 16.4V

Editat de Kreator
Link spre comentariu

Asa e, 256 de pasi (sic!) pot fi de ajuns. Depinde de cerintele utilizatorului. 

 

Ma gandeam ca se poate implementa mai complicat (daca tot punem controller) folosind cei 10b si face un reglaj fin + brut. Ar evita si problema, foarte posibila, indicata de tine = salt neuniform. 

Link spre comentariu

Codul lui @aetius in mikroc, implementat de mine pe neve in Proteus determina urmatoarele reglaje:

- cresterea tensiunii;

- scaderea tensiunii;

- presetare 12V;

- presetare 50V.

Acestea se fac cu PWM2, deci butoanele 1 si 2 care modifica PWM1 ar fi pentru reglajul fin al tensiunii de iesire asa cum bine a sugerat @Thunderer

 si ar trebui sa modific putin schema pentru aceasta.

 

@gsabac

Editat de gsabac
Link spre comentariu

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