hp154a驱动

目录 前言 如何控制HPDL 1414 利用74HC595控制HPDL-1414的电路 软件设计/看不见的大坑 操控和码表的对应方法 设计中需要避坑的地方 HPDL-1414 驱动程序 测试代码,主文件 测试代码,标签页文件 前言,什么是HPDL-1414 这次新收到一个有趣的屏幕,HPDL 1414,是HP做的,

目录

前言

如何控制HPDL 1414

利用74HC595控制HPDL-1414的电路

软件设计/看不见的大坑

操控和码表的对应方法

设计中需要避坑的地方

HPDL-1414 驱动程序

测试代码,主文件

测试代码,标签页文件


 

前言,什么是HPDL-1414

这次新收到一个有趣的屏幕,HPDL 1414,是HP做的,同样款式西门子也有做,应该是用于一些仪器上的古老电子元件。

本体并不是很大,1414应该十之八九是说4*4mm,这个东西小,但是亮度很高,设计上巧妙的用了一个凸透镜让数值显示的更清晰。

本身段位特别多,所以可以显示大量的字符

内置有一个驱动器了,所以没需要再使用上非常厉害IO扩展,这是让人觉得很方便的一点

 

如何控制HPDL 1414

要写软件之前需要先明白硬件,先来区分脚位,这一款的脚位和显示方向有差别,可以依据侧面的字符进行判断,侧面一面HPDL 1414,这一面的最左也是PIN 1

看脚位的定义,可以看到是D5数据输入,本身的数据是并联输入的。

所以HPDL 1414这一款产品驱动起来很简单,需要做的就是按照这个表格来输入数据,D0-D6这七个脚位决定字符,A1和A0决定是第几位数码管,WR是写入信号引脚,低电平有效,这个的作用就是让你可以并联多个HPDL1414,然后通过控制WR来决定要改变哪一个的数值。

 

利用74HC595控制HPDL-1414的电路

我预计是使用74HC595来控制输入,这是一个非常古典的芯片,5V驱动,通过3个脚位可以引出8个脚位,并且它在设计上支持多个74HC595串联,虽然驱动能力和C51差不多,但是优点是廉价耐用。

使用595间接控制HPDL-1414这样可以让引脚数减少到6个(SCK,RCK,CLR,DS以及HPDL的A1和A0)之少,当然这也是个坑,后面我会说一下。

 

首先是HPDL-1414和MCU的连接,我用的是Arduino UNO,因为方便测试且驱动力大,这里我把控制段位的A1和A0接入到数字引脚D8,D7上面。

HPDL的WR用于控制数据改写,在高电平的情况下是有效的,所以接一个10K的电阻,串联到GND让它平常是失能状态

这个简单的模块的另一个部分就是74HC595了,这个芯片同样不需要太多外部元器件,13引脚一定要连接到GND,我一开始没有连接到GND然后拿去制板,造成的结果就是74HC595一直工作不正常,不管怎么控制所有输出引脚都是高电平,后面飞了线解决。

可以看到我在10脚位接了一个10K电阻,再串接到高电平,使得CLR脚位平常是失能的状态,这个脚位发送一个低电平脉冲可以让74HC595的输出全部清零。

通过一个连接器,飞线和MCU进行连接,如果要更方便测试可以在PCB设计上预留几个测试点。

我的原理图是这样画的,仅供一个参考,因为HPDL-1414内置有驱动所以基本来说不需要外部电路。

最后这一款产品的PCB的完整版设计是这样

我找不到HPDL-1414的建模文件,简化的绘制了一个,方便后面设计外壳时候使用。

为了减少体积,在第二次改版中,我尽量的使用了贴片元件,一开始时候使用的是直插元器件(因为是库存)。

最终外观大概是这样子的。

电路原理图,以及我测试中和MCU的连接

 

软件设计/看不见的大坑

这个软件设计确实很不得了,当然这要从74HC595说起,这一个芯片看资料很容易云里雾里,为什么,因为它的引脚标注名称就有一大堆,比如一个11引脚,在一些地方叫SH_CP

在AltiumDesigner的库里面却是SRCK

然后,我再百度一下资料,又变成了SHIFT CLOCK

