1、概述

  CH455是数码管显示驱动和键盘扫描控制芯片。CH455内置时钟振荡电路,可以动态驱动4位数码管或者32只LED;同时还可以进行28键的键盘扫描;CH455通过SCL和SDA组成的2线串行接口与单片机等交换数据。

2、特点

●内置显示电流驱动级,段电流不小于25mA,字电流不小于160mA。

●动态显示扫描控制,支持8×4或者7×4,直接驱动4位数码管或者32只发光管LED。

●内部限流,通过占空比设定提供8级亮度控制。

●内置28键键盘控制器,基于7×4矩阵键盘扫描。

●内置按键状态输入的下拉电阻,内置去抖动电路。

●提供低电平有效的键盘中断,提供按键释放标志位,可供查询按键按下与释放。

●高速2线串行接口,时钟速度从0到4MHz,兼容两线I2C总线,节约引脚。

●内置上电复位,支持2.7V~5V电源电压。

●支持低功耗睡眠,节约电能,可以被按键唤醒或者被命令操作唤醒。

●内置时钟振荡电路,不需要外部提供时钟或者外接振荡元器件,更抗干扰。

3、引脚介绍

VCC:电源正电源,持续电流不小于150mA

GND:电源公共接地,持续电流不小于150mA

SEG0 ~SEG6:三态输出及输入数码管的段驱动,高电平有效,键盘扫描输入,高电平有效,内置下拉

SEG7:输出数码管的小数点段驱动输出,高电平有效,7段模式下的键盘中断输出,低电平有效

DIG0 ~DIG3:输出数码管的字驱动,低电平有效,键盘扫描输出,高电平有效

SDA:内置上拉开漏输出及输入2线串行接口的数据输入和输出,内置上拉电阻SCL:输入2线串行接口的数据时钟,内置上拉电阻

4、键盘扫描功能

  键盘扫描CH455的键盘扫描功能支持7×4矩阵的28键键盘。在键盘扫描期间,DIG3~DIG0引脚用于列扫描输出,SEG6~SEG0引脚都带有内部下拉电阻,用于行扫描输入。CH455定期在显示驱动扫描过程中插入键盘扫描。在键盘扫描期间,DIG3~DIG0引脚按照DIG0至DIG3的顺序依次输出高电平,其余引脚输出低电平;SEG6~SEG0引脚的输出被禁止,当没有键被按下时,SEG6~SEG0都被下拉为低电平;当有键被按下时,例如连接DIG1与SEG4的键被按下,则当DIG1输出高电平时SEG4检测到高电平;为了防止因为按键抖动或者外界干扰而产生误码,CH455实行两次扫描,只有当两次键盘扫描的结果相同时,按键才会被确认有效。如果CH455检测到有效的按键,则记录下该按键代码,并通过INT#引脚产生低电平有效的键盘中断,此时单片机可以通过串行接口读取按键代码;在没有检测到新的有效按键之前,CH455不再产生任何键盘中断。CH455支持SEG1和SEG0针对同一DIG的组合键,组合键是最优先的,除此之外,如果多个键同时按下,那么按键代码较小的按键优先。例如连接DIG1与SEG1及连接DIG1与SEG0的两个键,可作为组合键。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矩阵的按键编址,也是数码管段位和发光管LED阵列的顺序编址。由于按键代码是8位,键按下时位6总是1,所以当键按下时,CH455所提供的实际按键代码是表中的按键编址加上40H,也就是说,此时的按键代码应该在44H到7FH之间。

编址 DIG3 DIG2 DIG1 DIG0
SEG0 07H 06H 05H 04H
SEG1 0FH 0EH 0DH 0CH
SEG2 17H 16H 15H 14H
SEG3 1FH 1EH 1DH 1CH
SEG4 27H 26H 25H 24H
SEG5 2FH 2EH 2DH 2CH
SEG6 37H 36H 35H 34H
SEG0+SEG1 3FH 3EH 3DH 3CH

