16F88 için Pot kontrollü çek bırak devresi

Başlatan Melih1802, 08 Ekim 2015, 15:30:08

Melih1802

Potansiyometre den  kontrol edeceğim bir zamanlayıcı ile çek bırak yapmak istiyorum.
Potansiyometre den zamanlanacak süre içresinde çıkış ON 0.5sn, ( çıkış ON süresi sabit değişmiyor )  OFF süresi 60sn olacak şekilde bir program lazım.

Alttaki program üzerinde nasıl bir değişiklik yapmam lazım ki istediğimi yaptırabileyim.
Kodlar 16F88 için olacak.

Edit: Potansiyometre ile OFF zamanı kontrol edilecek.

@ DEVICE pic12F675 'işlemci 16F628
@ DEVICE pic12F675, WDT_ON              'Watch Dog timer açık
@ DEVICE pic12F675, PWRT_ON             'Power on timer açık
@ DEVICE pic12F675, PROTECT_OFF         'Kod Protek kapalı
@ DEVICE pic12F675, MCLR_off            'MCLR pini kullanılMIYOR.
@ DEVICE pic12F675, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak

DEFINE OSCCAL_1K 1  

DEFINE OSC 4

DEFINE ADC_BITS 10    ' ADCIN resolution  (Bits)
DEFINE ADC_SAMPLEUS 10 ' ADC sampling time (uSec)

CMCON = 7
ANSEL = %00010011
ADCON0=%10000000
GPIO=0
TRISIO=%00000001
WPU=0

HAM    VAR WORD
SYMBOL CIKIS=GPIO.5
GOSUB ADCAL
PAUSE 200

BASLA:
    gosub adcal
    PWM CIKIS,HAM,3
    GOTO BASLA

ADCAL:
      ADCIN 0,HAM
      RETURN</pre>

ferit06


"Potansiyometre den zamanlanacak süre içresinde çıkış ON 0.5sn, ( çıkış ON süresi sabit değişmiyor )  OFF süresi 60sn olacak şekilde bir program lazım."

Bu kısım anlaşılır değil, 0.5 sn ON 60 sn OFF diyorsunuz. Pot ile hangi süreyi değiştirmek istiyorsunuz? Pot ile değişecek olan maksimum 60 sn olacak şekilde OFF süresi mi?

Melih1802

Pot ile sadece OFF süresini değiştirmek istiyorum.

ferit06

protonda yazıldı, buna benzer yapabilirsiniz.
Device 16F88
'@ DEVICE pic16F88'işlemci 16F88
'@ DEVICE pic16F88, WDT_ON              'Watch Dog timer açık
'@ DEVICE pic16F88, PWRT_ON             'Power on timer açık
'@ DEVICE pic16F88, PROTECT_OFF         'Kod Protek kapalı
'@ DEVICE pic16F88, MCLR_off            'MCLR pini kullanılMIYOR.
'@ DEVICE pic16F88, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak

'DEFINE OSCCAL_1K 1 

Config   intrc_osc_noclkout, MCLRe_Off, WDTE_ON, PWRTE_ON, CP_OFF, CPD_OFF,  ' dahili
#define ADC_BITS 10
#define ADC_CLOCK 3
#define ADC_SAMPLEUS 10
'DEFINE OSC 4

'DEFINE ADC_BITS 10    ' ADCIN resolution  (Bits)
'DEFINE ADC_SAMPLEUS 10 ' ADC sampling time (uSec)

CMCON = 7
ANSEL = %00000001
ADCON0=%10000000
PORTB.1=0
TRISA=%00000001   ' POT PORTA.1 e bağlanacak
TRISB=0
'WPU=0
Dim Ham As Dword
Dim aaa As Dword

Symbol CIKIS=PORTB.0
GoSub ADCAL
PAUSE 200

BASLA:
     GoSub ADCAL
     aaa=60*Ham
     CIKIS=0
     DelayMS aaa
     CIKIS=1
     DelayUS 500
     GoTo BASLA

ADCAL:
      ADCIN 0,Ham
      Return
End

JOKERAS

Selam,

Değişik algoritmalarla yapılır.
En basiti bir Adc ile pot'u okursunuz
butona bastığınızda Çıkış ON olur aynı zamanda döngü bloğuna girer
Adc'den elde edilen değeri döngüye sokarsınız döngü bitince bloktan
çıkar OFF olur.



