PIC-C ve Pic Basic Pro Çevirimi

Başlatan ete, 02 Nisan 2004, 13:45:45

ete

Arkadaşlar,

Aşağıda Pic-C olarak ve Pic 16F876 için yazılmış bir program var.

Bu program Digital Güç Kaynağına aittir. Yani tamamen buttonlar yardımı ile kaynaktan çıkmasını istediğiniz volt ve amper değerini LCD ekrana bakarak ayarlıyorsunuz ve sonuçta çıkıştan bu

değerleri alıyorsunuz. Programda bazı değişiklikler yapmak istiyorum ancak hiç C bilmediğim için yapamıyorum. Anladığım kadarı ile LCD bölümü C de bayağı yer tutmuş. BU PBP da daha kısa

olabilir. Bir arkadaşımız bu programı kabaca da olsa PBPro ya çevirebilirmi acaba.
Bu arada devreyi ben yaptım ve çalışıyor. Görmek isteyen olursa

linki;

http://www.qsl.net/ve2emm/pic-projects/alim/alim-e.html

Link de yukarıdaki program hem hex olarak hemde açık olarak verilmiş. Yeniden yazmamak için ordan

alabilirsiniz.

Bu arada devrede LT1491 OPAMP kullanılmış ancak sistemi LM358 ile çalıştırabildim. Yapmak isteyen olursa ufak bir tadilat gerekiyor yalnızca LM358 offset voltaj ayarı

için. Buda LM317 ayar bacağı direkt şaseye değil 160 ohm gibi bir dirençle şaseye bağlanacak.

ETE


//-------------------------- ALIM 2 -----------------------------------------
//

  ALIMENTATION VARIABLE CONSTANT VOLTAGE, CONSTANT COURANT,      0 < 25V
//    2 gammes de courant, 0<1A et 0<10A                         VERSION:

1.3
//         PAR VE2EMM                                              janvier 03
//---------------------------------------------------------------------------
#include <16F876a.h>
//#device *=16      

                // l'indirect peut aller partout en memoire
#device ADC=16                      // les 10 bits de gauche sont valable
#use delay(clock=20000000)
#fuses

HS,NOWDT,PUT,BROWNOUT,NOPROTECT,NOLVP,NOCPD,NOWRT
//#rom 0x2100={0x00,0x00,0x00,0x00,0x00}   // zero les premieres 4 cases du

EEDATA

//------------------------- VARIABLES -------------------

int1 flag_low_range;  //  si 1 indique gamme 10A, si 0 indique gamme 1A
INT8 i;                //  0 < +

255
int8 commande;         //  0 < + 255
int8 car;              //  0 < + 255
int8 nibble;           //  0 < + 255
int8 boutons;          //  0 < + 255
int8 bit_status;       //  0

< + 255
//-----------

signed int16 volt_moy[16];
signed int16 amp_moy[16];
signed int16 volt_set=0; // -32768 < +32767
signed int16 volt_lue;     //    "        

"
signed int16 amp_set=100;  //    "        "
signed int16 amp_lue;      //    "        "

//------------------------- FONCTIONS ---------------

void pic_ini(void);
void

lcd_ini(void);
void write_cmd_lcd(int8);  // LCD
void write_car_lcd(INT8);  // LCD
void send_nibble(int8);    // LCD
void busy_status();        // LCD

void

lire_voltage();       // lire et afficher E
void lire_courant();       // lire et afficher I
void lire_PB(); // lire les boutons, changer les consignes de voltage et de courant
void

comparer_Iset_Ilue(); // determiner qui est en controle, E ou I

//********************************* MAIN ***********************************

void main(void)
{
 

pic_ini();
  lcd_ini();
  for(i=0;i<=15;i++) volt_moy=0;
  for(i=0;i<=15;i++) amp_moy=0;


//------- afficher ecran d"acceuil -------
 

write_cmd_lcd(128);      // adresse du debut de la 1 re ligne
  printf(write_car_lcd,"  ALIMENTATION  ");
  write_cmd_lcd(192);      // adresse du debut de la 2 ie ligne
 

printf(write_car_lcd,"   PAR VE2EMM   ");
  for(i=0;i<6;i++) delay_ms(250); // laisser affichage 1 1/2 seconde

//---- charger les valeurs du eedata
  for(i=0;i<2;i++)

*(&volt_set+i)=read_eeprom(10+i); // reprendre les consignes
  if((volt_set>1023)||(volt_set<0))volt_set=0;
  for(i=0;i<2;i++) *(&amp_set+i)=read_eeprom(12+i);  //

du dernier usage
  if((amp_set>1023)||(amp_set<0))amp_set=0;
  flag_low_range=read_eeprom(14); // reprendre l'etat du flag de range

//---- programme principal


 while(true)
  {
     lire_PB(); // lire les boutons et placer les consignes de voltage et de courant
     lire_voltage();       // lire et afficher
     lire_courant();       // lire et afficher
 

   comparer_Iset_Ilue(); // lire et afficher qui est en controle, E ou I
  }
}