5、串行接口

  CH455具有硬件实现的2线串行接口,包含2个主要信号线:串行数据时钟输入线SCL、串行数据输入和输出线SDA;以及1个辅助信号线:中断输出线INT#。其中,SCL是带上拉的输入信号线,CH455中文手册4默认是高电平;SDA是带上拉的准双向信号线,默认是高电平;INT#是带上拉的开漏输出,在启用键盘扫描功能后作为键盘中断输出线,默认是高电平。SDA用于串行数据输入和输出,高电平表示位数据1,低电平表示位数据0,串行数据输入的顺序是高位在前,低位在后。SCL用于提供串行时钟,CH455在其上升沿从SDA输入数据,在其下降沿从SDA输出数据。在SCL为高电平期间发生的SDA下降沿定义为串行接口的启动信号,在SCL为高电平期间发生的SDA上升沿定义为串行接口的停止信号。CH455只在检测到启动信号后才接收并分析命令。所以在单片机I/O引脚资源紧张时,可以在保持SDA引脚状态不变的情况下,将SCL引脚与其它接口电路共用;如果能够确保SDA引脚的变化仅在SCL引脚为低电平期间发生,那么SCL引脚和SDA引脚都可以与其它接口电路共用。INT#用于键盘中断输出,默认是高电平。当CH455检测到有效按键时,INT#输出低电平有效的键盘中断;单片机被中断后,对CH455执行读操作,CH455将INT#恢复为高电平,并从SDA输出按键代码,单片机从SDA获得一个字节的数据,即按键代码。单片机与CH455的通讯过程总是分为6个步骤,按单片机的操作方向分成两种类型,一种是写操作,用于输出数据,一种是读操作,用于输入数据。具体过程可以参考例子程序中的说明。写操作包括以下6个步骤:输出启动信号、输出字节1、应答1、输出字节2、应答2、输出停止信号。其中,启动信号和停止信号如上所述,应答1和应答2总是固定为1,输出字节1和输出字节2各自包含8个数据位,即一个字节数据。读操作包括以下6个步骤:输出启动信号、输出字节1、应答1、输入字节2、应答2、输出停止信号。其中,启动信号和停止信号如上所述,应答1和应答2总是固定为1,输出字节1和输入字节2各自包含8个数据位,即一个字节数据。

6、操作命令

  CH455的操作命令分为3组。各命令的启动信号、停止信号、应答1和应答2都相同,区别在于输出字节1和字节2的数据不同以及字节2的传输方向不同。

加载字数据命令:该命令的输出字节1为地址68H、6AH、6CH或者6EH,分别对应于DIG0~DIG3引脚驱动的4个数码管;输出字节2为[DIG_DATA]B,即00H到0FFH之间的值,是8位的字数据。加载字数据命令用于将字数据DIG_DATA写入字节1指定地址的数据寄存器中。例如,命令数据01101100B(即6CH对应DIG2)、01111001B表示将字数据79H写入第1个数据寄存器,使DIG2引脚驱动的数码管将显示E。

读取按键代码命令:该命令的输出字节1为01001111B,即4FH;输入字节2为按键代码。读取按键代码命令用于获得CH455最近检测到的有效按键的按键代码。该命令属于读操作,是唯一的具有数据返回的命令,单片机必须先释放SDA引脚(三态输出禁止或者上拉到高电平),然后CH455从SDA引脚输出按键代码,按键代码的有效数据是位7~位0,其中位6是状态码,位5~位0是扫描码和按键编址。

7、接口时序

  

TSSTA/THSTA/TSSTO/THSTO/TCLOW/TCHIG:最小时间100ns

TSD:最小时间30ns

THD:最小时间10ns

TAA/TDH:最小时间2ns

Rate:最大速率4Mbps

8、原理图接线

9、程序设计

  由于这次只是做个简单的按键检测,所以只用到键盘扫描功能,数码管有需要再做吧。先定义一下系统参数:

