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>
"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?
Pot ile sadece OFF süresini değiştirmek istiyorum.
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
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.
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.
(http://s13.postimg.cc/9ila5piir/Ekran_Al_nt_s.jpg) (http://postimg.cc/image/9ila5piir/)
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.
http://www.mediafire.com/download/vhvdacczo2noc5p/16F88PotileZaman.rar (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
@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.
Programı incele mantığını çözmeye çalış, takıldığın yerlerde yardımcı olurum.