1、概述

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

STM32与CH455g通信测试(仅键盘)-LMLPHP

2、特点

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

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

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

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

内置输入下拉,内置去抖动电路。

提供平有效的键盘中,提供释放标志位,可供查询按按下释放

高速2线串行接口,时钟04MHz兼容两线I2C线,节约引脚

内置位,支持2.7V5V

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

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

3、引脚介绍

STM32与CH455g通信测试(仅键盘)-LMLPHP

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之间。

 

5、串行接口

  CH455实现2线串行接口,包含2线:串行数据时钟输入线SCL、串行数输入输出线SDA;以及1辅助信线:中断输出线INT#中,SCL上拉输入线,CH455中文手册默认SDA上拉准双向信线,默认INT#上拉开漏输出在启用盘扫描功能键盘中断输出线,默认SDA于串行数据输入输出示位数据1示位数据0,串行数据输入SCL于提供串行时钟,CH455在其升沿SDA输入数据,在其沿SDA输出数据。SCLSDA沿串行接口的SCLSDA升沿串行接口的停止信CH455检测后才收并命令单片机I/O引脚紧张时,可以在保SDA引脚状态不情况SCL引脚其它接口电路如果够确SDA引脚变化仅SCL引脚那么SCL引脚SDA引脚可以其它接口电路INT#于键盘中断输出默认CH455检测到有效按键时,INT#输出低平有效键盘中;单片机CH455操作CH455INT#SDA输出按码,单片机SDA获得的数据,码。单片机与CH455的通6单片机的操作方向两种类型操作输出数据,操作输入数据。可以中的说明操作6输出输出11输出22输出止信中,停止信述,121输出1输出2包含8数据位,数据。操作6输出输出11输入22输出止信中,停止信述,121输出1输入2包含8数据位,数据。

6操作命令

  CH455操作命令分3组。命令停止信12同,别在输出1和字2的数据不同以及字2方向不同。

字数据命令:命令输出168H6AH6CH或者6EH别对应DIG0DIG3引脚驱动的4数码管;输出2[DIG_DATA]B00H0FFH,是8位的字数据。字数据命令字数据DIG_DATA1的数据寄存器中。例如命令数据01101100B6CH对应DIG201111001B字数据79H1数据寄存器,使DIG2引脚驱动的数码管显示E

读取命令:命令输出101001111B4FH输入2码。读取命令获得CH455检测有效按键的码。命令操作,是数据返回命令,单片机必须释放SDA引脚输出禁止或者上拉到高CH455SDA引脚输出按码,码的有效数据是位70中位6态码,位50是扫描码和编址

7、接口时序

  STM32与CH455g通信测试(仅键盘)-LMLPHP

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

TSD:最小时间30ns

THD:最小时间10ns

TAA/TDH:最小时间2ns

Rate:最大速率4Mbps

8、原理图接线

STM32与CH455g通信测试(仅键盘)-LMLPHP

9、程序设计

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

STM32与CH455g通信测试(仅键盘)-LMLPHPSTM32与CH455g通信测试(仅键盘)-LMLPHP
// 设置系统参数命令
#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模块不太可靠。

STM32与CH455g通信测试(仅键盘)-LMLPHPSTM32与CH455g通信测试(仅键盘)-LMLPHP
//--------------------------------------------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通信测试(仅键盘)-LMLPHP

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

10-05 12:41