会出现这个情况,主要还是因为这个芯片太简单,国内仿制很多所以有几家出了自己的datasheet,然后自己命名,于是乎就这样了,所以还是记控制脚位吧,名称伤不起。

 

10脚:重置

11脚:数据输入的时钟线

12脚:输出存储器锁存时钟线

13脚:输入串口

 

先来写74HC595 的代码, 引脚接哪儿可以看我刚刚的图,写这个代码很简单,先定义脚位,然后搞一下初始化,74HC595的控制是这样的


#define CLR 9

#define SI 10

#define RCK 11   //SH_CP  clock

#define SRCK 12  //ST_CP  latch


void _74HC595_Init()

{

  pinMode(RCK, OUTPUT);//接收数据使能引脚

  pinMode(SRCK, OUTPUT);//时钟引脚

  pinMode(SI, OUTPUT); //数据输入引脚

  pinMode(CLR, OUTPUT);

   digitalWrite(CLR, HIGH);

}

 

毕竟是始祖芯片,Arduino官方库都有个专门准备的函数用来把一个8位数据输入到74HC595中

void _74HC595(int data)

{

 

    printPin(data);

    shiftOut(SI, SRCK, LSBFIRST, data);  //调用官方的函数,通过10脚给595数据

   

    digitalWrite(RCK, LOW); //将输出存储器11脚上加低电平让芯片准备好接收数据

    digitalWrite(RCK, HIGH); //将输出存储器11脚恢复到高电平

    digitalWrite(RCK, LOW);

}

 

这样就写好了,但是有个小问题,就是这个输入的数据,最终是反向的

 

比如我程序上是输入:1000 0000(也就是0x80)

实际上74HC595的D7-D0的输出:0000 0001

 

所以还要做个转换,这里加一个函数,把数值预先反向一下,这样输出再反向也就正回来了

int reverse8( int c )

{

  c  =  ( c  &   0x55  )  <<   1   |  ( c  &   0xAA  )  >>   1 ;

  c  =  ( c  &   0x33  )  <<   2   |  ( c  &   0xCC  )  >>   2 ;

  c  =  ( c  &   0x0F  )  <<   4   |  ( c  &   0xF0  )  >>   4 ;

  return  c;

}

 

然后,我要说一说我的设计中最糟糕的部分了,我为了节约引脚把HPDL的WR连接到了595的最后一个输出位上面。

所以,要输入的数据,本来只是7位,而实际上是8位,最后的D7(也是最开始输入的数据)必须置一个位,因为要把修改HPDL显示内容的“开关”打开。

也因此,我虽然输入的内容对应码表,但实际上要在函数中增加一个D7位

 

(这部分之后再补充)

 

 

 

操控和码表的对应方法

看看码表,可以看到数值在表上是由D6-D4和D3-D0定义的,得益于段位特别多,所以这个显示的数据也很多样

比如说我要显示1234,那么就需要0x31,0x32,0x33和0x34

 

最后,如果一切妥当,就可以看到

 

举一反三,也就能设置一个动态的效果了

 

设计中需要避坑的地方

这一款产品的驱动不难,但是有需要避开坑的几个点:

 

1.芯片的选择,如果你选择使用74HC595,最后会发现节约的引脚位也没有几个,但是程序设计上反而更复杂了,并口输入数据和串口输入数据,后者会需要顾及更多。如果不是引脚奇缺,还是别用了。

2.我在74HC595的一个脚位上折腾了很久,因为忘记接入到GND。

 

3.这个东西的电路设计一定要考虑连接的稳健性,测试电路上我使用了杜邦线和连接器,测试是否是接触不良导致程序不能执行耗费了至少半小时的时间。

 

 

HPDL-1414 驱动程序

 

测试代码,主文件


#define HDPL_A0 7
#define HDPL_A1 8
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  _74HC595_Init();
  Clr();
  pinMode(HDPL_A0, OUTPUT);
  pinMode(HDPL_A1, OUTPUT);

  //高低位反向,先低后高
  HPDL_Build(1, 0x43); //1001 1011
  HPDL_Build(2, 0x4F); //1001 1101
  HPDL_Build(3, 0x4D); //1001 0101
  HPDL_Build(4, 0x36); //1001 1011
  //Convert(0x34);
}

