Sari la conținut
ELFORUM - Forumul electronistilor

Voltmetru/Ampermetru cu PIC 16F877A


GeoMar

Postări Recomandate

PIC-ul e protejat numai la citire. Il poti re-scrie oricand peste un cod (hex) protejat. Problema e in alta parte.Esti sigur ca ai ales PIC-ul corect in programator? Ce programator ai? Cablu lung?

Link spre comentariu

pic 16f877A am programat..programator am pickit2 clona..cablu o folosesc pe cea de la imprimantasi a doua problema regulatoru de +5 volti se incinge cam tare..cu lcd-ul in montaj...fara lcd nu..oare e de proasta calitate regulatoru??sau backlightu consuma asa de mult??

Link spre comentariu

pic 16f877A am programat..programator am pickit2 clona..cablu o folosesc pe cea de la imprimantasi a doua problema regulatoru de +5 volti se incinge cam tare..cu lcd-ul in montaj...fara lcd nu..oare e de proasta calitate regulatoru??sau backlightu consuma asa de mult??

 

Vorba colegilor, (cu), code protect activat NU poti citi ce hex ai scris in PIC, nu are treaba cu rescrierea unui alt hex in PIC.

 

Referitor la "incingerea" stabilizatorului de +5Vcc, posibil sa fie "prost" el de la mama lui si verifica ca la afisajul LCD, pe partea de backlight, dioda LED care ilumineaza afisajul sa "contina" o rezistenta serie cu ea, multe LCD-uri au/nu au acea rezistenta de limitare pe backligt

Editat de GeoMar
Link spre comentariu

ok... multumesc pentru sfaturi..am sa verific...lcd-ul,s-a rezolvat si programarea picului pina la urma...nu stiu ce a avut dar tot l-am fortat si a mers pina la urma...si inca o intrebare...daca nu sunt prea obraznic...cu ce program se poate copila(si un pic de ajutor cu pasii urmati) si mai are cineva programu radacina inca?????

Link spre comentariu

ok... multumesc pentru sfaturi..am sa verific...lcd-ul,s-a rezolvat si programarea picului pina la urma...nu stiu ce a avut dar tot l-am fortat si a mers pina la urma...si inca o intrebare...daca nu sunt prea obraznic...cu ce program se poate copila(si un pic de ajutor cu pasii urmati) si mai are cineva programu radacina inca?????

 

Codul este scris in Micro C, programul "radacina", adica mai pe romaneste, proiectul "de baza" de la care am pornit/modificat/imbunatatit softul este aici:  http://www.sj-hobi.net/index.php?id=multimeter-pic16f877

Softul pentru proiectul meu a suferit multe/diverse modificari/imbunatatiri fata de proiectul de "baza".

 

Succes.

Link spre comentariu

si acest soft cu modificari si imbunatatiri nu o mai are nimeni oare?? care sa se poata copila..adica schimbarea mesajului de intimpinare..

Daca este vorba de schimbarea mesajului de intampinare, de la softul modificat de mine, zilele urmatoare iti pot modifica mesajul care apare si iti pot oferi HEX-ul.

 

Trebuie doar sa instalez MicroC ca nu il mai am in PC, dupa reinstalul de Win.  :pandaci

Link spre comentariu

e ok pentru mine...dar nu am vrut sa deranjez...acum de sarbatori cu problemele mele..de aceea am cerut softul radacina si programul cu care se poate copila...si cu un pic de ajutor poate ma descurcam si eu......

Link spre comentariu

Postez software-ul care il folosesc in prezent pe V-A ce echipeaza sursa mea:

http://www.elforum.info/topic/42375-sursa-0-30v0-10a/?p=899917

Pt. a masura pana la 10A am modificat R7 si R6 noile valori fiind 3,3 k respectiv 680 ohmi plus calibrare din R8, notatiile fiind cele din schema lui GeoMar (atentie, schema lui GeoMar are o mica eroare la conectarea +5V pe pinul 1 MCLR si VDD pinii12, 31 in topic este si schema corecta).

Explicatii cum functioneaza se gases in paginile precedente, cine vrea sa aduca imbunatatiri este binevenit. 

