我已经编写了2个函数(gpio_write和gpio_set_function)来控制7段显示器(共阳极LED)的数字和段,该显示器通过双极结型晶体管连接到我的RPi:集电极连接到通用电源,通过1 kOhm电阻将其基极连接到RPi引脚,并将发射极连接到显示器上的数字节点(此处为图片)。
该代码成功点亮了数字1和3(以及所有段),但是数字2和4没有点亮。我需要一些帮助找出原因。
我已经对接线进行了两次和三次检查,确保将数字连接到引脚10到13,并将段连接到引脚20到26(期间为引脚27)。我也检查了代码,找不到它的问题。我还通过断开与RPi的连接并分别点亮每个数字上的每个分段来确保每个数字都能正常工作(数字3的B段被烧毁,其他所有分段都起作用)。
又是什么可能导致数字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
}