Melih1802

#5
Alıntı yapılan: JOKERAS - 08 Ekim 2015, 20:45:52
Selam,

Değişik algoritmalarla yapılır.
En basiti bir Adc ile pot'u okursunuz
butona bastığınızda Çıkış ON olur aynı zamanda döngü bloğuna girer
Adc'den elde edilen değeri döngüye sokarsınız döngü bitince bloktan
çıkar OFF olur.




Yapmak istediğimde POT sürekli okunacak ve POT değişiminde zamanda eş zamanlı değişecek. 2. bir onaya gerek olmayacak.

mesaj birleştirme:: 08 Ekim 2015, 21:27:37

Alıntı yapılan: ferit06 - 08 Ekim 2015, 17:15:43
protonda yazıldı, buna benzer yapabilirsiniz.
Device 16F88
'@ DEVICE pic16F88'işlemci 16F88
'@ DEVICE pic16F88, WDT_ON              'Watch Dog timer açık
'@ DEVICE pic16F88, PWRT_ON             'Power on timer açık
'@ DEVICE pic16F88, PROTECT_OFF         'Kod Protek kapalı
'@ DEVICE pic16F88, MCLR_off            'MCLR pini kullanılMIYOR.
'@ DEVICE pic16F88, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak

'DEFINE OSCCAL_1K 1 

Config   intrc_osc_noclkout, MCLRe_Off, WDTE_ON, PWRTE_ON, CP_OFF, CPD_OFF,  ' dahili
#define ADC_BITS 10
#define ADC_CLOCK 3
#define ADC_SAMPLEUS 10
'DEFINE OSC 4

'DEFINE ADC_BITS 10    ' ADCIN resolution  (Bits)
'DEFINE ADC_SAMPLEUS 10 ' ADC sampling time (uSec)

CMCON = 7
ANSEL = %00000001
ADCON0=%10000000
PORTB.1=0
TRISA=%00000001   ' POT PORTA.1 e bağlanacak
TRISB=0
'WPU=0
Dim Ham As Dword
Dim aaa As Dword

Symbol CIKIS=PORTB.0
GoSub ADCAL
PAUSE 200

BASLA:
     GoSub ADCAL
     aaa=60*Ham
     CIKIS=0
     DelayMS aaa
     CIKIS=1
     DelayUS 500
     GoTo BASLA

ADCAL:
      ADCIN 0,Ham
      Return
End


CSS C de derlenebilirmi.

mesaj birleştirme:: 08 Ekim 2015, 21:53:23

Şemam bu. Buna göre yukarıdaki programı nasıl düzenleyebilirim.


omenek

O zamanda bir timeri start darbesiyle temizlersin timer içeriğini adc değeriyle sürekli karşılaştırırsın eşit olunca yapmak istediğin şeyi yaparsın.

RaMu

#7
http://www.mediafire.com/download/vhvdacczo2noc5p/16F88PotileZaman.rar

Biraz kontrol edilmesi lazım ama istediğin işi yapıyor.
(02 nolu proje)
Proteus8.2 simulasyonunuda ekledim.

mesaj birleştirme:: 09 Ekim 2015, 00:07:54

main
/* Açıklamalar
yazar: RaMu || ucanel@outlook.com
derleyici: CcsC 5.025
08.10.2015

Amaç:
RA0 pinine pot bağlı
RB0 pinine led bağlı,
led 0,5 saniye yanacak ve
pot ile belirlenen süre kadar sönük kalacak,
pot ile belirlenecek maksimum sönük kalma süresi 60 saniye olacak.

Yöntem:
timer1 ile her 524 ms de bir kesme alınıyor,
adc dönüşümü tamamlandı kesmesi kullanılıyor.

ADC 16 bit sola yatık değer verecek şekilde ayarlandı,
yani en büyük değer 65535, en küçük değer 0,
öyleyse
60 saniye için pot dan adc ile 65535 okunması lazım,
0 saniye için pottan adc ile 0 okunması lazım,
60 saniye 60000 milisaniyedir,
adc ile okunan en büyük değer 65535 
sistemi matematiksel hesaplardan kurtarmak için
maksimum ayar süresine 65,535 saniye diyelim,
yani ADC den okunan değer kadar milisaniye OFF olarak bekleyeceğiz.
Timer ile 1 milisaniye kesme kuralım,
adc den okunan değeri timer kesmesi içinde işleme sokup ledi sönük tutalım,

bu değeri kontrol amaçlı lcd de gösterelim.
*/