// 设置系统参数命令
#define CH455_SCL_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)
#define CH455_SCL_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)
#define CH455_SCL_D_OUT {} // 设置SCL为输出方向,对于双向I/O需切换为输出 #define CH455_SDA_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)
#define CH455_SDA_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)
#define CH455_SDA_IN HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9) // 读取SDA输入电平 #define CH455_BIT_ENABLE 0x01 // 开启/关闭位
#define CH455_BIT_SLEEP 0x04 // 睡眠控制位
#define CH455_BIT_7SEG 0x08 // 7段控制位
#define CH455_BIT_INTENS1 0x10 // 1级亮度
#define CH455_BIT_INTENS2 0x20 // 2级亮度
#define CH455_BIT_INTENS3 0x30 // 3级亮度
#define CH455_BIT_INTENS4 0x40 // 4级亮度
#define CH455_BIT_INTENS5 0x50 // 5级亮度
#define CH455_BIT_INTENS6 0x60 // 6级亮度
#define CH455_BIT_INTENS7 0x70 // 7级亮度
#define CH455_BIT_INTENS8 0x00 // 8级亮度 #define CH455_SYSOFF 0x0400 // 关闭显示、关闭键盘
#define CH455_SYSON ( CH455_SYSOFF | CH455_BIT_ENABLE ) // 开启显示、键盘
#define CH455_SLEEPOFF CH455_SYSOFF // 关闭睡眠
#define CH455_SLEEPON ( CH455_SYSOFF | CH455_BIT_SLEEP ) // 开启睡眠
#define CH455_7SEG_ON ( CH455_SYSON | CH455_BIT_7SEG ) // 开启七段模式
#define CH455_8SEG_ON ( CH455_SYSON | 0x00 ) // 开启八段模式
#define CH455_SYSON_4 ( CH455_SYSON | CH455_BIT_INTENS4 ) // 开启显示、键盘、4级亮度
#define CH455_SYSON_8 ( CH455_SYSON | CH455_BIT_INTENS8 ) // 开启显示、键盘、8级亮度 // CH455接口定义
#define CH455_I2C_ADDR 0x40 // CH455的地址
#define CH455_I2C_MASK 0x3E // CH455的高字节命令掩码 // 读取按键代码命令
#define CH455_GET_KEY 0x0700 // 获取按键,返回按键代码

define

另外,用的是stm32的HAL库,但是IIC通讯依然用的是IO口模拟IIC的,主要是因为CH455g的器件地址没有找到,其次是HAL库自带的IIC模块不太可靠。

