Я написал 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
}