#include <main_16F88_pot_zaman_02.h>
#include <pot_zaman_02_ekler.c>
#include <interrupts_02.c>
#include <pot_zaman_02_flex_lcd.c>



void main()
{
   setup_adc_ports(sAN0);
   setup_adc(ADC_CLOCK_DIV_64);
   setup_timer_2(T2_DIV_BY_16,64,1);      //1,0 ms overflow, 1,0 ms interrupt

delay_ms(100);
lcd_init();

   enable_interrupts(INT_AD);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);


set_adc_channel(0);
delay_ms(100);
read_adc(ADC_START_ONLY); //adc okumayı (sadece) başlat, int_ad de değeri okuyacağız

   printf(lcd_putc,"\fOffSuresi: %05lu\nKalan:    %05lu"pot_okunan,led_off_zaman);
   while(TRUE)
   {
   lcd_gotoxy(11,1);
   printf(lcd_putc,"%6.3w"pot_okunan);
   
   lcd_gotoxy(11,2);
   printf(lcd_putc,"%6.3w"led_off_zaman);
   //delay_ms(50);
   }

}


kesme
#INT_AD
void  AD_isr(void) 
{


pot_okunan = read_adc(ADC_READ_ONLY); //adc den gelen değeri (sadece) oku

   if(pot_okunan != pot_eski_okunan)
   {
   led_off_zaman = pot_okunan;
   pot_eski_okunan = pot_okunan;
   }



}

#INT_TIMER2
void  TIMER2_isr(void) 
{
set_timer2(0UL); //timer2 sıfırla, (aslında taştığı için gerek yoktur kendi sıfıra döner)

if( adc_done() ) read_adc(ADC_START_ONLY); //adc okumayı (sadece) tekrar başlat

   if(led_off_zaman == 0UL)
   {
   led_on_zaman--;
      if(led_on_zaman == 0)
      {
      output_low(led_pin);
      led_off_zaman = pot_okunan;
      led_on_zaman = LEDONSURESI;
      }
      else
      {
      output_high(led_pin);
      }
      
      
   }
   
   else
   {
   led_off_zaman--;
   }
}


ekler
//pin tanımlamaları
//lcd pinleri lcd kütüphanesinde tanımlı
#define led_pin  pin_B0

//pin tanımlamaları son


//sabitler
#define  LEDONSURESI 500 //milisaniye cinsinden ledin yanık kalma süresi

//sabitler son

//Makrolar

//Makrolar son




//Global değişkenler


unsigned int16 pot_okunan=0 ,pot_eski_okunan=0, led_off_zaman=0, led_on_zaman=LEDONSURESI;

//Gloabal değişkenler son


//Fonksiyon Prototipleri


//Fonksiyon Prototipleri son


flex_lcd.c
//Buradaki ayar bendeki Deneme Kartina göredir, istenilirse baska Pinlere cevrilebilinir.
#define LCD_DB4   PIN_B4 
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6 
#define LCD_DB7   PIN_B7 

#define LCD_E     PIN_b2
#define LCD_RS    PIN_b3

//#define LCD_RW    PIN_A7 //Bendeki Deneme Kartinda LC_RW PIC'in GND Pinine bagli.Bu nedenle bu satiri iptal ediyoruz...
//#define USE_LCD_RW   1   // Ayni sebepden bu satirida iptal ediyoruz !!    

//======================================== 

#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines 
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line 


int8 const LCD_INIT_STRING[4] = 
{ 
 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots 
 0xc,                    // Display on 
 1,                      // Clear display 
 6                       // Increment cursor 
 }; 
                              

//------------------------------------- 
void lcd_send_nibble(int8 nibble) 
{ 
// Note:  !! converts an integer expression 
// to a boolean (1 or 0). 
 output_bit(LCD_DB4, !!(nibble & 1)); 
 output_bit(LCD_DB5, !!(nibble & 2));  
 output_bit(LCD_DB6, !!(nibble & 4));    
 output_bit(LCD_DB7, !!(nibble & 8));    

 delay_cycles(1); 
 output_high(LCD_E); 
 delay_us(2); 
 output_low(LCD_E); 
} 

