7 segment display doğru çalışmıyor

Başlatan Ramazans, 05 Temmuz 2024, 11:36:39

Ramazans

AŞAĞIDA VERMİŞ OLDUĞUM DEVRE VE KODLAR
bu kodlara göre swicli bir proje yapmamız istendi ama swiclerde 121 sayısı doğru çalışırken diğerleri bazen çalışıyor bazen çalışmıyor kafasına göre takılıyor bu yüzden yardım istiyorum.
bazı satırlardan sonra ek bilgiler yazılı ama ben gene anlamadım.

#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000) 


// 7 segment display için segment bağlantıları
#define SEG_A PIN_B1
#define SEG_B PIN_B2
#define SEG_C PIN_B7
#define SEG_D PIN_B6
#define SEG_E PIN_B5
#define SEG_F PIN_B3
#define SEG_G PIN_B4

// Display pozisyonları
#define POS_HUNDREDS PIN_D5
#define POS_TENS    PIN_D6
#define POS_UNITS    PIN_D7

// Fonksiyon prototipleri
void displayDigit(int digit, char position);
void showNumber(int number);

volatile unsigned long timer0_millis = 0;

#INT_TIMER0
void TIMER0_isr(void) {
    ++timer0_millis; // Timer0 kesmesi her 1 ms'de bir çağrılır
    set_timer0(6); // Timer0'ı yeniden yükleyin
}

unsigned long millis() {
    return timer0_millis;
}

void main() {
    // Port konfigürasyonları
    set_tris_b(0x00); // PORTB çıkış olarak ayarlandı
    set_tris_d(0xFF); // PORTD giriş olarak ayarlandı
    set_tris_c(0xFF); // PORTC giriş olarak ayarlandı
    set_tris_a(0x00); // PORTA çıkış olarak ayarlandı

    setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256); // Timer0'ı yapılandırın
    set_timer0(6); // Timer0 başlangıç değeri (1 ms için ayarlayın)
    enable_interrupts(INT_TIMER0);
    enable_interrupts(GLOBAL);

    int currentNumber = 0;
    int switchPressed = -1;

    while (true) {
        if (input(PIN_D0)) {
            currentNumber = 0; // 000 olarak yazınca sadece birler basamağı yanıyor
        } else if (input(PIN_D4)) {
            currentNumber = 121;
        } else if (input(PIN_C7)) {
            currentNumber = 242;
        } else if (input(PIN_D2)) {
            currentNumber = 363; // 017 yazarak üç basamağı da gösterecek şekilde düzeltildi
        } else if (input(PIN_D3)) {
            currentNumber = 484;
        } else if (input(PIN_C4)) {
            currentNumber = 176;
        } else if (input(PIN_C5)) {
            currentNumber = 347;
        } else if (input(PIN_C6)) {
            currentNumber = 518;
        } else if (input(PIN_D1)) {
            currentNumber = 689;
        } else {
            currentNumber = 0; // Varsayılan durumda 000 olarak ayarlandı
        }

        showNumber(currentNumber);

        delay_ms(5); // Kısa bir bekleme süresi ekliyoruz
    }
}

void displayDigit(int digit, char position) {
    unsigned char segments[] = {
        0b00111111, // 0
        0b00000110, // 1
        0b01011011, // 2
        0b01001111, // 3
        0b01100110, // 4
        0b01101101, // 5
        0b01111101, // 6
        0b00000111, // 7
        0b01111111, // 8
        0b01101111  // 9
    };

    unsigned char mask = segments[digit];
    // Segmentleri PORTB'ye ata
    output_bit(SEG_A, (mask >> 0) & 1);
    output_bit(SEG_B, (mask >> 1) & 1);
    output_bit(SEG_C, (mask >> 2) & 1);
    output_bit(SEG_D, (mask >> 3) & 1);
    output_bit(SEG_E, (mask >> 4) & 1);
    output_bit(SEG_F, (mask >> 5) & 1);
    output_bit(SEG_G, (mask >> 6) & 1);

    // Display seçim pinlerini aktif et
    output_bit(POS_HUNDREDS, position == POS_HUNDREDS);
    output_bit(POS_TENS, position == POS_TENS);
    output_bit(POS_UNITS, position == POS_UNITS);

    delay_us(100); // LED yanma süresi olarak 100us ekledik

    // Displayleri kapat
    output_low(POS_HUNDREDS);
    output_low(POS_TENS);
    output_low(POS_UNITS);
}