//********************************* FIN MAIN

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

//************************************ FONCTIONS *****************************

void pic_ini(void)
{
//-- PORTS
 

output_A(0x00);
  #use fast_io(A)
  set_tris_A(0b11011111);
  output_B(0x00);
  port_B_pullups(true);
  #use fast_io(B)
  set_tris_B(0b11111111);
 

output_C(0x00);
  #use fast_io(C)
  set_tris_C(0b00000000);
//--- ADC
  setup_adc_ports(RA0_RA1_RA3_ANALOG);
 

setup_adc(ADC_CLOCK_INTERNAL);
//--- PWM
  setup_ccp1(CCP_PWM_PLUS_3);
  setup_ccp2(CCP_PWM_PLUS_3);
  setup_timer_2(t2_div_by_16,255,1);
 

SET_PWM1_duty(0); // amp_set
  SET_PWM2_duty(0); // volt_set
}

//-------------------------------------------------

void lcd_ini(void)
{
   delay_ms(100);        //

attendre que le 5V soit stabilise
  output_bit(PIN_A5,0); // E clock
  output_bit(PIN_C0,0); // R/W  R=1,W=0
  output_bit(PIN_C3,0); // R/S 0 pour commande, 1 pour

data
   for(i=1;i<=4;i++) {send_nibble(0x30); delay_ms(5);} // reset du LCD
  send_nibble(0x20);    // interface 4 bits
  delay_us(43);
   write_cmd_lcd(0x28);  // interface 4

bits, 5X7
  write_cmd_lcd(0x08);  // display off
   write_cmd_lcd(0x0C);  // display on
   write_cmd_lcd(0x06);  // increment no display shift
}

//***********************

Fonctions du LCD *****************************

void write_cmd_lcd(commande)
{
  busy_status();          // LCD pret?
  output_bit(PIN_C3,0);   // R/S 0 pour

commande
   send_nibble(commande);  // placer commande dans LCD
  swap(commande);
  send_nibble(commande);  // placer commande dans LCD
}

//--------------

afficher un caractere sur le LCD --------------------------

void write_car_lcd(car)
{
  busy_status();         // LCD pret?
  output_bit(PIN_C3,1);  // R/S 1 pour

data
   send_nibble(car);      // placer commande dans LCD
  swap(car);
  send_nibble(car);      // placer commande dans LCD
}

//-------------------- Envoyer un nibble

----------------

void send_nibble(nibble)
{
  output_bit(PIN_C0,0);  // R/W  R=1, W=0
   output_bit(PIN_A5,0);  //  E line low
 

delay_cycles(3);
   output_bit(PIN_A5,1);  // pulser E high
  nibble=nibble&0xF0;    // vider les 4 bits du bas de la byte
  nibble=nibble|(input_C()&0x0F); // charger

C0-C3
  output_C(nibble);
  delay_cycles(3);
  output_bit(PIN_A5,0);  // E low
}

//-----------------------

void busy_status() // tester si le LCD est pret a

accepter un data
{
  do
  {
     set_tris_C(0b11110000);
     output_bit(PIN_A5,0); // E off
     output_bit(PIN_C0,1); // R/W  R=1,W=0
     

output_bit(PIN_C3,0); // R/S 0 pour commande, 1 pour data
     delay_cycles(3);
     output_bit(PIN_A5,1); // pulser E high
     delay_cycles(3);
     

bit_status=input_C()&0X80; // lire status
     delay_us(2);
     output_bit(PIN_A5,0); // E off
     delay_cycles(3);

     output_bit(PIN_A5,1); // pulser E high
     

delay_us(1);          // faire semblant de lire les 4 bits de status du bas
     output_bit(PIN_A5,0); // E off
     delay_cycles(3);

  }
  while(bit_status==0x80);
 

set_tris_C(0b00000000);
}

//***************************** Fin des fonctions LCD ********************************

void lire_voltage()           // lire et afficher
{
     

SET_ADC_CHANNEL(0);
     delay_ms(1);
     for(i=15;i>=1;i--) volt_moy=volt_moy[i-1];
     volt_moy[0]=READ_ADC()/64; // tasser a droite la lecture dans les 2 bytes, 6

bits
     volt_lue=0;
     for(i=0;i<=15;i++) volt_lue=volt_lue+volt_moy;
     volt_lue=volt_lue/16;
     volt_lue=volt_lue+2;// compenser pour le restant de la division a

l'affichage
     //if(volt_lue<=7)volt_lue=0;
     write_cmd_lcd(203);     // adresse du debut de la 2ie ligne
     

printf(write_car_lcd,"%02ld,%1ldV",volt_lue/40,volt_lue/4);
}