//--------------------------------------------i2c-------------------------------------------
// 设置SDA为输出方向,对于双向I/O需切换为输出
void CH455_SDA_D_OUT()
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } // 设置SDA为输入方向,对于双向I/O需切换为输入
void CH455_SDA_D_IN()
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } void CH455_I2c_Start( void ) // 操作起始
{
//DISABLE_KEY_INTERRUPT; //禁止键盘中断,防止开始时被CH455中断而进入中断服务程序中的START CH455_SDA_SET; /*发送起始条件的数据信号*/
CH455_SDA_D_OUT(); /* 设置SDA为输出方向 */
CH455_SCL_SET;
CH455_SCL_D_OUT; /* 设置SCL为输出方向 */
HAL_Delay(10);
CH455_SDA_CLR; /*发送起始信号*/
HAL_Delay(10);
CH455_SCL_CLR; /*钳住I2C总线,准备发送或接收数据 */
} void CH455_I2c_Stop( void ) // 操作结束
{
CH455_SDA_CLR;
CH455_SDA_D_OUT(); /* 设置SDA为输出方向 */
HAL_Delay(10);
CH455_SCL_SET;
HAL_Delay(10);
CH455_SDA_SET; /*发送I2C总线结束信号*/
HAL_Delay(10);
CH455_SDA_D_IN(); /* 设置SDA为输入方向 */
//ENABLE_KEY_INTERRUPT;
} void CH455_I2c_WrByte( uint8_t dat ) //写一个字节数据
{
uint8_t i;
CH455_SDA_D_OUT(); /* 设置SDA为输出方向 */
for( i = 0; i != 8; i++ ) // 输出8位数据
{
if( dat & 0x80 )
{
CH455_SDA_SET;
}
else
{
CH455_SDA_CLR;
}
HAL_Delay(10);
CH455_SCL_SET;
dat <<= 1;
HAL_Delay(10); // 可选延时
CH455_SCL_CLR;
}
CH455_SDA_D_IN(); /* 设置SDA为输入方向 */
CH455_SDA_SET;
HAL_Delay(10);
CH455_SCL_SET; // 接收应答
HAL_Delay(10);
CH455_SCL_CLR;
} uint8_t CH455_I2c_RdByte( void ) //读一个字节数据
{
uint8_t dat,i;
CH455_SDA_SET;
CH455_SDA_D_IN(); /* 设置SDA为输入方向 */
dat = 0;
for( i = 0; i != 8; i++ ) // 输入8位数据
{
HAL_Delay(10); // 可选延时
CH455_SCL_SET;
HAL_Delay(10); // 可选延时
dat <<= 1;
if( CH455_SDA_IN ) dat++; // 输入1位
CH455_SCL_CLR;
}
CH455_SDA_SET;
HAL_Delay(10);
CH455_SCL_SET; // 发出无效应答
HAL_Delay(10);
CH455_SCL_CLR;
return dat;
} void CH455_Write( uint16_t cmd ) //写命令
{
CH455_I2c_Start(); //启动总线
CH455_I2c_WrByte(((uint8_t)(cmd>>7)&CH455_I2C_MASK)|CH455_I2C_ADDR);
CH455_I2c_WrByte((uint8_t)cmd); //发送数据
CH455_I2c_Stop(); //结束总线
} uint8_t CH455_Read( void ) //读取按键
{
uint8_t keycode;
CH455_I2c_Start(); //启动总线
CH455_I2c_WrByte((uint8_t)(CH455_GET_KEY>>7)&CH455_I2C_MASK|0x01|CH455_I2C_ADDR);
keycode=CH455_I2c_RdByte(); //读取数据
CH455_I2c_Stop(); //结束总线
return keycode;
}

IO口模拟IIC

主函数开启中断和键盘:

HAL_ADC_Start_IT(&hadc1);
CH455_Write( CH455_7SEG_ON );// 开启显示和键盘,8段显示方式

写完回调函数,即可打印输出键码:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
RX_AD = HAL_ADC_GetValue(&hadc1);
if(RX_AD == 0)
{
RX_CH455 = CH455_Read();
printf("键码:%x\r\n",RX_CH455);
}
}

完了给大伙看看按键打印结果:

需要程序的记得留言打赏哦

