话说初中的时候学得一个重要的理论,就是我们还处在“初级阶段”,而且这个初级阶段据说还很漫长,于是大街上满眼的山寨货,经常是形似神缺,总是差点那么点儿意思。就拿今天要说的这个测线器来说吧,市面上经常看到的只是个8根线导通性的检测,可是以太网不是点灯泡,因此完整的功能还应有协议的检测(还可以测量长度),所以说平时看到的那些8个灯的测线器,只能算是山寨货。

为了弘扬初级阶段的山寨……我意思是自力更生的精神,我决定山寨一个山寨测线器。

首先看看原版的山寨测线器是什么样子。核心的部件是这样的:

这样,让1个引脚为低,另外7个为高,就可以依次点亮对应的led。所以,只要让stm32的8个引脚按照上述的方式工作就可以了,但是本人stm32小白一枚,还搞不明白怎么把stm32的io配成双向的,于是在人才济济的QQ群里问了一下,马上就有了回音——YouRaiseMeUp马上回复了。YouRaiseMeUp非常热心的提供了一段F1的代码,是他用GPIO模拟I2C时的配置方法,真是好人啊!于是就搞定了。

首先,为了轮询方便,把led和pin放进数组里:

Led_TypeDef a_LEDs[]={LED3,LED5,LED7,LED9,LED10,LED8,LED6,LED4};

uint16_t a_PINs[]={GPIO_Pin_0,GPIO_Pin_1,GPIO_Pin_2,GPIO_Pin_3,GPIO_Pin_4,GPIO_Pin_5,GPIO_Pin_6,GPIO_Pin_7};

为什么led是这个顺序呢?看这张图:

这下大家知道为什么原理图里PE的8个引脚弄成这么个怪顺序了吧?

然后是监测函数,入口参数只有一个,表示检测的是0~7中的第几个脚:

uint8_t testPin(int i_seq)

{

  GPIO_InitTypeDef GPIO_InitStructure;

int i=0;

uint16_t PortVal;

uint8_t t;

PortVal=0;

for(i=0;i<8;i++)

{

if(i!=i_seq)

PortVal|=a_PINs[i];

}

RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOD, ENABLE);

GPIO_InitStructure.GPIO_Pin   = a_PINs[i_seq];

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

//GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOD, &GPIO_InitStructure);

 

GPIO_InitStructure.GPIO_Pin   = PortVal;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

//GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOD, &GPIO_InitStructure);

GPIO_Write(GPIOD, PortVal);

return GPIO_ReadInputDataBit(GPIOD,a_PINs[i_seq]);

}

然后呢,就是main()了:

int main(void)

{

uint8_t t;

int i=0;

GPIOInit();

SysTick_Config(SystemCoreClock / 1000);

 

for(i=0;i<8;i++)  

{

STM_EVAL_LEDInit(a_LEDs[i]);

STM_EVAL_LEDOff(a_LEDs[i]);

}

   while (1)

   {

for(i=0;i<8;i++)

{

t=testPin(i);

if(t==Bit_RESET)

{

STM_EVAL_LEDOff(a_LEDs[i]);

}

else

{

STM_EVAL_LEDOn(a_LEDs[i]);

}

Delay(1);//注1

STM_EVAL_LEDOff(a_LEDs[i]);

}

}

}

看效果,先用f3连上根坏网线(1、5是断的),再接上测线器的远端试了一下:

可以看出f3的gpio输出可以点亮测线器远端的led。但是发现f3端的8个led都是灭的,估计是电压降的太多了。然后决定不用测线器的远端了,用模块做成这个样子:

然后f3连上根好网线,再接上刚做出来的模块:

还可以吧?下面把前文提到的代码里“注1”修改一下:

Delay(100);//注1

于是毫无悬念的成动态效果了:

当然,还可以把这个参数的切换和功能的开关写进来,就成了个完整的制作了。不过考虑到这是个山寨的山寨测线器,好像没必要搞这么隆重,毕竟山寨了半天,看上去倒像个走马灯。