void showNumber(int number) {
    int hundreds = number / 100;
    int tens = (number / 10) % 10;
    int units = number % 10;

    for (int i = 0; i < 50; i++) { // Döngü sayısını artırarak her basamağı daha uzun süre gösteriyoruz
        displayDigit(hundreds, POS_HUNDREDS);
        displayDigit(tens, POS_TENS);
        displayDigit(units, POS_UNITS);
    }
}

mehmet

#1
showNumber(int number) fonksiyonuna her girdiğinizde bir haneyi gösterin. "switch", "case" ve "static" bu konuda size yardımcı olacaktır.
Ayrıca timer kesmesini boşuna yapmışsınız. Madem kesmeyi yaptınız, display gösterme kısmını timer kesmesi ile yapınız.

Ek:
İşinize yarar umarım: https://www.mehmetbilgi.net.tr/genel-amacli-voltmetre/
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr
CC BY

Ramazans


mehmet

Ne yapmamızı istersin?
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr
CC BY

temha43

senaryonu tam olarak söylersen pbp de yazabilirim belki girişleri pull up veya puldown direnci taktınmı.

ete

Şema ile program bir biri ile uyumsuz.
Uyumsuz olan yerleri açıklayayım sen önce bunları düzelt. Ancak mesajlara cevap verme şekline bakılırsa bu işten hiç anlamıyorsun ve benimde anlamadığım bu güne kadar ne yaptında bu kadar cahil kaldın acaba. !!!!

Bu sitede yardım isteyenlere yardım etmeye çalışıyoruz ve ediyoruz da. Ancak sıfırdan hiç bir zaman kod vermiyoruz. Çünki bu yardım olmuyor bana göre tembelliğe teşvik primi oluyor. Bu nedenle işin bir ucundan tutmayana yardım yok maalesef.
Gelelim uyumsuluklara,
- Şemaya PORTC ye bakılır ise ilk üç pini boşa duruyor. Bu durumda Programda TRISC tanımlaması ;0xFF şeklinde olmamalı. Ne olmalı dersen 0b11111000 yada 0xF8 şeklinde olmalı.
- Benzer şekilde Şema da PORTD ye bakılacak olur ise ilk (sıfır nolu) biti boş bırakılmış. Sonra takip eden pinlere 4 adet toggle switch bağlanmış ve en sonda da 3 pin displayin ortak katod pinlerini sürmek amacı ile kullanılmış Bu durumda programda TRISD registeri için verilmiş olan 0xFF değeride yanlış olmuş demektir. Doğrusu 0b00011110 yada 0x1E şeklinde olmalı idi.

- Şema da PORTD.0 pininin boşa bırakıldığını görebiliyoruz. O halde bu pinin program içinde kullanılmaması gerekmezmi. Ama programda tuş kontrolüne bakınca;
if (input(PIN_D0))  şeklindeki ifade de D0 pininin test edildiğini görüyoruz. Bu olmamalı.

- Şema da PORTC.3 pinine switch bağlı iken Tuş kontrolünde bu pinin kontrolü yapılmıyor.
  PortC den C4,C5,C6 ve C7 pinlerinin kontrolleri yapılıyor ama C3 yok. Gerçi çalışmaya engel bir durum değil bu. Sadece eksikliği belirtmek amacı ile ikaz ediyorum.

- Mehmet'in de belirttiği gibi bir timer kesmesi ayarlanmasındaki temel amaç displaylerin her kesme oluştuğunda yenilenmesi işleminin yapılması içindir. Sendeki kesme rutini çalışıyor ama orada hiç bir iş yapılmıyor.
Normal şartlarda he 1 ms de bir kesme oluştuğunda gösterilecek sayının bir hanesi gösterilir.
Kesme oluştu ===> yüzler hanesini göster
Yeniden kesme oluştu ===> Onlar hanesini göster
Yeniden kesme oluştu ===>Birler hanesini göster
Bu şekilde döngü devam eder ve her bir hanenin gösterim aralığı 1 ms olduğu için göz bu konuda yanılgıya uğrar ve 3 haneyide yanar şekilde görür bakanlar.
Bence gösterme işini kesme içine almalısın.

Ete



Powered by EzPortal
▲