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

1、概述

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

STM32与CH455g通信测试(仅键盘)_第1张图片

2、特点

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

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

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

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

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

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

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

内置位,支持2.7V5V

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

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

3、引脚介绍

STM32与CH455g通信测试(仅键盘)_第2张图片

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中文手册默认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通信测试(仅键盘)_第3张图片

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

TSD:最小时间30ns

THD:最小时间10ns

TAA/TDH:最小时间2ns

Rate:最大速率4Mbps

8、原理图接线

STM32与CH455g通信测试(仅键盘)_第4张图片

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通信测试(仅键盘)_第5张图片

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

你可能感兴趣的:(STM32与CH455g通信测试(仅键盘))