.
1、74HC595电路
引脚功能
管脚序号 | 符号 | 管脚功能 |
---|---|---|
10 | S C L R ‾ \overline{SCLR} SCLR | 复位端(低电平有效) |
11 | SCK | 数据输入时钟端,上升沿移位 |
12 | RCK | 输出存储器锁存时钟端(下降沿,输出状态保持不变;上升沿,8 位锁存移位寄存器中的状态值并行输出) |
13 | G ‾ \overline{G} G | 输出使能端,为低电平使,输出选通;为高电平时,输出高阻态 |
14 | SER | 串行数据输入端 |
15、1~7 | Q0~Q7 | 八位数据并行输出端 |
9 | Q7` | 串行数据输出端 |
8 | GND | 电源地 |
16 | Vcc | 电源端 |
不同原理图对74HC595引脚符号的标注不同,但对应引脚的功能都是相同的。
.
电路连接
将输出使能引脚 G# 下拉,使之可以输出数据。
复位引脚 SCLR# 上拉,不需要进行复位。
ESP32的GPI/O33连接 数据输入端 SER ,输出串行数据。
ESP32的GPI/O26连接 数据输入时钟端 SCK ,产生发送数据时需要的时钟。
ESP32的GPI/O27连接 锁存寄存器时钟端 RCK ,控制数据输出状态的保持。
级联
级联方法
需要将其中一个595的串行数据输出引脚连接到另一个的数据输入引脚上。
两个595芯片的数据时钟引脚,锁存器引脚分别连接到相同的单片机控制引脚。
数据写入
先写入的数据往后移,例如输入 0000 0000 0000 0101
,若是从低位开始输入,则第一个数据应该是1,第二个是0,第三个是1,第四个是0,第五个是0,…
输入完成后对 RCK引脚发送一个上升沿,然后发送一个下降沿,使其输出的引脚状态保持。
OUT_0~OUT15的状态应为:0000 0000 0000 0101
。
.
.
在键盘的原理图设计时,为了在编程时方便写按键扫描驱动,将输出的位置对调了一下,即OUT_0设为OUT_15,OUT_1设为OUT_14,其余部分也是如此。
.
.
2、按键矩阵原理
以上为部分按键矩阵,通过二极管的单向导通特性实现按键放冲突(所有按键同时按下也不会高低电平直接连接)。
.
扫描方法
初始化:
74HC595芯片引脚全部输出低电平,即OUT0~OUT13全为低电平,
5个输入引脚设置为下拉输入。
扫描:
扫描时仅将其中一个的输出状态设为1,其余设为0,然后读取5个输入引脚的状态。
反复上述步骤13次即可扫描一遍键盘状态。
.
.
.
3、扫描驱动程序
引脚初始化
引脚初始化函数为 void pin_init();
输出设置
驱动程序 void write_hc595(uint8_t loc)
将 OUT_loc 设定为1,其余为0。
void write_hc595(uint8_t loc)
{
//将锁存时钟引脚置低
//原来为高电平,此时为低电平,产生下降沿
//保持原来的数据状态,防止在写入新数据时输出引脚也随着新数据变化
digitalWrite(STC_PIN, LOW);
for (uint8_t j = 0; j < 16; j++)
{
//将时钟引脚置低,
//原来为高电平,此时为低电平,产生下降沿
digitalWrite(SHC_PIN, LOW);
//如果当前数据位需要置1
if (j == loc)
{
digitalWrite(OUT_PIN, HIGH);//数据引脚拉高,写入1
}
else//否则置0。
{
digitalWrite(OUT_PIN, LOW);//数据引脚拉低,写入0
}
digitalWrite(SHC_PIN, HIGH);
//将时钟引脚置高,
//原来为低电平,此时为高电平,产生上升沿,写入的数据向后移,并将数据引脚的状态保存。
}
//将锁存时钟引脚置高
//原来为低电平,此时为高电平,产生上升沿
//将8位锁存移位寄存器中保存的的状态值并行输出
digitalWrite(STC_PIN, HIGH);
delayMicroseconds(1); //此处需要延迟1us,保证输出状态稳定
}
扫描读取
示例
pin_init(); //引脚初始化
iir_begin(); //开启IIR滤波
uint8_t IN_P[5] = {IN0, IN1, IN2, IN3, IN4};
uint8_t KEY_STATE[KEYBOARD_ROW][KEYBOARD_COLUMN] = {};
for (;;)
{
//如果允许键盘读取get_scan_keyboard()返回1,否则返回0
if (get_scan_keyboard() == 1)
{
//逐列扫描
for (int i = 0; i < KEYBOARD_ROW; i++)
{
//逐行读取
for (int j = 0; j < KEYBOARD_COLUMN; j++)
{
//将对应列置1,其余列置0。
write_hc595(j);
//读取对应行的输入引脚状态
KEY_STATE[i][j] = digitalRead(IN_P[i]);
}
}
//由于回车键单独使用一个GPI/O引脚检测,所以
KEY_STATE[ENTER_X][ENTER_Y] = !digitalRead(ENTER_PIN);
//将扫描得出的状态写入队列,提供给其他任务读取。
xQueueOverwrite(KEYBOARD_SATE_QUEUE, &KEY_STATE);
}
}
.
.
3、参考资料
1、百度百科 74HC595
https://baike.baidu.com/item/74HC595/9886491?fr=aladdin
.
.
资料获取
全部工程文件进ESP32工程群(483217976)自行下载,所有文件在 ESP32键盘 目录下。