ccs c yardım.

xman

Üye
Katılım
9 Eki 2008
Mesajlar
32
Puanları
1
Yaş
40
pottan girdiğim voltajı pwm olarak nasıl alırım? yardım.


Kod:
#include <16f877.h> 
#device ADC=10 
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000) //4 Mhz osilatör hızı 
#include <benim_LCD.c>
#define use_PORTB_lcd TRUE   // LCD B portuna bağlı 

void lcd(void); ////////////////////////////////// 
void adc(void); // Kullanılacak fonksiyonlar tanımlandı // 
void pwm(void); /// /////////////////////////////// 

unsigned long int bilgi; // İşaretsiz 16 bitlik tam sayı tipinde değişken tanımlanıyor
float voltaj;          // ondalıklı tipte voltaj isminde değişken tanıtılıyor

void main() 
{ 
setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
setup_spi(SPI_SS_DISABLED);     // SPI birimi devre dışı
setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı

set_tris_a(0xff);
set_tris_c(0x00);   // C portu komple çıkış

while(true)
{
output_low(pin_c2); // pwm i açıp kapattıktan sonra çıkış değerinin
// +5 de kalması engelleniyor. 

if(input(pin_a0) == 0) lcd(); //porta 1.buton yürüyen ışığa geç 
delay_ms(100); 
if(input(pin_a1) == 0) adc(); // porta 2.buton adc'e geç 
delay_ms(100); 
if(input(pin_a2) == 0) pwm(); 
} 
}
////////////////////////////////lcd fonksiyonu///////////////////////////////
void lcd (void)
{ 
while(true);
{
      lcd_hazirla(); // LCD başlangıç ayarları yaptırılıyor 
      imlec(1,1); // İmlec 1.satır 1.sütunda
      printf(lcd_veri "\fADC_UYGULAMASI"); // LCD'ye yazı yazdırılıyor
      delay_ms(1500);
      lcd_komut(0x01); // LCD sıfırlanıyor
      imlec(1,1); // İmlec 1.satır 1.sütunda
      printf(lcd_veri,"fAN5_Kanali"); // LCD'ye veri 
      delay_ms(1000);
      imlec(2,4); // İmlec 2.satır 4.sütunda
      printf(lcd_veri "\nVoltaj=%fV"voltaj);
      imlec(2,4);
      delay_ms(1000);
      printf(lcd_veri,"\fDijital=%lu"bilgi); // LCD'ye veri yazdırılıyor
      delay_ms(1000);       
      lcd_komut(0x01); // LCD sıfırlanıyor
      lcd_komut(0x0E); // İmleç alt çizgi modunda      
      imlec(1,5); // İmlec 1.satır 5.sütunda
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri," ");
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri,"");delay_ms(500);
      printf(lcd_veri,""),delay_ms(500);
      lcd_komut(0x01); // LCD sıfırlanıyor  
}
}
//////////////////////////adc fonksiyonu////////////////////////////////////
void adc (void)
{ 
setup_adc_ports(ALL_ANALOG);
setup_adc(adc_clock_div_32);

set_adc_channel(5);   // RE0/AN5 ucundaki sinyal A/D işlemine tabi tutulacak
delay_us(20);         // Kanal seçiminde sonra bu bekleme süresi verilmelidir
bilgi=read_adc();     // ADC sonucu okunuyor ve bilgi değişkenine aktarılıyor
voltaj=0.0048828125*bilgi;   // Dijitale çevirme işlemine uğrayan sinyalin gerilimi hesaplanıyor
}



 ////////////////////// /////pwm fonksiyonu //////////////////////////////////
void pwm(void) 
{ 
setup_ccp1(ccp_pwm); //Yakalama modu PWM olarak ayarlandı. 
setup_timer_2(t2_div_by_16, 255,1); //PWM ferakansı ayarlandı 
setup_adc_ports(ALL_ANALOG); 
setup_adc(adc_clock_internal); 
set_adc_channel(0); 
while(true)
{ 
bilgi=read_adc(); 
set_pwm1_duty(voltaj);
}
}
 
Port a yı hem buton, hem de adc girişi yapmışsınız. ALL_Analog yaparak kanal 5 i okutursunuz. Tabi buton koyduğunuz kanallar da analog oldu. Yani devrenizde baya karışıklık var. Butonları genelde portB ye koymak uygundur. Dahili pull up dirençlerinden dolayı. Lcd de d portuna uygun olur.

Programı çok detaylı inceleyemedim ama ilk gördüklerim bunlar.
 
butonları iptal edip kontrol komutları ile kontrol edicem.
önemli olan potansiyometreden girdiğim değeri pwm çıkışından birebir allmak
pwm konusunda doğru yoldamıyım bilmiyorum.
 