//----------------------------

void lire_courant() // lire et afficher, tester si I depasse la limite et est en

controle
{
     SET_ADC_CHANNEL(1);
     delay_ms(1);
     for(i=15;i>=1;i--) amp_moy=amp_moy[i-1];
     amp_moy[0]=READ_ADC()/64; // tasser a droite la

lecture dans les 2 bytes, 6 bits
     amp_lue=0;
     for(i=0;i<=15;i++) amp_lue=amp_lue+amp_moy;
     amp_lue=amp_lue/16;
     amp_lue=amp_lue+1;
     

write_cmd_lcd(192);    // adresse du 3/4 de la 2ie ligne
     if(flag_low_range!=0)printf(write_car_lcd,"%02ld,%02ldA",amp_lue/100,amp_lue);
     else

printf(write_car_lcd,"%01ld,%03ldA",amp_lue/1000,amp_lue);
}

//----------------------------

void lire_PB() // lire les boutons et setter voltage et le courant
{
 

boutons=input_b();
  if(boutons!=0xFF)
  {
     switch(boutons)
    {
        case 0b01111111:      // grande reduction du courant *************
           

volt_set=volt_set-40;
           if(volt_set<=0) volt_set=0;
           break;
       case 0b10111111:      // grande reduction du voltage
           amp_set=amp_set-50;
           

if(amp_set<=0) amp_set=0;
           break;
        case 0b11011111:      // grande augmentation du courant **********
           volt_set=volt_set+40;
           if(volt_set>=1000)

volt_set=1000;
           break;
        case 0b11101111:      // grande augmentation du voltage
           amp_set=amp_set+50;
           if(amp_set>=1000) amp_set=1000;
     

     break;
        case 0b11110111:      // petite augmentation du courant **********
           volt_set=volt_set+4;
           if(volt_set>=1000) volt_set=1000;
           break;
   

    case 0b11111011:      // petite augmentation du voltage
           amp_set=amp_set+1;
           if(amp_set>=1000) amp_set=1000;
           break;
        case 0b11111101:      //

petite reduction du courant *************
           volt_set=volt_set-4;
           if(volt_set<=0) volt_set=0;
           break;
        case 0b11111110:      // petite reduction du

voltage
           amp_set=amp_set-1;
           if(amp_set<=0) amp_set=0;
           break;
        default:              //  plus qu'un bouton pese
           break;
     }
     

for(i=0;i<2;i++) write_eeprom(10+i,*(&volt_set+i));
     for(i=0;i<2;i++) write_eeprom(12+i,*(&amp_set+i));
     delay_ms(350);           // taux de repetition
 

}

  if(flag_low_range<!input(pin_A2))// tester la swich 0-10A   0-1A  et changer la gamme
  {
     flag_low_range=!input(pin_A2);
     amp_set=amp_set/10;
     

write_eeprom(14,flag_low_range);
     for(i=0;i<2;i++) write_eeprom(12+i,*(&amp_set+i));
  }
  if(flag_low_range>!input(pin_A2))
  {
     

flag_low_range=!input(pin_A2);
     amp_set=amp_set*10;
     if(amp_set>1000)amp_set=1000;
     write_eeprom(14,flag_low_range);
     for(i=0;i<2;i++)

write_eeprom(12+i,*(&amp_set+i));
  }

  write_cmd_lcd(128);      // adresse du debut de la 1ere ligne
  if(flag_low_range>0)printf(write_car_lcd,"%02ld,%02ldA SET

%02ld,%1ldV",amp_set/100,amp_set,volt_set/40,volt_set/4);
  else printf(write_car_lcd,"%01ld,%03ldA SET %02ld,%1ldV",amp_set/1000,amp_set,volt_set/40,volt_set/4);
 

SET_PWM1_duty(amp_set);  // amp_set
  SET_PWM2_duty(volt_set); // volt_set
}

//-------------------------------

comparer_Iset_Ilue()
{
 

write_cmd_lcd(198);  // milieu de la 2ie ligne
  if (amp_lue<(amp_set-1)) printf(write_car_lcd," >>> ");
  else printf(write_car_lcd," <<<

");
}

//******************************** Fin des fonctions **************************************
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

ykp

sevgili   ete    bilgini paylaştığınicin cok teşekkürler...

ben de snden projenin "digital power suplay" tüm ndökümanlarını e mailime göndermeni rica edecektim.
gönderirsen cok sevinmirim.    sevgiler saygılar.

digi_ykp@yahoo.com