一、硬件
数码管连接
刚好有一个项目用的是HT16D35A作为数码管驱动,记个笔记,防止遗忘,同时单片机用的是AVR。数码管是共阴极。
看数据手册,HT16D35A使用的是SPI/IIC总线驱动,在PCB布板的时候,考虑到布线难度,并没有使用内部的SPI/IIC,而是采用的模拟方式。
因为应用场合并不需要特别的高效,反而需要持久运行,所以整个单片机程序结构使用的是状态机方式编写,而不是事件驱动或者是时间片轮询的写法。
在手册中截了一张HT16D35A的内部结构
所以整个硬件布局是数码管的COM(公共端)连接到ROW端上,如果是共阳极就接到COM与COM连起来。下面是其中一个数码管的连接,在这个项目有十个数码管。
因为数码管本身就是七个LED,正极对应a~h。所以也可以将多个LED的负极连接到a~h,将它们的正极连接到ROW上。这次的笔记重点也就是这两部分:数码管驱动、LED驱动。
电路图如下,LED的型号是2835红色灯,封装SMD2835,立创是大头为正,拿到样品后,先用万用表二极管档检查,能否点亮,避免正反搞错(PS:前人搞错过)。数码管也是,用二极管档检查COM口的位置是否无误(有的是对角是COM口,有的是38号角是COM口,原理图、PCB画错基本上板子废了,而且最少耽误一周),以及是否是共阳或者共阴。下面左图是2835连接到HT16D35A,右图是2835封装。
确定极限参数
1、HT16D35A输出电流
2、2835最大电流
所以无需增加电阻。其实HT16D35A也可以用R_EXT引脚调整电流大小。后面再写。
HT16D35A引脚部分,与单片机连接。
看了一下数据手册,HT16D
CSB:I2C接口设备地址数据输入引脚/SPI 片选信号
SDA/DIO:串行数据输入 / 输出引脚。
OSC:系统振荡器输入 / 输出引脚。IRC模式才会用的到。
说人话:
- IRC(Internal RC)是指内部 RC(Resistor-Capacitor)振荡器,它是芯片内部集成的一个振荡器,用于产生系统时钟信号。
- ERC(External RC)是指外部 RC 振荡器,它是由外部器件提供的一个振荡器,同样用于产生系统时钟信号。
- 引脚OSC是一个I/O类型的引脚,既可以作为输入也可以作为输出。
- 当使用IRC模式命令时,系统时钟信号来自于芯片内部的RC振荡器,并且可以通过引脚OSC输出。换句话说,系统时钟是由芯片内部的RC振荡器提供的,并且可以通过引脚OSC输出给外部其他设备使用。
- 当使用从机模式或ERC模式命令时,系统时钟信号来自于引脚OSC上连接的外部时钟。这意味着系统时钟是由外部器件提供的,并且通过引脚OSC输入到芯片中。
- 看样子应该是用不到,估计是多个驱动芯片才会用到。
SYNC:如果使用主机模式命令,同步信号将从 SYNC 引脚输出。 如果使用从机模式指令,同步信号将从 SYNC 引脚输入。(应该也用不到)
R_EXT:外部电阻连接输入引脚。连接一个外部电阻以设置输出端口的电流大小。所以这个角可以根据LED调整电流。
SCL/SCK:串行时钟输入引脚。I 2 C 接口的串行时钟 (SCL) 输入。 SPI 3 线接口的串行时钟 (CLK) 输入。
二、驱动
单字节数据(模拟SPI)
数据手册描述:
HT16D35A 芯片具有一个 SPI 3 线串行接口。• CSB 引脚用于识别传输的数据。传输是由有效的低电平信号 CSB 来控制的。当 CSB 下降到低电平以后,数据才可以进行传输。• 数据是从每个字节的 MSB 开始传输 – MSB 优先 – 数据会在 CLK 的上升沿被移入到寄存器。• 从 CSB 信号的下降沿处开始,输入数据的每 8 位依序自动加载到一个寄存器。• 对于读模式,当 CSB 为低时,在发送完一个读命令代码后 DIO 引脚变为输出模式并开始读取起始地址的设置值。在接收完输出数据后,如果 MCU 将 CSB 信号设为高电平,DIO 引脚将变为输入模式,并终止读模式周期。• 对于读模式,数据将在 CLK 的下降沿输出到 DIO 引脚。
下面是写时序
根据时序从大的出发,1个字节是8位,所以传输一个字节只需要将CSB先拉低再拉高。下面是这部分的伪代码。如下图:
void Send_Byte(unsigned char a)
{
Low CSB; // 拉低CSB
//发送
High CSB; // 拉高CSB
}
接下来就是1位的发送:一个字节有8位,以BIT7为例,传输一位时钟是先拉低,传输,最后再拉高。所以传输一位的伪代码:
void Send_Bit(void)
{
clk_low;
if(bit & 0x80) io_high; // 高位传输
else io_low; // 低位传输
bit <<= 1;
// 延时,等待完成以为
clk_high;
// 延时
}
那么发送一个字节的逻辑就有了,伪代码为:
void Send_Bit(type bit)
{
for(int i = 8; i >0; i--)
{
clk_low; // 时钟拉低
// 高位传输
if(bit & 0x80) io_high; // 端口拉高
else io_low; // 低位拉低
bit <<= 1; // 左移一位
delay();
clk_high; // 时钟拉高
delay(); // 延时
}
}
-----------------
// 发送模块
CSB_LOW;
Send_Bit(0x..); // 发送第一个指令
Send_Bit(0x..); // 发送第二个指令
........
CSB_HIGH;
备注:这个只是单16位数据,连续十六位数据是。
三、指令
在HT16D35A手册中有命令描述,以及下面对应的解释
1、点亮第一个数码管
比如把第一个数码管全部点亮,那么需要配置ROM和COM即可
COM脚之前连接的是数码管的七段,所以必须全部输出开启。这两行的意思是先发送0x41h进入COM引脚控制,然后接着发送下一个指令。
CSB_LOW;
Send_Bit(0x41); // 发送第一个指令
Send_Bit(0xFF); // 发送第二个指令
CSB_HIGH;
CSB_LOW;
Send_Bit(0x42); // 命令
Send_Bit(0x00); // R27-R20,用不到
Send_Bit(0x00); // R19-R12,用不到
Send_Bit(0x00); // R11-R4,用不到
Send_Bit(0x01); // 打开第一个数码管公共端
CSB_HIGH;