pwm duty ayarına ineteger sayı girmeniz gerekir. Siz float girmişsiniz. Ayrıca pwmi 10 bit ayarlarsanız ADC den okuduğunuz değeri doğrudan pwm e verebilirsiniz. Veya adc sinyalini işler sonra pwm e verirsiniz.

Bu tür uygulamalarda integer aritmetiği ile çalışmak daha mantıklıdır. Float aritmetiği işlem sayısının çokluğu nedeniyle yavaştır.
 
ilginiz için teşekkürler.
 
adc kanallarının birinden okunan voltaj değerine Vadc dersek vede PWM'in doluluk oranını X dersek şöyle bir eşitlik olabilir
Vadc=(X/100)*5 bu denklemde Vadc biliniyor senin herhangi bir kanaldan okuduğun değer denklemde yerine koyarsın X'i bulursun bu X de senin pwm'in doluluk oranındır bu şekilde yapıldığında Vadc, pwm çıkışının ortalama değerine eşit olur(5 pwm çıkışının tepedeğeri)
 
denklemlerle ilgili örnek varmı elinizde...
 
Merhaba
Bir önceki cevabımdaki denklemde bir kaç düzeltme yaparsak pwm çözünürlüğün 255 olsun adc çözünürlüğü 10bit, referans voltajı 5v kabul edersek bit başına düşen voltaj yaklaşık (5v/1024) 5mv burdan okuduğun analog değer Vadc=5mv*ikilik değer(adc işlemi sonucu elde ettiğin 10 bitlik sayısal değer) burdan
Vadc=(x/255)*5v burdan x'i çeker ve doğrudan set_pwm1_duty(x) dersin
ama tip konusuna gelince ya tamamı float olarak seçilir sonra sonuç bir integer sayıya aktarılır virgülden sonrası yok sayılarak buda "floor" komutuyla yapılabilir.
 
sağolasın. ben bi uğraşayım.
 
Kod:
#include <16f877.h> 
#device ADC=10 
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000) //4 Mhz osilatör hızı 
#include <lcd.c>

int vadc;
unsigned long int voltaj;
void main() 
{ 
setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
setup_spi(SPI_SS_DISABLED);     // SPI birimi devre dışı
setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı


while(true)
{
lcd:
////////////////////////////////lcd////////////////////////////////////////////
      lcd_init(); // LCD başlangıç ayarları yaptırılıyor 
      lcd_gotoxy(1,1); // İmlec 1.satır 1.sütunda
      printf(lcd_putc "\fADC_UYGULAMASI"); // LCD'ye yazı yazdırılıyor
      delay_ms(1000);
      lcd_putc("\f");//lcd=(0x01); // LCD sıfırlanıyor
      lcd_gotoxy(1,1); // İmlec 1.satır 1.sütunda
      printf(lcd_putc,"fAN5_Kanali"); // LCD'ye veri 
      delay_ms(1000);
      lcd_gotoxy(2,4); // İmlec 2.satır 4.sütunda 
      printf(lcd_putc,"voltaj %d\V",vadc);
      delay_ms(1000);                         
      lcd_putc("\f");// LCD sil
      lcd_gotoxy(1,5); // İmlec 1.satır 5.sütunda
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc," ");
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc,"x");delay_ms(100);
      printf(lcd_putc,"x"),delay_ms(100);
      lcd_putc("\f"); // LCD sil
      
for(;;)
{      
      /////////////////////////////////////////////////////////////
      setup_adc(adc_clock_div_32);
      set_adc_channel(0);   // RE0/AN5 ucundaki sinyal A/D işlemine tabi tutulacak
      delay_us(20);         // Kanal seçiminde sonra bu bekleme süresi verilmelidir
      setup_adc_ports(RA0_ANALOG); 
      setup_ccp1(ccp_pwm); //Yakalama modu PWM olarak ayarlandı. 
      setup_timer_2(t2_div_by_16,255,1); //PWM ferakansı ayarlandı     
      setup_adc(adc_clock_internal);
      enable_interrupts(GLOBAL);
      
      

      voltaj=read_adc();     // ADC sonucu okunuyor ve voltaj değişkenine aktarıl
      //vadc=0.0048828125*voltaj;
      vadc=(voltaj/255)*3.5;
      set_pwm1_duty(voltaj);      
     
goto lcd;
}  
}     
}

arakadas dediğin gibi yaptım . bu sefer pwm gec devreye giriyor lamba yandıktan sonrada
pot u çevirdiğim halde lambada bi değişiklik olmuyor yardım.
 

Forum istatistikleri

Konular
129,846
Mesajlar
930,722
Kullanıcılar
452,701
Son üye
Kerem1453

Yeni konular

Geri
Üst