//----------------------------------- 
// This sub-routine is only called by lcd_read_byte(). 
// It's not a stand-alone routine.  For example, the 
// R/W signal is set high by lcd_read_byte() before 
// this routine is called.      

#ifdef USE_LCD_RW 
int8 lcd_read_nibble(void) 
{ 
int8 retval; 
// Create bit variables so that we can easily set 
// individual bits in the retval variable. 
#bit retval_0 = retval.0 
#bit retval_1 = retval.1 
#bit retval_2 = retval.2 
#bit retval_3 = retval.3 

retval = 0; 
    
output_high(LCD_E); 
delay_cycles(1); 

retval_0 = input(LCD_DB4); 
retval_1 = input(LCD_DB5); 
retval_2 = input(LCD_DB6); 
retval_3 = input(LCD_DB7); 
  
output_low(LCD_E); 
    
return(retval);    
}    
#endif 

//--------------------------------------- 
// Read a byte from the LCD and return it. 

#ifdef USE_LCD_RW 
int8 lcd_read_byte(void) 
{ 
int8 low; 
int8 high; 

output_high(LCD_RW); 
delay_cycles(1); 

high = lcd_read_nibble(); 

low = lcd_read_nibble(); 

return( (high<<4) | low); 
} 
#endif 

//---------------------------------------- 
// Send a byte to the LCD. 
void lcd_send_byte(int8 address, int8 n) 
{ 
output_low(LCD_RS); 

#ifdef USE_LCD_RW 
while(bit_test(lcd_read_byte(),7)) ; 
#else 
delay_us(60);  
#endif 

if(address) 
   output_high(LCD_RS); 
else 
   output_low(LCD_RS); 
      
 delay_cycles(1); 

#ifdef USE_LCD_RW 
output_low(LCD_RW); 
delay_cycles(1); 
#endif 

output_low(LCD_E); 

lcd_send_nibble(n >> 4); 
lcd_send_nibble(n & 0xf); 
} 

//---------------------------- 
void lcd_init(void) 
{ 
int8 i; 

output_low(LCD_RS); 

#ifdef USE_LCD_RW 
output_low(LCD_RW); 
#endif 

output_low(LCD_E); 

delay_ms(15); 

for(i=0 ;i < 3; i++) 
   { 
    lcd_send_nibble(0x03); 
    delay_ms(5); 
   } 

lcd_send_nibble(0x02); 

for(i=0; i < sizeof(LCD_INIT_STRING); i++) 
   { 
    lcd_send_byte(0, LCD_INIT_STRING[i]); 
    
    // If the R/W signal is not used, then 
    // the busy bit can't be polled.  One of 
    // the init commands takes longer than 
    // the hard-coded delay of 60 us, so in 
    // that case, lets just do a 5 ms delay 
    // after all four of them. 
    #ifndef USE_LCD_RW 
    delay_ms(5); 
    #endif 
   } 

} 

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

void lcd_gotoxy(int8 x, int8 y) 
{ 
int8 address; 

if(y != 1) 
   address = lcd_line_two; 
else 
   address=0; 

address += x-1; 
lcd_send_byte(0, 0x80 | address); 
} 

//----------------------------- 
void lcd_putc(char c) 
{ 
 switch(c) 
   { 
    case '\f': 
      lcd_send_byte(0,1); 
      delay_ms(2); 
      break; 
    
    case '\n': 
       lcd_gotoxy(1,2); 
       break; 
    
    case '\b': 
       lcd_send_byte(0,0x10); 
       break; 
    
    default: 
       lcd_send_byte(1,c); 
       break; 
   } 
} 

//------------------------------ 
#ifdef USE_LCD_RW 
char lcd_getc(int8 x, int8 y) 
{ 
char value; 

lcd_gotoxy(x,y); 

// Wait until busy flag is low. 
while(bit_test(lcd_read_byte(),7));  

output_high(LCD_RS); 
value = lcd_read_byte(); 
output_low(lcd_RS); 

return(value); 
} 
#endif
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Melih1802

@RaMu Tam olarak istediğim buydu.
Bir isteğim daha olacak ON-OFF sürelerinde ayar yapmam için neredeki değerleri değiştirmem gerekecek.

RaMu

Programı incele mantığını çözmeye çalış, takıldığın yerlerde yardımcı olurum.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html