实验九 矩阵键盘和数码管显示—模拟IIC
一.实验目标
1.熟悉通过IO口模拟IIC实现方式;
2.通过本实验掌握STM32的模拟IIC控制,熟悉CH455控制。
二.知识储备及设计思路
前面章节详细介绍了I2C的物理层和协议层,通过编程硬件I2C实现EEPRAM的读写,在实际使用中,可能设备硬件I2C接口不够使用,我们就需要通过普通IO口实现模拟I2C功能。
用软件模拟IIC,最大的好处就是方便移植,同一个代码兼容所有MCU,任何一个单片机只要有IO口,就可以很快的移植过去,而且不需要特定的IO口。而硬件IIC,则换一款MCU,基本上就得重新搞一次,移植是比较麻烦的。
CH455芯片简介
CH455 是数码管显示驱动和键盘扫描控制芯片。CH455 内置时钟振荡电路,可以动态驱动 4
位数 码管或者 32 只 LED;同时还可以进行 28 键的键盘扫描;CH455 通过 SCL 和 SDA
组成的 2 线串行接口 与单片机等交换数据。
芯片特点:
● 内置显示电流驱动级,段电流不小于 25mA,字电流不小于 160mA。
● 动态显示扫描控制,支持 8×4 或者 7×4,直接驱动 4 位数码管或者 32 只发光管 LED。
● 内部限流,通过占空比设定提供 8 级亮度控制。
● 内置 28 键键盘控制器,基于 7×4 矩阵键盘扫描。
● 内置按键状态输入的下拉电阻,内置去抖动电路。
● 提供低电平有效的键盘中断,提供按键释放标志位,可供查询按键按下与释放。
● 高速 2 线串行接口,时钟速度从 0 到 4MHz,兼容两线 I 2 C 总线,节约引脚。
● 内置上电复位,支持 2.7V~5V 电源电压。
● 支持低功耗睡眠,节约电能,可以被按键唤醒或者被命令操作唤醒。
● 内置时钟振荡电路,不需要外部提供时钟或者外接振荡元器件,更抗干扰。
● 提供 DIP18、SOP18 和 SOP16 三种无铅封装,功能和引脚部分兼容 CH450 芯片。
CH455功能说明
1) 显示驱动
CH455 对数码管和发光管采用动态扫描驱动,顺序为 DIG0 至 DIG3,段驱动引脚
SEG6~SEG0 分别对应数码管的段 G~段 A,段驱动引脚 SEG7 对应数码管的小数点,字驱
动引脚 DIG3~DIG0 分别连接 4 个数码管的阴极;CH455
将分配给每个数码管的显示驱动时间进一步细分为 8 等份,通过设定显示占空比支持 8 级
亮度控制。占空比的值从 1/8 至
8/8,占空比越大,数码管的平均驱动电流越大,显示亮度也就越高.
CH455 内部具有 4 个 8 位的数据寄存器,用于保存 4 个字数据,分别对应于 CH455
所驱动的 4 个 数码管或者 4 组每组 8 个的发光二极管。
2) 键盘扫描
CH455 的键盘扫描功能支持 7×4 矩阵的 28 键键盘。在键盘扫描期间,DIG3~DIG0
引脚用于列 扫描输出,SEG6~SEG0 引脚都带有内部下拉电阻,用于行扫描输入。CH455
定期在显示驱动扫描过程中插入键盘扫描。
当有键被按下时,例如连接 DIG1 与 SEG4 的键被按下,则 当 DIG1 输出高电平时 SEG4
检测到高电平;为了防止因为按键抖动或者外界干扰而产生误码,CH455
实行两次扫描,只有当两次键盘扫描的结果相同时,按键才会被确认有效。如果 CH455
检测到有效的 按键,则记录下该按键代码,并通过
INT#引脚产生低电平有效的键盘中断,此时单片机可以通过串行接口读取按键代码。
CH455 所提供的按键代码为 8 位:位 7 始终为 0,位 2 始终为 1,位 1~位 0
是列扫描码,位 5~ 位 3 是行扫描码,位 6 是状态码(键按下为 1,键释放为
0)。例如,连接 DIG1 与 SEG4 的键被按下, 则按键代码是 01100101B 或者
65H,键被释放后,按键代码通常是 00100101B 或者 25H(也可能是其它值,但是肯定小于
40H),其中,对应 DIG1 的列扫描码为 01B,对应 SEG4 的行扫描码为 100B。单
片机可以在任何时候读取按键代码,但一般在 CH455
检测到有效按键而产生键盘中断时读取按键代 码,此时按键代码的位 6 总是
1,另外,如果需要了解按键何时释放,单片机可以通过查询方式定期
读取按键代码,直到按键代码的位 6 为 0。
下表是在 DIG3~DIG0 与 SEG6~SEG0 之间 7×4 矩阵的按键按下后编址。
编址 | DIG3 | DIG2 | DIG1 | DIG0 |
---|---|---|---|---|
SEG0 | 47H | 46H | 45H | 44H |
SEG1 | 4FH | 4EH | 4DH | 4CH |
SEG2 | 57H | 56H | 55H | 54H |
SEG3 | 5FH | 5EH | 5DH | 5CH |
SEG4 | 67H | 66H | 65H | 64H |
SEG5 | 6FH | 6EH | 6DH | 6CH |
SEG6 | 77H | 76H | 75H | 74H |
SEG0+SEG1 | 7FH | 7EH | 7DH | 7CH |
3) 串行接口
CH455 具有硬件实现的 2 线串行接口,包含 2 个主要信号线:串行数据时钟输入线
SCL、串行数 据输入和输出线 SDA;以及 1 个辅助信号线:中断输出线
INT#,默认高电平。
写操作包括以下 6 个步骤:输出启动信号、输出字节 1、应答 1、输出字节 2、应答
2、输出停 止信号。其中,启动信号和停止信号如上所述,应答 1 和应答 2 总是固定为
1,输出字节 1 和输出字 节 2 各自包含 8 个数据位,即一个字节数据。
读操作包括以下 6 个步骤:输出启动信号、输出字节 1、应答 1、输入字节 2、应答
2、输出停 止信号。其中,启动信号和停止信号如上所述,应答 1 和应答 2 总是固定为
1,输出字节 1 和输入字 节 2 各自包含 8 个数据位,即一个字节数据。
下图是一个写操作的实例,字节 1 为 01001000B,即 48H;字节 2 为 00000001B,即
01H。
4) 操作命令
a. 设置系统参数命令
设置系统参数命令用于设定 CH455 的系统级参数:显示及键盘扫描使能 ENA、睡眠使能
SLEEP、7 段模式 7SEG、显示亮度控制 INTENS。该命令不影响内部数据缓冲区中的数据。
该命令的字节 1 为 01001000B,即 48H;输出字节 2 为 0 [INTENS] [7SEG]
[SLEEP]0[ENA]B。
Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 | |
---|---|---|---|---|---|---|---|---|
输出字节2 | 0 | [INTENS] | [7SEG] | [SLEEP] | 0 | [ENA] |
ENA 位为 1 时允许显示输出和键盘扫描,当 ENA 位为 0 时关闭显示驱动和键盘扫描。
SLEEP 位为 1 时使 CH455 进入低功耗睡眠状态,从而可以节约电能。
7SEG 位为 1 时对应 7 段模式,显示扫描为 7×4, 为 0 时对应 8 段模式,显示扫描为
8×4。
INTENS 通过 3 位数据控制,数据 001B~111B 和 000B 设定显示驱动占空比为 1/8~
7/8 和 8/8,默认值是 8/8。
b. 加载字数据命令
该命令的输出字节 1 为地址 68H、6AH、6CH 或者 6EH,分别对应于 DIG0~DIG3
引脚驱动的 4 个 数码管;输出字节 2 为[DIG_DATA]B,即 00H 到 0FFH 之间的值,是 8
位的字数据。
c. 读取按键代码命令
读取按键代码命令用于获得 CH455
最近检测到的有效按键的按键代码。该命令属于读操作,是 唯一的具有数据返回的命令,
该命令的输出字节 1 为 01001111B,即 4FH;输入字节 2 为按键代码。
三.引脚说明与硬件连接
图9.1为4位七段共阴极数码管COM1-COM4的硬件连接图。STM32通过IIC接口配置CH455H寄存器,CH455H芯片控制数码管显示和按键扫描。每位数码管由对应的位选信号DIG1-DIG4控制是否选中,低电平有效,即输出低电平则选中该位数码管;选中的七段共阴极数码管由七个字码段SEG0-SEG6以及小数点位SEG7控制是否点亮,高电平有效,即输出高电平对应的引脚点亮。IIC接口9.1为其引脚说明。
图9.1 数码管硬件连接图
表9.1 数码管引脚说明
设备名 | 引脚号 |
---|---|
CH455_SCL | PC14 |
CH455_SDA | PC15 |
CH455_INT | PC13 |
CH455通过模拟IIC和单片机通信,当按键按下后,CH455_INT管脚会产生一个下降沿,寄存器数据会发生变化,单片机通过检测PC13管脚的边沿,进入中断,在中断中读取IIC数据。
四.程序设计
本实验,我们新建了myiic.c , myiic.h文件用于实现模拟I2C的功能, ch455.c ,
ch455.h实现ch455的控制。
myiic.c的代码如下,用于实现模拟IIC功能.
1 |
|
该部分为IIC驱动代码,实现包括IIC的初始化(IO口)、IIC开始、IIC结束、ACK、IIC读写等功能,在其他函数里面,只需要调用相关的IIC函数就可以和外部IIC器件通信了,这里并不局限于ch455,该段代码可以用在任何IIC设备上。
打开myiic.h头文件可以看到,我们除了函数申明之外,还定义了几个宏定义标识符:
myiic.h的代码如下:
1 |
|
该部分代码的SDA_IN
()和SDA_OUT()分别用于设置IIC_SDA接口为输入和输出,如果这两句代码看不懂,请好好温习下IO口的使用相关寄存器。
本节,外部中断和模拟IIC都在前面章节详细讲解过,这里不再详细描述。最要讲CH455实现读写操作,再将数据写在数码管上显示。
这里我们在main函数调用cube生成的初始化函数MX_GPIO_Init();初始化GPIO参数配置和中断配置,具体函数如下:
1 | GPIO_InitStruct.Pin = GPIO_PIN_13; |
接下来就是编写中断回调函数HAL_GPIO_EXTI_Callback。具体函数如下:
1 | // 按键中断回调函数,在中断环境中执行 |
回调函数首先判断中断是来自哪个管脚,然后将CH455_KEY_RX_FLAG置1,在中断里通过函数CH455_Key_Read()读取寄存器的值返回给CH455_KEY_NUM。再清除寄存器中断标志位,表示可以接收下一次中断。
再main函数中,在while循环内部,只需一直判断CH455_KEY_RX_FLAG值,如果为1,就按键值显示在数码管上。
1 | int main(void) |
Ch455.c文件中,我们只部分函数分析。Ch455.h定义了部分寄存器和设定值。
芯片初始化函数CH455_init,用于初始化芯片寄存器,这段程序必须在主函数初始化时中调用。
1 | //CH455初始化 |
数码管显示函数CH455_Display,用于4位数码管显示。
1 | /数码管显示 |
按键检测函数CH455_Display,读取按键的值。
1 | uint8_t CH455_Key_Read(void) // 向CH450发出按键读操作命令 |
五.实验结果
我们把程序下载到STM32F407开发板,未进行任何操作时,可以看到数码管上显示值是1234,当我们按下按键后,可以看到数码管显示的值发生变化,按键和数码管显示的值对应关系:(key1-key16)
对应 (0 – F)。
六.STM32CubeMx配置
使用CUBE配置GPIO管脚和中断截图图下。