öncelikle umarım herkesin sağlığı ve işleri yolundadır.
Şuan denemek ve projemin alt yapısını oluşturmak ve biraz da Xc8 in dosya fonksiyon sistemini öğrenmek için bir örnek çalışma yaptım .
yapmak istediğim şu;
Ana Main.c Dosyam içerisine alt 2 adet fonksiyon çağırdım.1
1-) run_led() fonksiyonum butona basıldığı sürece 3 ledi sürekli sıralı olarak yakıp söndüren bir fonksiyondur.
#define _XTAL_FREQ 8000000UL // to perform delay
#include <xc.h> // to perform header
#define BTN PORTBbits.RB0 // PORT B zero leg is connected to BTN
#define led1 PORTBbits.RB1 // PORT B first leg is connected to led1
#define led2 PORTBbits.RB2 // PORT B second leg is connected to led2
#define led3 PORTBbits.RB3// PORT B third leg is connected to led3
char led_state = 1; // define led state initial value as 1
void run_led() {
TRISBbits.TRISB1 = 0; //make led1 output
TRISBbits.TRISB2 = 0; //make led2 output
TRISBbits.TRISB3 = 0; //make led3 output
TRISBbits.TRISB0 = 1; // make BTN input
while(1){
if(BTN == 0){ // If button is pressed
__delay_ms(100); // Wait for contact debouncing 100ms
if(BTN == 0) // If is button is still pressed
led_state++; // incease the led state if button is still pressed(count)
if(led_state == 5) led_state = 1; // if led state =5 turn to 1 again for count
switch(led_state){
case 1: // if led state=1
led1=1; led2=0; led3=0; break; // led1 open
case 2: // if led state=2
led1=0; led2=1; led3=0; break; // led2 open
case 3: // if led state=3
led1=0; led2=0; led3=1; break; // led3 open
case 4: // if led state=4
led1=0; led2=1; led3=0; break; // led2 open
case 5: led1=1; led2=0; led3=0; break; // led1
default: // any time
led1=1; led2=1; led3=1; break; // led1 open in other conditions
}
}
}
}
2-) Seven() Fonksiyonum butona basıldığı sürece 7-segment displayde 0-dan 9 a kadar rakamları yazdıran bir fonksiyondur.
#define _XTAL_FREQ 8000000UL // to perform delay
#include <xc.h> // to perform header
char disp_counter = 0; // define disp_counter initial value as 0
#define BTN PORTBbits.RB0 // PORT B zero leg is connected to BTN
void seven(){
TRISBbits.TRISB0 = 1; // make BTN input
TRISD = 0; // Make PortD output
while(1){
if(BTN == 0){ // If button is pressed
__delay_ms(500); // Wait for contact debouncing 500ms
if(BTN == 0) // If button is still pressed
disp_counter++; // incease the disp_counter if button is still pressed(count)
if(disp_counter == 10) disp_counter = 0; // if disp_counter =10 turn to 0 again for count
switch(disp_counter){
case 0: // if disp_counter=0
PORTD=0b00111111; break; // Show 0 on display
case 1: // if disp_counter=1
PORTD=0b00000110; break; // Show 1 on display
case 2: // if disp_counter=2
PORTD=0b01011011; break; // Show 2 on display
case 3: // if disp_counter=3
PORTD=0b01001111; break; // Show 3 on display
case 4: // if disp_counter=4
PORTD=0b01100110; break; // Show 4 on display
case 5: // if disp_counter=5
PORTD=0b01101101; break; // Show 5 on display
case 6: // if disp_counter=6
PORTD=0b01111101; break; // Show 6 on display
case 7: // if disp_counter=7
PORTD=0b00000111; break; // Show 7 on display
case 8: // if disp_counter=8
PORTD=0b01111111; break; // Show 8 on display
case 9: // if disp_counter=9
PORTD=0b01101111; break; // Show 9 on display
default: // any time
PORTD=0b00111111;break; // Show 0 on display
}
}
if(BTN == 1){PORTD=0b00111111; // If button is not pressed Show 0 on display
}
}
}
Ana Min kodum;
/*
* File: newmain.c
* Author: samed
*
* Created on 03 Haziran 2020 Çar?amba, 18:01
*/
#include <xc.h>
//#include <xc.h>
void run_led(void);
void seven(void);
void main(void) {
TRISBbits.TRISB1 = 0; //make led1 output
TRISBbits.TRISB2 = 0; //make led2 output
TRISBbits.TRISB3 = 0; //make led3 output
TRISBbits.TRISB0 = 1; // make BTN input
TRISD = 0;
while(1){
run_led();
seven();
}
}
istediğim Ana butona bastığımda hem ledler yanıp sönsün hemde displayde rakamlar sıralı olarak değişsin
yani kısacası 2 adet fonksiyonu aynı anda çalıştırmak istiyorum. ama şuan ilk öne hangisini yazdıysam hep o çalışıyor
sorunu çözemedim
Fonksiyonlarımı aynı zamanda iç içe de mi tanımlamam gerekiyor acaba
yada farklı bir yöntemi mi vardır
bilenler lütfen yardımcı olabilir mi ?
(https://i.ibb.co/vBk2DqN/image.png) (https://ibb.co/vBk2DqN)
if(BTN == 0) ları silip
while(BTN ==0) denermisin.
Tek butonla aynı anda sadece birisi çalışır ondan dolayı olabilir.
Alıntı yapılan: serkan - 03 Haziran 2020, 19:43:15if(BTN == 0) ları silip
while(BTN ==0) denermisin.
hemen deneyim hocam
Benim bildigim iki cozum olabilir.
1. Dedigin gibi tek fonksiyon olacak.
2. kesme kullanarak fonksuyonun birini kesme icinde calistiracaksin.
Alıntı yapılan: serkan - 03 Haziran 2020, 19:43:15if(BTN == 0) ları silip
while(BTN ==0) denermisin.
Yok hocam malesef bir değişiklik olmadı
Alıntı yapılan: Endorfin35+ - 03 Haziran 2020, 19:48:46Benim bildigim iki cozum olabilir.
1. Dedigin gibi tek fonksiyon olacak.
2. kesme kullanarak fonksuyonun birini kesme icinde calistiracaksin.
ama tek fonksiyonda bile aynı anda olmuyor hocam
Uzman degilim.
Tavsiye niteliginde, delay kullanma.
En basitinden bir adet sayac adinda long degisken kullan. Sayaci her fonksiyon dungusunde 1 arttir. İslem hizina gore degisecektir ancak soyle bir yapi olusur sayac atiyorum 3000 oldugunda senin istedigin delay kadar sure gecmis olur. Bunuda if ile kontrol edersin. Hatta fonksiyon dongusune sadece tek bir delay ekle 1ms lik. Sayac degerin yaklasik ms deger verir.
Boylece fonksiyonlar bir birini beklemeden islemleri yapar. Fonksiyonlar demek yanlis aslinda sonucta tek bir fonksiyon haline gelecek.
hocam bir yöntem görmüştüm iç içe dosyalama gibi yapıyorlar o şekilde ortak kullanılıyor gibi yapıyorlar.
ama onu da bulamadım.
acaba XC8 ait bir kullanım mı diye sormak istedim
Fonksiyonlarının ikisinin de kendi sonsuz döngüleri var, bu da hiçbir zaman sonlanmayacakları anlamına gelir. Normalde bu şekilde iki fonksiyonu aynı anda çalıştıramazsın. Bu ancak RTOS kullanarak mümkün olabilir. Yapmaya çalıştığın şey RTOS kullanmadan da yapılabilir, ama bu durumda programını iki ayrı fonksiyon olarak yazamazsın.
Alıntı yapılan: Tagli - 03 Haziran 2020, 22:44:18Fonksiyonlarının ikisinin de kendi sonsuz döngüleri var, bu da hiçbir zaman sonlanmayacakları anlamına gelir. Normalde bu şekilde iki fonksiyonu aynı anda çalıştıramazsın. Bu ancak RTOS kullanarak mümkün olabilir. Yapmaya çalıştığın şey RTOS kullanmadan da yapılabilir, ama bu durumda programını iki ayrı fonksiyon olarak yazamazsın.
Peki nasıl yapabilirim hocam?
pekiş o nasıl olcak hocam
Aynı anda çalışması için çift çekirdek bir işlemci gerekir. Ancak timer kesmesi kullanıp zamanlama işlerini timer kesmesi ile yaparak döngüyü hizlandirirsiniz. Başka türlü tek çekirdek işlemci ile mümkün değil.
Fonksiyonları sürekli girip çıkılacak şekilde yazacaksın,
sanki herşeyi if ile yazıyormuşsun gibi düşün.
butona basıldımı, led yanma zamanı doldu mu ... gibi.
Bu mantıkla dene çözüm bulamazsan yardımcı olurum.
Fonksiyonlardaki while (1) leri kaldırıp denenebilir.
void run_led() {
while (BTN == 0){
__delay_ms(100);
disp_counter++; // incease the disp_counter if button is still pressed(count)
if(disp_counter == 10) disp_counter = 0; // if disp_counter =10 turn to 0 again for count
switch(disp_counter){
case 0: // if disp_counter=0
PORTD=0b00111111; break; // Show 0 on display
case 1: // if disp_counter=1
PORTD=0b00000110; break; // Show 1 on display
case 2: // if disp_counter=2
PORTD=0b01011011; break; // Show 2 on display
case 3: // if disp_counter=3
PORTD=0b01001111; break; // Show 3 on display
case 4: // if disp_counter=4
PORTD=0b01100110; break; // Show 4 on display
case 5: // if disp_counter=5
PORTD=0b01101101; //break; // Show 5 on display
led1=1; led2=0; led3=0; break;// led1 open
case 6: // if disp_counter=6
PORTD=0b01111101; //break; // Show 6 on display
led1=0; led2=1; led3=0; break; // led2 open
case 7: // if disp_counter=7
PORTD=0b00000111; //break; // Show 7 on display
led1=0; led2=0; led3=1; break; // led3 open
case 8: // if disp_counter=8
PORTD=0b01111111; //break; // Show 8 on display
led1=0; led2=1; led3=0; break; // led2 open
case 9: // if disp_counter=9
PORTD=0b01101111; //break; // Show 9 on display
led1=1; led2=0; led3=0; break; // led1
default: // any time
PORTD=0b00111111;//break; // Show 0 on display
led1=1; led2=1; led3=1; break; // led1 open in other conditions
}
if(BTN == 1){PORTD=0b00111111; // If button is not pressed Show 0 on display
}
}
}
void main(void) {
nRBPU =0; //PORTB.0 pullup direnci acik
TRISB= 0b00000001; //PORTB.0 giris
TRISD = 0b00000000;
PORTA=0x00; PORTB=0x00; PORTC=0x00; PORTD=0x00; //portlari temizle.
while(1){
run_led();
}
}
yada
void run_led() {
while (BTN == 0){
__delay_ms(100); // Wait
led_state++; // incease the led state if button is still pressed(count)
if(led_state == 5) led_state = 1; // if led state =5 turn to 1 again for count
switch(led_state){
case 1: // if led state=1
led1=1; led2=0; led3=0; break; // led1 open
case 2: // if led state=2
led1=0; led2=1; led3=0; break; // led2 open
case 3: // if led state=3
led1=0; led2=0; led3=1; break; // led3 open
case 4: // if led state=4
led1=0; led2=1; led3=0; break; // led2 open
case 5: led1=1; led2=0; led3=0; break; // led1
default: // any time
led1=1; led2=1; led3=1; break; // led1 open in other conditions
}
disp_counter++; // incease the disp_counter if button is still pressed(count)
if(disp_counter == 10) disp_counter = 0; // if disp_counter =10 turn to 0 again for count
switch(disp_counter){
case 0: // if disp_counter=0
PORTD=0b00111111; break; // Show 0 on display
case 1: // if disp_counter=1
PORTD=0b00000110; break; // Show 1 on display
case 2: // if disp_counter=2
PORTD=0b01011011; break; // Show 2 on display
case 3: // if disp_counter=3
PORTD=0b01001111; break; // Show 3 on display
case 4: // if disp_counter=4
PORTD=0b01100110; break; // Show 4 on display
case 5: // if disp_counter=5
PORTD=0b01101101; break; // Show 5 on display
case 6: // if disp_counter=6
PORTD=0b01111101; break; // Show 6 on display
case 7: // if disp_counter=7
PORTD=0b00000111; break; // Show 7 on display
case 8: // if disp_counter=8
PORTD=0b01111111; break; // Show 8 on display
case 9: // if disp_counter=9
PORTD=0b01101111; break; // Show 9 on display
default: // any time
PORTD=0b00111111;break; // Show 0 on display
}
if(BTN == 1){PORTD=0b00111111; // If button is not pressed Show 0 on display
}
}
}
void main(void) {
nRBPU =0; //PORTB.0 pullup direnci acik
TRISB= 0b00000001; //PORTB.0 giris
TRISD = 0b00000000;
PORTA=0x00; PORTB=0x00; PORTC=0x00; PORTD=0x00; //portlari temizle.
while(1){
run_led();
}
}