// LCD module connectionssbit LCD_RS at RB2_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 TRISB2_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;// End LCD module connections//char lcd_buffer[16];char msg[17];                        //declare array set to max size required plus 1 [for terminator] for copying into// copy const to ram stringchar * CopyConst2Ram(char * dest, const char * src){  char * d ;  d = dest;  for(;*dest++ = *src++;)    ;  return d;}const char LCD_txt1[] = "Hello xxxxxxxxx!";const char LCD_txt2[] = "How are you?";const char LCD_txt3[] = "Loading modules";const char LCD_txt4[] = "Power supply";const char LCD_txt5[] = "0-30Vdc  0-10Adc";const char LCD_txt6[] = "* I'm ready! *";const char LCD_txt7[] =  "What about you?";const char LCD_txt8[] = "Output short";const char LCD_txt9[] = "circuit detected";const char LCD_txt10[] = "Please remove";const char LCD_txt11[] = "short circuit!";const char LCD_txt12[] = "OVERCURRENT";const char LCD_txt13[] = "I > 10A";const char LCD_txt14[] = "Overtemperature!";const char LCD_txt15[] = "T>90";const char units[] = {'V', 'A', 'W'}; void Tone1() {  Sound_Play(659, 75);               // Frequency = 659Hz, duration = 250ms}void Tone2() {  Sound_Play(698, 75);               // Frequency = 698Hz, duration = 250ms}void Tone3() {  Sound_Play(784, 75);               // Frequency = 784Hz, duration = 250ms}bit x;                              // Flag for subroutine short or overcurrentunsigned int y=0, time=0, scov=0, tmp=0, sc=0;void interrupt() {  if (INTCON.TMR0IF ==1)   {    sc++;                                      // Used in short-circuit timing    tmp++;                                     // Used in read temperature timing    scov++;                                  // Used in short-circuit, overcurrent and overtemperature timing    time++;                                    // Used in read temperature timing    y++;                                        // Used in short-circuit, overcurrent and overtemperature timing    INTCON.TMR0IF = 0;               // Clear timer0 interrupt flag    TMR0 = 4;                               // Preset for timer register   } }const char character[] = {14,10,14,4,31,4,10,17};           // Initial splash screen symbolvoid CustomChar(char pos_row, char pos_char){  char i;  Lcd_Cmd(64);  for (i = 0; i<=7; i++)  Lcd_Chr_CP(character[i]);  Lcd_Cmd(_LCD_RETURN_HOME);  Lcd_Chr(pos_row, pos_char, 0);}unsigned char  ch, ADCx;unsigned int Voltage, Current;unsigned long V, A, Pw;  void show_intro(void)                           // Initial splash screen{  char i;Tone1();  delay_ms (100);  Lcd_Cmd(_LCD_CURSOR_OFF);                             // Turn cursor off  Lcd_Cmd(_LCD_CLEAR);                                         // Clear LCD  Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt1));       // Write text "Hello ***!" in first row  delay_ms (1000);Tone1();  Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt2));       // Write text "How are you?" in second row  delay_ms (1500);  Lcd_Cmd(_LCD_CLEAR);  Lcd_Out(1,2,CopyConst2Ram(msg,LCD_txt3));       // Write text "Loading modules" in first row  delay_ms(500);  CustomChar (2,1);                                                       // Write custom character in second row -->  for(i=0;i<15;i++)  {    LCD_Chr_CP(0);    Tone3();    delay_ms(50);  }  delay_ms(500);  Lcd_Cmd(_LCD_CURSOR_OFF);  Lcd_Cmd(_LCD_CLEAR);Tone1();  Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt4));         // Write text "Power supply" in first row  Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt5));         // Write text "0-30Vdc  0-10Adc" in second row  delay_ms(2500);  Lcd_Cmd(_LCD_CLEAR);  Lcd_Out(1,2,CopyConst2Ram(msg,LCD_txt6));         // Write text "* I'm ready! *" in first row  Lcd_Out(2,2,CopyConst2Ram(msg,LCD_txt7));         // Write text "What about you?" in second rowTone1();Tone2();Tone3();Tone3();Tone1();Tone2();Tone3();Tone3();Tone1(); Tone2(); Tone3();  delay_ms(1500);  Lcd_Cmd(_LCD_CURSOR_OFF);                           // Turn cursor off  Lcd_Cmd(_LCD_CLEAR);                                       // Clear LCD}//const unsigned short TEMP_RESOLUTION = 9;          // Resolution of used DS18x20 sensorchar *text = "  0.0";unsigned temp; void Display_Temperature(int temp2write)                     // Format temperature results {  bit T;                                                                                 // Flag to select negative or positive temperature display  const unsigned short RES_SHIFT = 1;                             //TEMP_RESOLUTION - 8;  char temp_whole;  unsigned int temp_fraction;  // Check if temperature is negative  if (temp2write & 0x8000)    {     T=1;                                                                 // Flag =1 to select negative temperature display     temp2write = ~temp2write + 1;    }    else   T=0;                                                                      // Flag =0 to select positive temperature display  // Extract temp_whole  temp_whole = temp2write >> RES_SHIFT ;  // Convet temp_whole to characters  switch(T)   {     case 0:                                                                    // Display if temperature is positive            if(!(temp_whole/100))            text[0] = ' ';            else            text[0] = temp_whole/100 + 48;                           // Extract hundreds digit            if(!(temp_whole/10)%10)            text[1] = ' ';            else            text[1] = (temp_whole/10)%10 + 48;                    // Extract tens digit            text[2] =  temp_whole%10 + 48;                          // Extract ones digit            break;     case 1:                                                                       // Display if temperature is negative            if(!((temp_whole/10)%10))            {              text[0] = ' ';              text[1] = '-';              text[2] = (temp_whole%10 + 48);                         // Extract ones digit             }           if((temp_whole/10)%10)            {             text[0] = '-';             text[1] = ((temp_whole/10)%10 + 48);                  // Extract tens digit             text[2] = (temp_whole%10 + 48);                           // Extract ones digit            }            break;   }  // Extract temp_fraction and convert it to unsigned int  temp_fraction  = temp2write << (4-RES_SHIFT);  temp_fraction &= 0x000F;  temp_fraction *= 625;  // Convert temp_fraction to characters  text[4] =  temp_fraction/1000    + 48;                // Extract thousands digit  //text[5] = (temp_fraction/100)%10 + 48;         // Extract hundreds digit }  void ReadTemp()                                              // Perform temperature reading {  Ow_Reset(&PORTD, 0);                                // Onewire reset signal  Ow_Write(&PORTD, 0, 0xCC);                      // Issue command SKIP_ROM  Ow_Write(&PORTD, 0, 0x44);                       // Issue command CONVERT_T   if (time>80)         // Delay for temp conversion (Temperature Conversion Time 750ms Max)   {    Ow_Reset(&PORTD, 0);    Ow_Write(&PORTD, 0, 0xCC);                      // Issue command SKIP_ROM    Ow_Write(&PORTD, 0, 0xBE);                      // Issue command READ_SCRATCHPAD    temp =  Ow_Read(&PORTD, 0);    temp = (Ow_Read(&PORTD, 0) << 8) + temp;    time=0;   } }  const char gradc[] = {16,6,9,8,8,9,6,0};                   // Degree celsius symbol  void celsius(char pos_row, char pos_char) {  char i;  Lcd_Cmd(64);  for (i = 0; i<=7; i++) Lcd_Chr_CP(gradc[i]);  Lcd_Cmd(_LCD_RETURN_HOME);  Lcd_Chr(pos_row, pos_char, 0); }  void Display_Temp()                                 // Display Temperature {   Lcd_Out(2,11,text);   Display_Temperature(temp);   ReadTemp(); }  void Overtemp()                                      // Overtemperature subroutine{    if(!(temp & 0x8000)) {       scov=0;     y=0;     Lcd_Cmd(_LCD_CLEAR);     PORTB.F1=0;                                        // Relay OFF     while (temp>160) {     celsius(2,16);                                     // Degree celsius symbol     Display_Temp();                                    // Display temperature      if(scov<3000)    {       if(y>10)      {       Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt14));       // Write text "Overtemperature!" in first row       Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt15));       // Write text "T>90" in second row       celsius(2,5);                                                                // Write celsius symbol after "T>90" in second row      }      if(y>150)      {       Lcd_Cmd(_LCD_CLEAR);       Tone3();       Delay_ms(100);       y=0;      }     }     else         //if(scov>3000)    {       if(y>10)      {       Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt14));        // Write text "Overtemperature!" in first row       Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt15));        // Write text "T>90" in second row       celsius(2,5);                                                                  // Write celsius symbol after "T>90" in second row      }       if(y>3000)      {        Tone3();        Lcd_Cmd(_LCD_CLEAR);        Delay_ms(10);        y=0;        scov=3001 ;      }    }  } } Lcd_Cmd(_LCD_CLEAR);} void volt_ADC()                                 // Reading the analog inputs (ADC)  {    Voltage = 0;    for (ADCx=0; ADCx<5; ADCx++)     {      Voltage += ADC_Read(1);           // Reading voltage values from channel 1      Delay_us(20);     }    Voltage = Voltage/ADCx;                 // Voltage calculation    V = (long)Voltage*3500;                  // Millivolts conversion    V = V/1023;                                     // 0...1023 => 0...3500mV  } void crt_ADC()                                     // Reading the analog inputs (ADC)  {    Current = 0;    for (ADCx=0; ADCx<5; ADCx++)     {      Current += ADC_Read(0);           // Reading current values from channel 0      Delay_us(20);     }    Current = Current/ADCx;              // Current calculation    A = (long)Current*1005;               // Millivolts conversion    A = A/1023;                                  // 0..1023 => 0...3500mV  } void Display_voltage ()  {    ch = V/1000;                                    // Extract tens digit 10.00    if (ch==0)    Lcd_Chr(1,1,32);    else    Lcd_Chr(1,1,48+ch);                // Display results in ASCII format    ch = (V/100) % 10;                  // Extract ones digit 01.00    Lcd_Chr_CP(48+ch);               // Display results in ASCII format    Lcd_Chr_CP('.');                      // Display caracter '.'    ch = (V/10) % 10;                    // Extract tenths digit  00.10    Lcd_Chr_CP(48+ch);    ch = V % 10;                            // Extract hundredths digit 00.01    Lcd_Chr_CP(48+ch);    LCD_Chr_CP (units[0]);             // Print "V" after voltage value    Delay_ms(50);  }  void Display_current ()  {    ch = A/1000;                             // Extract tens 10.00    if (ch==0)    Lcd_Chr(1,11,32);    else    Lcd_Chr(1,11,48+ch);             // Display results in ASCII format    ch = (A/100) % 10;                   // Extract ones digit 01.00    Lcd_Chr_CP(48+ch);                // Display results in ASCII format    Lcd_Chr_CP('.');                        // Display caracter '.'    ch = (A/10) %10;                       // Extract tenths  00.10    Lcd_Chr_CP(48+ch);                // Display results in ASCII format    ch = A % 10;                             // Extract hundredths 00.01    Lcd_Chr_CP(48+ch);    Lcd_Chr_CP(units[1]);              // Print "A" after current value    Delay_ms(50);                          // Ten microseconds delay  }  void Display_power ()  {    Pw = V*A/1000;                   // Power calculation    ch = Pw/1000;                      // Hundreds digit calculation and display    if (ch==0)     Lcd_Chr(2,1,32);    else    Lcd_Chr(2,1,48+ch);    ch = (Pw/100) % 10;              // Tens digit calculation and display    if (ch==0 && (Pw/1000==0))    Lcd_Chr(2,2,32);    else    Lcd_Chr(2,2,48+ch);    ch = (Pw/10) %10;                // Units digit calculation and display    Lcd_Chr_CP(48+ch);    Lcd_Chr_CP('.');                    // Display caracter '.'    ch = (Pw/1) % 10;                // Tenths digit calculation and display    Lcd_Chr_CP(48+ch);    Lcd_Chr_CP(units[2]);            // Print "W" after power value  }  void display_short()               // Short circuit subroutine { char a;  PORTB.F1=0;                        // Relay OFF  Lcd_Cmd(_LCD_CLEAR);  y=0;  scov=0;  sc=0;  do {   if(sc<3000) a=1;   if(sc>3000) a=2;  switch(a)  {    case 1:        if(y<10)        {          Lcd_Cmd(_LCD_CLEAR);          Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt8));     // Write text "Output short" in first row          Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt9));     // Write text "circuit detected" in second row          Tone3(); Tone1();          scov=0;          y=50;         }        if((y>150)&&(scov<250))        {         Lcd_Cmd(_LCD_CLEAR);         Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt10));     // Write text "Please remove" in first row         Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt11));     // Write text "short circuit!" in second row         Tone1();  Tone3();         scov=250;        }        if(scov>350)        {         y=0;        }      break;    case 2:         if(y<10)        {          Lcd_Cmd(_LCD_CLEAR);          Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt8));     // Write text "Output short" in first row          Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt9));     // Write text "circuit detected" in second row          Tone3();  Tone1();          scov=0;          y=50;         }        if((y>1500)&&(scov<2150))        {         Lcd_Cmd(_LCD_CLEAR);         Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt10));     // Write text "Please remove" in first row         Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt11));     // Write text "short circuit!" in second row         Tone1();  Tone3();         scov=2150;        }        if(scov>2800)        {         y=0;        }      break;   }   if(tmp>80)                                               // Delay for temp conversion (Temperature Conversion Time 750ms Max)    {     ReadTemp();     tmp=0;    }    if((temp>80)&&(!(temp & 0x8000))) PORTD.F1=1;           // If temp. is positive and > 40 start cooler    if(temp<60) PORTD.F1=0;                                                 // If temp is < 30 stop cooler    volt_ADC();                                                                       // Read voltage  }  while(V>0);                                                                          // Do print_scurt while voltage > 0  Lcd_Cmd(_LCD_CLEAR);  x=1;                                                                                     // Set flag x}  void display_overcurrent()                                                   // Overcurrent subroutine {   PORTB.F1=0;                                                                          // Relay OFF  Lcd_Cmd(_LCD_CLEAR);  scov=0;  y=0;  //PORTB.F0=1;  do  {    if(scov<3000)    {       if(y>10)       {       Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt12));            // Write text "OVERCURRENT" in first row       Lcd_Out(2,5,CopyConst2Ram(msg,LCD_txt13));            // Write text "I > 10A" in second row       }       if(y>150)       {         Lcd_Cmd(_LCD_CLEAR);         Tone2();         Delay_ms(100);         y=0;       }     }     else  //if(scov>=1550)     {       if(y>5)        {        Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt12));            // Write text "OVERCURRENT" in first row        Lcd_Out(2,5,CopyConst2Ram(msg,LCD_txt13));            // Write text "I > 10A" in second row        }        if(y>3000)        {         Lcd_Cmd(_LCD_CLEAR);         Tone2();         Delay_ms(100);        y=0;        }       scov=3500 ;     }    if(tmp>80)                                                                     // Delay for temp conversion (Temperature Conversion Time 750ms Max)    {     ReadTemp();      tmp=0;    }    if((temp>80)&&(!(temp & 0x8000))) PORTD.F1=1;         // If temp.is positive and > 40 start cooler    if(temp<60) PORTD.F1=0;                                                // If temp is < 30 stop cooler    volt_ADC();                                                                     // Read voltage  }  while(V>0);                                                                   // Do print_overload while voltage > 0  Lcd_Cmd(_LCD_CLEAR);  x=1;                                                                                 // Set flag x }  void main(){  TRISB=0;                                       // Make PORTB pin an output  PORTB=0;                                      // Set PORTB to 0  ADCON1     = 0x88;                       // Configure Vref, and analog channels  TRISA      = 0xFF;                          // Designate PORTA as input  TRISD      = 0xFD;                          // Designate PORTD as input, RD1 output  OPTION_REG = 0;                                  // Clear option register  OPTION_REG = 0b10000111;                 // Prescaler is assigned to the Timer0, Prescaler = 256  INTCON     = 0;                                        // Clear the interrpt control register  INTCON     = 0b10100000;                      // Bit7 global interrupt enable, Bit5 TMR0 overflow interrupt enable  TMR0             = 4;                                   // Preset for timer register    PORTD.F1=0;                                              // Set PORTD pin 1 to 0  //PORTB.F1=0;                                            // Set PORTB pin 1 to 0  Sound_Init(&PORTB, 0);                             // Configures the MCU pin 0 for sound generation  Lcd_Init();                                                       // Initialize LCD  Lcd_Cmd(_LCD_CLEAR);                              // Clear LCD  Lcd_Cmd(_LCD_CURSOR_OFF);                  // Turn cursor off  show_intro();                                                // Show splash screen  Lcd_Cmd(_LCD_CLEAR);  Delay_ms(10);                                              // 10 milliseconds delay  time=0;  while(1)                                                        // Endless loop {    do      {       volt_ADC();                                                        // Read voltage       crt_ADC();                                                          // Read current       x=0;                                                                      // Reset flag x       if((V==0) && (A>0)) display_short();                    // Check for output short circuit       if((V>0) && (A>1000)) display_overcurrent();     // Check for output overcurrent      }    while(x>0);  // Do while x=1, means that the subroutine short or overcurrent has finished         PORTB.F1=1;                          // Relay ON     PORTB.F0=0;                          // Set PORTB pin 0 to 0     celsius(2,16);                         // Display degree celsius symbol row 2 col 16     Display_voltage();     Display_current();     Display_power();     Display_Temp();     if((temp>=80)&&(!(temp & 0x8000))) PORTD.F1=1;      // If temp.is positive and > 40 start cooler     if(temp<=60) PORTD.F1=0;                                            // If temp is < 30 stop cooler     if(temp>180) Overtemp();                                              // If temp is > 90 do overtemp }}
Link spre comentariu

Buna seara domnilor, as vrea sa fac si eu v-a metrul acesta dar fara optiunea cu protectia la scurtcircuit dar nu stiu sa modific programul, ma puteti ajuta careva?

Editat de Florian Ciobanu
Link spre comentariu
  • 2 săptămâni mai târziu...
  • 2 săptămâni mai târziu...

buna seara..am finalizat voltampermetru cu pic 16f877a...totul functioneaza aproape bine(zic aproape bine deoarece...am icarcat hexul(ultimul postat)de domnul danpin..dar nu imi masoara curentul doar tensiunea...daca pun sarcina pe sursa monitorizata nu imi indica nimic la curent....oare care ar fi problema??undeam gresit?? niste pareri sugestii...multumesc..

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