int i = 0;
void loop() {
  DisNumber(2,7);
  DisNumber(3,2);
  HPDL_Build(4,0x25);
  delay(1000);
}
void DisNumber(int vec, int num)
{
  if (num > 9) num = 9;
  if (num < 0) num = 0;
  HPDL_Build(vec, 0x30 + i); //1001 1011
  delay(100);
}
void SelectVec(int i)
{

  digitalWrite(HDPL_A0, LOW);
  digitalWrite(HDPL_A1, LOW);
  switch (i)
  {
    case 4:
      break;
    case 3:
      digitalWrite(HDPL_A0, HIGH);
      break;
    case 2:
      digitalWrite(HDPL_A1, HIGH);
      break;
    case 1:
      digitalWrite(HDPL_A0, HIGH);
      digitalWrite(HDPL_A1, HIGH);
      break;
    default:
      break;

  }
  delay(10);
}

void HPDL_Build(int sector, int data)
{
  data =  reverse8(data); //反向
  SelectVec(sector);
  _74HC595_Test(data);
  Clr();
  if (data & 0x01 == 1)
    _74HC595_Test(data - 0x01);
}
void printPin(int data)
{
  Serial.println("Current set:");

  Serial.println("A7------------A0");
  for (int i = 0; i < 8; i++)
  {
    Serial.print(data & 0x01);
    Serial.print(" ");
    data = data >> 1; //右移一位
  }

  Serial.println(" ");
  Serial.println("----------------");
}

//Input: 0101 1100 Output: 1010 0011
int Convert(int data)
{
  int datL, datH;
  int datLN, datHN;
  int output = 0;
  Serial.println("convert data:");
  printPin(data);
  datL = data & 0xF;
  datH = data & 0xF0;

  datLN = (datL) & 0x01; //    0000
  datLN = datLN << 1;
  datLN += (datL >> 1) & 0x01; // 0000  +  0110&0x01
  datLN = datLN << 1;
  datLN += (datL >> 2) & 0x01; // 0000 + 0011&0x01
  datLN = datLN << 1;
  datLN += (datL >> 3) & 0x01; //0010 + 0001&0x01 = 0011

  datHN = datH & 0x01;
  datHN = datHN << 1;
  datHN += (datH >> 1) & 0x01;
  datHN = datHN << 2;
  datHN += (datH >> 2) & 0x01;
  datHN = datHN << 3;
  datHN += (datH >> 3) & 0x01;


  output = datHN << 4 + datLN;

  Serial.println("output data:");
  printPin(output);
  return output;
}

int reverse8( int c )
{
  c  =  ( c  &   0x55  )  <<   1   |  ( c  &   0xAA  )  >>   1 ;
  c  =  ( c  &   0x33  )  <<   2   |  ( c  &   0xCC  )  >>   2 ;
  c  =  ( c  &   0x0F  )  <<   4   |  ( c  &   0xF0  )  >>   4 ;
  return  c;
}









测试代码,标签页文件

#define CLR 9
#define SI 10
#define RCK 11   //SH_CP  clock
#define SRCK 12  //ST_CP  latch

void _74HC595_Init()
{
  pinMode(RCK, OUTPUT);//接收数据使能引脚
  pinMode(SRCK, OUTPUT);//时钟引脚
  pinMode(SI, OUTPUT); //数据输入引脚
  pinMode(CLR, OUTPUT);
   digitalWrite(CLR, HIGH); 
}
void _74HC595_Test(int data)
{
    shiftOut(SI, SRCK, LSBFIRST, data);
    
    digitalWrite(RCK, LOW); //将ST_CP口上加低电平让芯片准备好接收数据
    digitalWrite(RCK, HIGH); //将ST_CP这个针脚恢复到高电平
    digitalWrite(RCK, LOW);
}
void Clr()
{
  
  //清空
   digitalWrite(CLR, HIGH); 
   delay(1);
   digitalWrite(CLR, LOW); 
   delay(1);
   digitalWrite(CLR, HIGH); 
}

 

 

 

知秋君
上一篇 2024-07-17 21:48
下一篇 2024-07-17 21:12

相关推荐