STM32与CH455g通信测试(仅键盘)的更多相关文章

  1. STM32 实现 4*4 矩阵键盘扫描(HAL库、标准库 都适用)

    本文实现的代码是基于STM32HAL库的基础上的,不过标准库也可以用,只是调用的库函数不同,逻辑跟配置是一样的,按我这里的逻辑来配置即可. 1.键盘原理图: 原理举例:先把 F0-F7 内部拉高,这样 ...

  2. Tkinter 鼠标键盘事件(二)

    一个Tkinter主要跑在mainloop进程里.Events可能来自多个地方,比如按键,鼠标,或是系统事件. Tkinter提供了丰富的方法来处理这些事件.对于每一个控件Widget,你都可以为其绑 ...

  3. python tkinter教程-事件绑定

    一个Tkinter主要跑在mainloop进程里.Events可能来自多个地方,比如按键,鼠标,或是系统事件. Tkinter提供了丰富的方法来处理这些事件.对于每一个控件Widget,你都可以为其绑 ...

  4. [FreeRTOS入门] 1.CubeMX中FreeRTOS配置参数及理解

    1.有关优先级 1.1 Configuration --> FreeRTOS MAX_PRIORITIES 设置任务优先级的数量:配置应用程序有效的优先级数目.任何数量的任务都可以共享一个优先级 ...

  5. python tkinter中的事件绑定

    一个Tkinter主要跑在mainloop进程里.Events可能来自多个地方,比如按键,鼠标,或是系统事件. Tkinter提供了丰富的方法来处理这些事件.对于每一个控件Widget,你都可以为其绑 ...

  6. 【STM32学习笔记】STM32f407 使用4*4矩阵键盘

    作者:李剀 出处:https://www.cnblogs.com/kevin-nancy/ 欢迎转载,但也请保留上面这段声明.谢谢! 写在前面: 这是本人第一次开始写博客,可能写的不是很好,也请大家谅 ...

  7. ARM开发(3)基于STM32的矩阵键盘控制蜂鸣器

    一 矩阵键盘控制蜂鸣器原理:  1.1 本实验实现8*7矩阵键盘上按键控制蜂鸣器响.  1.2 实验思路:根据电路图原理,找出矩阵键盘行列所对应的引脚,赋予对应的按键值,然后控制蜂鸣器响.  1.3 ...

  8. stm32 hid 键盘描述

    /* USB Standard Device Descriptor */ const uint8_t Joystick_DeviceDescriptor[JOYSTICK_SIZ_DEVICE_DES ...

  9. stm32矩阵键盘扫描数据通过USB发送

                   Keyboard.c #include "keyboard.h"#include "my_usb.h"#include " ...

随机推荐

  1. google protocol buffer——protobuf的编码原理二

    这一系列文章主要是对protocol buffer这种编码格式的使用方式.特点.使用技巧进行说明,并在原生protobuf的基础上进行扩展和优化,使得它能更好地为我们服务. 在上一篇文章中,我们主要通 ...

  2. k8s部署mysql主从复制

    Mysql主从 准备环境 一,准备软件 官方docker_image :Mysql5.7.28 Docker Version:        19.03.4 K8s api-version:      ...

  3. LeetCode 95 | 构造出所有二叉搜索树

    今天是LeetCode专题第61篇文章,我们一起来看的是LeetCode95题,Unique Binary Search Trees II(不同的二叉搜索树II). 这道题的官方难度是Medium,点 ...

  4. Java/后端学习路线

    点赞再看,养成习惯,微信搜一搜[三太子敖丙]关注这个喜欢写情怀的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系 ...

  5. python笔记-正则表达式

    什么是正则表达式: 正则表达式是一个特殊的字符序列,能帮助我们方便的检查一个字符串是否与某种模式匹配(定义往往都很枯燥) 也称之为”模式“,即可用于检查一个给定的字符串是否符合某种模式 举例: 我们定 ...

  6. Animator.SetFloat(string name,float value,float dampTime,float deltaTime)详解

    一般来说,我们用到的是这个API: animator.SetFloat("Speed",2.0f); 但是这个还有一个重载的方法,叫做: Animator.SetFloat(str ...

  7. python学习第八天

    解析库之bs4的基本使用方法 ''' pip install beautifulsoup4#安装bs4 pip install lxml#安装lxml ''' html_doc = "&qu ...

  8. HDU - 5775-Bubble Sort(权值线段树)

    P is a permutation of the integers from 1 to N(index starting from 1). Here is the code of Bubble So ...

  9. 520是秀恩爱吃狗粮,521才是真正的告白日,- Python告白神器用起来 !

    网络情人节是信息时代的爱情节日,定于每年的5月20日和5月21日,该节日源于歌手范晓萱的<数字恋爱>中“520”被喻成“我爱你” ,以及音乐人吴玉龙的网络歌曲中“我爱你”与“网络情人”的紧 ...

  10. C#操作Excel开发报表系列整理

    C#操作Excel进行报表开发系列共写了八篇,也已经有很久没有新东西了,现在整理一下,方便以后查阅,如果有写新的,会同时更新.需要注意的是因为Office的版本不同,实际的代码可能会有所不同,但是都是 ...