-1
\$\begingroup\$

I'm working on make a 4 digit counter starting from 0 to 999. I'm using port D for which digit is gonna be writen and port B for which seven segment number is gonna display.

I'm using 4 digit commond anode display. 330ohm for seven segment number , 10K for transistors and transistors connected to Port D (PD0,PD1,PD2,PD3). I used transistor for decide which digit is gonna be writen. Here is my code down below.

    #include <stdint.h>
#include "inc/lm4f120h5qr.h"

#include "inc/hw_ints.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"

static inline void disable_interrupts() {
    asm("CPSID I");
}

static inline void enable_interrupts() {
    asm("CPSIE I");
}

static inline void wait_for_interrupt() {
    asm("WFI");
}

void init_port_B() {
    volatile unsigned long delay;
    SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOB;
    delay = SYSCTL_RCGC2_R;
    GPIO_PORTB_DIR_R |= 0xFF;
    GPIO_PORTB_AFSEL_R &= ~0xFF;
    GPIO_PORTB_DEN_R |= 0xFF;
}

void init_port_D() {
    volatile unsigned long delay;
    SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOD; // activate port D
    delay = SYSCTL_RCGC2_R;     // allow time for clock to stabilize
    GPIO_PORTD_DIR_R |= 0x0F;   // make PD3-0 out
    GPIO_PORTD_AFSEL_R &= ~0x0F; // regular port function
    GPIO_PORTD_DEN_R |= 0x0F;   // enable digital I/O on PD3-0
}

void init_timer_0(unsigned int period) {
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    TimerLoadSet(TIMER0_BASE, TIMER_A, period);

    IntEnable(INT_TIMER0A);
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

    TimerEnable(TIMER0_BASE, TIMER_A);
}

volatile int flag_ekran_guncelle = 0;

void timer_0_handler() {
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); // clear time interrupt

    flag_ekran_guncelle = 1;
}

void SysTick_Init(unsigned long period) {
    NVIC_ST_CTRL_R = 0;         // disable SysTick during setup
    NVIC_ST_RELOAD_R = period - 1;      // reload value
    NVIC_ST_CURRENT_R = 0;      // any write to current clears it
    NVIC_SYS_PRI3_R = (NVIC_SYS_PRI3_R & 0x00FFFFFF) | 0x40000000; // priority 2
    NVIC_ST_CTRL_R = 0x07; // enable SysTick with core clock and interrupts
    // enable interrupts after all initialization is finished
}

// 1 saniyedeki systick kesmesi sayisi
#define SYSTICK_HZ 100
// baslangictan itibaren olusan systick kesmesi sayisi
uint32_t systick_count = 0;

volatile int flag_sayi_arttir = 0;

void systick_handler() {
    systick_count++;

    // 0.1 saniyede bir sayiyi arttirma flagini 1 yap
    if ((systick_count % (SYSTICK_HZ / 10)) == 0)
     flag_sayi_arttir = 1;
}

// 0'dan 9'a kadar olan sayilarin seven segment kodlari
// bit sirasi: g f e d c b a
uint8_t kodlar[10] = {

        0xC0,
        0XF9,
        0XA4,
        0XB0,
        0X99,
        0X92,
        0X83,
        0XF8,
        0x80,
        0x98
   /*0b0111111,
    0b0000110,
    0b1011011,
    0b1001111,
    0b1100110,
    0b1101101,
    0b1111101,
    0b0000111,
    0b1111111,
    0b1101111*/

};

int ekran_guncelle_no = 0;
void ekran_guncelle(int sayi) {
    ekran_guncelle_no = (ekran_guncelle_no + 1) % 4; // guncellenen ekranin numarasini bir arttir

    if (ekran_guncelle_no == 0) {
     int birler = sayi % 10;
    GPIO_PORTD_DATA_R |= 0b1111; // hepsini kapat
    GPIO_PORTD_DATA_R &= ~0b0001;
    GPIO_PORTB_DATA_R = kodlar[birler];
    // birler basamagini aktiflestir
    } else if (ekran_guncelle_no == 1) {
     int onlar = (sayi / 10) % 10;
    GPIO_PORTD_DATA_R |= 0b1111; // hepsini kapat
    GPIO_PORTD_DATA_R &= ~0b0010;
    GPIO_PORTB_DATA_R = kodlar[onlar];// onlar basamagini aktiflestir
    }if (ekran_guncelle_no == 2) {
     int yuzler = (sayi / 100) % 10;
    GPIO_PORTD_DATA_R |= 0b1111; // hepsini kapat
    GPIO_PORTD_DATA_R &= ~0b0100;
    GPIO_PORTB_DATA_R = kodlar[yuzler];// yuzler basamagini aktiflestir
    } else if (ekran_guncelle_no == 3) {
     int binler = (sayi / 1000) % 10;
    GPIO_PORTD_DATA_R |= 0b1111; // hepsini kapat
    GPIO_PORTD_DATA_R &= ~0b1000;
    GPIO_PORTB_DATA_R = kodlar[binler];// binler basamagini aktiflestir
    }
}

int main() {

    disable_interrupts();
    init_port_B();
    init_port_D();
    init_timer_0(SysCtlClockGet() / 200);
    SysTick_Init(1600000);

    enable_interrupts();

    int sayi = 1234;

    while (1) {
     if (flag_ekran_guncelle == 1) {
         flag_ekran_guncelle = 0;
         ekran_guncelle(sayi);
     }

     if (flag_sayi_arttir == 1) {
         flag_sayi_arttir = 0;
         sayi++;
     }

     wait_for_interrupt();
    }
}

I don't know where is the wrong this code but it is not working well. If you think code was right , it might be electronic connection problem. So, if you think this way please tell me how can I connect 4 digit seven segment to my launchpad correctly.

\$\endgroup\$
  • \$\begingroup\$ Have you managed to blink just blink a single LED, understanding what each line of code does? What toolchain do you use, your program looks a fair bit different from what I would expect. \$\endgroup\$ – jippie Jun 6 '15 at 6:09
  • \$\begingroup\$ It's been a while for me to remember exact details, but some GPIO registers come with a "lock register". You probably want to check the datasheet for those. For example to enable GPIOF I had to fiddle with: ROM_SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOF ); GPIO_PORTF_LOCK_R; GPIO_PORTF_CR_R and GPIO_PORTF_DEN_R. Check the datasheet for details. Try to control each single pin first before trying to control the whole display. The controller you picked is a fairly complex. \$\endgroup\$ – jippie Jun 6 '15 at 6:21
1
\$\begingroup\$

I moved to 2 pin (PD3,PD4) to another pin (PE1,PE2) and changed the code that way. It worked. I don't know why but it works for now very well.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.