pcbway

Pic çıkışından ayarlanabilir gerilim üretmek

Başlatan anti_cheist, 06 Kasım 2013, 13:28:00

anti_cheist

arkadaşlar merhaba,

    Bir projenin başlangıç aşaması olarak PİC denitleyicisine dışardan bir pot vasıtası ile 0-5 V gerilim girip,gerilimle oynadıkça bunu % şeklinde 4x16 ekranımda görebiliyorum.Yapmam gereken bu giriş gerilimini( örneğin %50\'de 2.5 V) picin başka bir pininden çıkış almak.Bunu da pot değeri %50 olur olmaz hemen almak değil de :(  ayarlanabilir bir süre zarfında çıkışa vermek örneğin pot %50 de iken 3 saniye boyunca artarak 2.5 volta  ulaştırmak.
inşallah anlatabilmişimdir arkadaşlar yardımcı olursanız çok sevinirim..
iyi günler..

pwm.c

Hangi programlama dilini kullanıyorsun? buda önemli.
daha önceleri bu forumda birisi için benzer bir uygulama hazırlamıştım. belki sana fikir verebilir.
https://elektronikprojeler.com/index.php/topic,3203.msg13772.html#msg13772
_/\/\/\_ -[ı- -ı>|- -|ı|ı|ı- -ı< -||- -l[]l-

anti_cheist

Alıntı yapılan: pwm.c - 06 Kasım 2013, 14:52:39Hangi programlama dilini kullanıyorsun? buda önemli.
daha önceleri bu forumda birisi için benzer bir uygulama hazırlamıştım. belki sana fikir verebilir.
https://elektronikprojeler.com/index.php/topic,3203.msg13772.html#msg13772
pwm.c hocam cevabınız için teşekkürler ben de ccs c ile yazıyorum yazılımınızı epeyce inceledim ve uyarlamaya çalıştım ancak compiler derlemesine rağmen çıkış gerilimi 0 v gözüküyor.
bir de siz pwm ile timer2 kullanmamışsınız.
setup_timer_2(T2_DIV_BY_16,250,1); // Timer2 ayarları yapılıyor        timer2 yi kullanmadan nasıl oldu?

acil cevaplayabilirseniz çok sevinirim..

pwm.c

elbette pwm kullandım ama pwm komutu ile değil. 10 bit pwm için bazı registerlere değer vermem gerekiyordu ve bende ilgili registerlerin atamasını yaparak pwm çıkışını bununla ayarladım.

#byte CCPR1L = 0x15
#byte CCP1CON = 0x17 
#bit CCP1CONY = 0x17.4
#bit CCP1CONX = 0x17.5
_/\/\/\_ -[ı- -ı>|- -|ı|ı|ı- -ı< -||- -l[]l-

anti_cheist

Alıntı yapılan: pwm.c - 06 Kasım 2013, 18:36:18elbette pwm kullandım ama pwm komutu ile değil. 10 bit pwm için bazı registerlere değer vermem gerekiyordu ve bende ilgili registerlerin atamasını yaparak pwm çıkışını bununla ayarladım.

#byte CCPR1L = 0x15
#byte CCP1CON = 0x17 
#bit CCP1CONY = 0x17.4
#bit CCP1CONX = 0x17.5
peki bu kullandığınız kodlar 16f876 ya mı ait ben 18f4620 ye de aynı şeyi yaparak çıkış elde edebilirmiyim? burada çıkış port/pini sizin pic\'inize göre farklı.bu durumda ne yapmak gerekir?

pwm.c

06 Kasım 2013, 23:24:25 #5 Son düzenlenme: 06 Kasım 2013, 23:26:56 pwm.c
ccs derleyicisinde herzaman register kullanmaya gerek yoktur. bu isteğe bağlı bişey.
şu hazırladığım örnekte 18f4620 entegresiyle 10bit pwm ürettim. ADC ile gerilim okunuyor ve pwm e dönüştürülüyor. değerler ise LCD ekranda görünür.

#include <18F4620.h>
#device ADC=10

#FUSES NOWDT               
#FUSES WDT128                 
#FUSES NOBROWNOUT             
#FUSES NOLVP                 
#FUSES NOXINST                 
#FUSES NOMCLR

#use delay(crystal=4000000)
#define LCD_ENABLE_PIN PIN_D3
#define LCD_RS_PIN PIN_D1
#define LCD_RW_PIN PIN_D2
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7

#include <lcd.c>

void main()
{
   int16 kanal0=0;
   float volt=0;
   setup_adc_ports(AN0_TO_AN1);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_timer_2(T2_DIV_BY_16,255,2);     
   setup_ccp1(CCP_PWM);
   set_pwm1_duty((int16)0);
   lcd_init();

   while(TRUE)
   {
    set_adc_channel(0);
    delay_ms(10);
    kanal0= read_adc();
    set_pwm1_duty(kanal0);
    volt=kanal0+1;
   volt=(volt * 5 )/1024;
   lcd_gotoxy(1,1);
   printf(lcd_putc,\" ADC=%lu   \\n VOLT=%1.2f   \",kanal0,volt,);
   delay_ms(100);   
   }

}
_/\/\/\_ -[ı- -ı>|- -|ı|ı|ı- -ı< -||- -l[]l-

anti_cheist

#include <18F4620.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT                //Code not protected from reading
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV21                   //Brownout reset at 2.1V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled


#use delay(clock=8000000)

#include <LCD.C>

#define frek pin_c0
#define volt pin_c1
#define menu pin_c3
#define LCD_TYPE 2
#define kanal0 pin_a0;

long i,f=0;
long hiz=0;
unsigned long int dijital;
float a;
int yuzde;
int k;



#priority TIMER0,EXT

#int_TIMER0
void  TIMER0_isr(void)
{
set_timer0(57724);
f=i;
i=0;
}

#int_EXT
void  EXT_isr(void)
{
i++;
}

void frekans()
{
   printf(lcd_putc,\"\\f  frekansmetre\");
   lcd_gotoxy(1,2);
   printf(lcd_putc,\"frekans= %lu \",f);
   
   while(1)
   {
   lcd_gotoxy(10,2);
   printf(lcd_putc,\"%lu\",f);
   if(input(menu))
   {
   delay_ms(15);
   break;
   }
   }

}

void voltaj()
{
printf(lcd_putc,\"\\f\");

while(1)
{
set_adc_channel(0);
delay_us(50); //muhakkak verilmeli

  dijital=read_adc();

  a=0.0048828125*dijital;

   
lcd_gotoxy(1,1);
printf(lcd_putc,\"     deneme\");

yuzde=a*20;
lcd_gotoxy(1,2);

printf(lcd_putc,\"Guc =%%%d\",yuzde);

if(input(menu))
  {
  delay_ms(15);
  break;
  }
 
}
}




void secimmenusu()
{
menubasi:
    printf(lcd_putc,\"\\f1.Frekans Degeri\");
    printf(lcd_putc,\"\\n2.Voltaj Yuzdesi\");
    while(1)
    {
   if(input(frek))
   {
   delay_ms(15);
   frekans(); goto menubasi;   
   }
   if(input(volt))
   {
   delay_ms(15);
   voltaj(); goto menubasi;
   }
   if(input(menu))
   {
   delay_ms(15);
   goto menubasi;
   }

}
}

void anasayfa()

{
  for(k=1;k<25;k++)
  {
   lcd_init();
   lcd_gotoxy(k,1);
  printf(lcd_putc,\"   deneme\\n   PROJE DENEME\");
  lcd_send_byte(0,0x14);
  delay_ms(25);
}


}

void main()
{
   lcd_init();



   setup_adc_ports(AN0_TO_AN1);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
   set_timer0(57724);
   setup_timer_1(T1_DISABLED);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   
   set_tris_c(0b11010000);// pin_C2 Pwm çıkışı olarak ayarlandı.
   set_tris_a(0b10000000); //pin_A0 giriş olarak alındı.
   
   setup_timer_2(T2_DIV_BY_16,255,2);     
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(dijital);
   
   
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   lcd_init();
   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_8MHZ|OSC_TIMER1|OSC_31250|OSC_PLL_OFF);
   
   anasayfa();
   secimmenusu();
   
   lcd_init();
   while(1)
   
   {
    set_pwm1_duty(dijital);
    delay_ms(100);     
   }
   
     
   
}


hocam ne yaptıysam bir türlü olmuyor.ben burada ayrı bir pinden frekans ölçerken adc ile de gerilimi gösteriyorum.ancak çıkış gerilimi ? olmadı.% şeklinde giriş gerilimini gösteriyordum tam doğru bir şekilde şimdi o da bozulmaya başladı.
yardımlarınızı bekliyorum

pwm.c

yazılımın tamamen mantık hatası dolu.

1- öncelikle a portlarının hepsini giriş yap:
set_tris_a(0b11111111);
analog girişi çıkış olarak ayarlarsan elbette sorun yaşarsın.

2- pwm ayarı için bir döngü yapmışın ama bu sonsuz döngü olarak kalmış ve buraya ne girmişin nede çıkmışın.
while(1)   
   {
    set_pwm1_duty(dijital);
    delay_ms(100);     
   }
adc ile okuduğun değeri buraya taşımassan elbette çıkış alamassın.
set_pwm1_duty(dijital); komutunu void voltaj() fonsiyonun içine biryere yerleştir.
eğerki voltajın zamanla artmasını istiyorsan ozaman araya for döngüsü koyarsın ve bir değişken atayıp döngü boyunca 1 arttırırsın taki digital değişkenine eşit olana kadar. döngü içine birde gecikme koymalısın ama bu gecikme sabit değerli olmayacak. digital sonuçla orantılı olmalı ama pwm çözünürlüğü 1023 olduğu için sana kısıtlı bir imkan veriyor. örneğin 0...5v arası 1 saniyede arttırmakla 0...1v arasını 1 saniyede arttırmak aynı olmaz. 0...1v arası için döngü içindeki gecikmeyi daha uzun tutman gerekecek ve buda çalışmayı etkileyebilir.

3- çok önemli bir hata değil ancak C ile yazılım yazarken asla GOTO komutunu kullanma.

4-  PIC ile frekansmetre, ampermetre ve voltmetre gibi ölçüm cihazları yapmak pek akıllıca iş değil. elde ettiğin sonuçlarda çok sapma oluşabilir. genelde bu tür işler hazır modüllerle yapılır ama bunları piyasada bulmak biraz sıkıntılı. eğerki göstermelik bir devre yapıyorsan ozaman hassasiyet aramamayabilirsin.
_/\/\/\_ -[ı- -ı>|- -|ı|ı|ı- -ı< -||- -l[]l-