Код для 4-значного 7-сегментного дисплея: почему код не работает для 2 из 4 цифр? - PullRequest
0 голосов
/ 08 февраля 2019

Я написал 2 функции (gpio_write & gpio_set_function), чтобы иметь возможность управлять цифрами и сегментами 7-сегментного дисплея (общего анодного светодиода), который подключен к моему RPi через биполярные переходные транзисторы: коллектор на общую мощность,база к контактам RPi через резистор 1 кОм и эмиттер для разряда цифровых узлов на дисплее (изображение здесь).

Сегменты подключаются непосредственно к контактам на RPi.

Код успешно высвечивает цифры 1 и 3 (и все сегменты), но цифры 2 и 4 не загораются.Мне нужна помощь, чтобы выяснить, почему это так.

Я дважды и трижды проверил проводку, убедился, что цифры подключены к контактам с 10 по 13 и сегменты к контактам с 20 по 26 (точка для контакта 27).Я также проверил код и не смог найти с ним проблемы.Я также позаботился о том, чтобы каждая из цифр действительно работала, отключившись от RPi и освещая каждый из сегментов каждой цифры независимо (сегмент B цифры 3 сожжен, все остальные работают).

Чтоможет быть еще одна проблема, которая может привести к тому, что цифры 2 и 4 не загораются?Или, возможно, что-то не так с кодом?

#include "timer.h"
#include "gpio.h"

void gpio_set_function(unsigned int pin, unsigned int function) {
  unsigned int mask = 7;
    if ( (pin < GPIO_PIN_FIRST || pin > GPIO_PIN_LAST) || (function < GPIO_FUNC_INPUT || function > GPIO_FUNC_ALT3) )
        ;
    else{
        switch (pin/10){
            case 0:
                *GP_FSEL0 &= ~((mask)<<(3*pin));
                *GP_FSEL0 |= function<<(3*pin);
                break;
            case 1:
                pin = pin%10;
                *GP_FSEL1 &= ~((mask)<<(3*pin));
                *GP_FSEL1 |= function<<(3*pin);
                break;
            case 2:
                pin = pin%20;
                *GP_FSEL2 &= ~((mask)<<(3*pin));
                *GP_FSEL2 |= (function<<(3*pin));
                break;
            case 3:
                pin = pin%30;
                *GP_FSEL3 &= ~((mask)<<(3*pin));
                *GP_FSEL3 |= function<<(3*pin);
                break;
            case 4:
                pin = pin%40;
                *GP_FSEL4 &= ~((mask)<<(3*pin));
                *GP_FSEL4 |= function<<(3*pin);
                break;
            default:
                ;
        }
    }
}

void gpio_write(unsigned int pin, unsigned int value) {
    if ( (pin < GPIO_PIN_FIRST || pin > GPIO_PIN_LAST) || (value < 0 || value > 1) ) ;
    else {
        switch (pin/32){
            case 0:
                if (value==1){
                    *GP_FSET0 &= ~(1<<pin);
                    *GP_FSET0 |=   1<<pin;
                }
                else
                    *GP_CLR0 |= 1<<pin;
                break;
            case 1:
                if (value==1){
                    *GP_FSET1 &= ~(1<<(pin-32));
                    *GP_FSET1 |=   1<<(pin-32);
                }
                else
                    *GP_CLR1 |= 1<<(pin-32);
                break;
            default:
                ;
        }
    }
}

void main(void) {
    volatile int i;
    for(i = 10; i < 14 ; i++)
        gpio_set_function(i, GPIO_FUNC_OUTPUT);
    for(i = 19; i < 27 ; i++)
        gpio_set_function(i, GPIO_FUNC_OUTPUT);
    while (1){
        for(i = 10; i < 14 ; i++)
            gpio_write(i, 1);
        for(i = 19; i < 27; i++)
            gpio_write(i, 0);
        for (volatile int delay = 0xF0000; delay != 0; delay--);
        for(i = 10; i < 14 ; i++)
            gpio_write(i, 0);
        for (volatile int delay = 0x0000F; delay != 0; delay--);
    }
}

ДОПОЛНИТЕЛЬНАЯ ПОПЫТКА: Я попытался упростить код, не используя никаких функций.Все еще получаю тот же результат.Все сегменты работают с цифрами 1 и 3. Цифры 2 и 4 не загораются.

void main(void) {
    // set functions
    unsigned int mask = 7;
    *GP_FSEL1 &= ~((mask)<<(3*1));          // reset pin 11
    *GP_FSEL1 |= GPIO_FUNC_OUTPUT<<(3*1);   // set pin 11 to OUTPUT

    *GP_FSEL2 &= ~((mask)<<(3*0));          // reset pin 20
    *GP_FSEL2 |= GPIO_FUNC_OUTPUT<<(3*0);   // set pin 20 to OUTPUT

    *GP_FSET0 &= ~(1<<11);                  // reset SET Reg of pin 11
    *GP_FSET0 |=   1<<11;                   // set SET Reg of pin 11 to high

    *GP_CLR0 &= ~(1<<20);                   // reset CLR Reg of pin 20
    *GP_CLR0 |=   1<<20;                    // set CLR Reg of pin 20 to high
}
...