CH455 数码管驱动以及键盘控制芯片 应用笔记

    CH455是一款用于驱动数码管(LED)和矩阵键盘扫描控制芯片。能够动态驱动4位数码管或者32个LED。同时支持7x4的键盘扫描。单片机通过I2C对CH455进行读写,同时包括一个#INT中断引脚,任何一个按键按下都会触发中断,在INT引脚上产生低电平脉冲。

  主要特点:

  • 内置较大电流的驱动器,段电流达25mA,位电流达160mA
  • 支持8x4或7x4,能够直接控制4位数码管或32个LED
  • 能够设置8种亮度,由内部PWM驱动LED
  • 提供低电平有效的键盘中断,提供按键释放标志位,可通过该位来判断按键是否按下和释放。
  • 供电电压范围2.7~5V

    CH455内部的显示驱动电路和按键扫描电路是独立开的,两部分电路使用相同的引脚,分时对引脚进行驱动和读取。在显示驱动中,插入键盘键值读取操作。

 显示驱动

    显示驱动原理与HT1612段码屏驱动原理类似,都是以SEG[n:0]和DIG[m:0]分别作为行、列,组成一个寄存器矩阵,一共(n+1)*(m+1)位数据。将单个LED要显示的状态对应写进寄存器,芯片内部电路会按照寄存器中数据进行动态扫描输出。

       CH455对数码管和LED采用动态扫描驱动,顺序为DIG0~DIG3,当其中一个引脚吸入电流时,其他引脚不吸入电流。

    如下图中,若硬件上将SEG0~7的公共端接到DIG0时,若要左侧共阴数码管显示0,在要在SEG0地址寄存器中写入0B00111111,即0x3F。芯片会按照寄存器的值来驱动左侧数码管显示。


    寄存器地址:

键盘扫描

    键盘扫描时,DIG3~DIG0引脚用于列扫描输出,SEG6~SEG0引脚带有内部下拉电阻,用于行扫描输入。在键盘扫描期间,DIG0~DIG3一次输出高电平,其余引脚输出低电平,该状态下SEG0~SEG6引脚的输出被禁止。 CH455内部带有消抖功能,连续两次判断有按键按下才会被确认。当检测到按键后,会讲按键值存储在寄存器中,并在#INT引脚上产生低电平中断。

    注:当多个按键按下时,按键码较小的按键优先。

    按键码格式:bit7一直为0, bit2一直为1,bit[1:0]为列扫描码,bit[5:3]为行扫描码,bit6位状态码(按键按下为1,按键松开为0,判断该位的值来判断按键是否松开)。如连接DIG2和SEG5的按键被按下,则bit[1:0]=10,bit[5:3]=101,bit6=1,有

Key = 0B01101110 (0x6E)

    对应按键码如下,因为按下立即读键码寄存器是bit6=1,所以需要在按键编码上加上0x40



设置系统参数

    系统参数主要包括,显示驱动电路和键盘扫描使能,7/8段模式,8阶亮度控制,sleep模式。系统参数有一个字节控制,其中bit7和bit1一直为0,bit[6:4]控制亮度显示(000为8/8,001~111为1/8~7/8亮度),bit3控制7/8模式(0为8段,1为7段),bit2为sleep模式(写1使能,可通过按键唤醒或者操作指令唤醒),bit0为使能(高电平有效)。

    如需要让CH455工作在8段,最亮的情况下,则该值为0B00000001,,即0x01。


    总的来说,实际上只要对6个寄存器进行操作就行。

  1. 系统参数寄存器*1
  2. 键值寄存器*1
  3. 显示驱动寄存器*4


代码实现

下列为STM32应用代码,已经验证能够稳定使用,留言询问后方可转载。

ch455.h    

#ifndef __CH455_H
#define __CH455_H
#include "sys.h"

typedef unsigned char   UINT8;
typedef unsigned short  UINT16;	

#define high 	1
#define low 	0

/* 2线接口的连接,与实际电路有关 */
#define   CH455_SCL         PBout(4) //SCL
#define   CH455_SDA         PBout(5) //SDA


/* 2线接口的位操作,与单片机有关 */
#define		CH455_SCL_SET		{CH455_SCL=1;}
#define		CH455_SCL_CLR		{CH455_SCL=0;}
#define		CH455_SCL_D_OUT	  	{GPIOB->CRL&=0XFFF0FFFF;GPIOB->CRL|=(u32)3<<(4*4);}				      //  设置SCL为输出方向,对于双向I/O需切换为输出
#define		CH455_SDA_SET		{CH455_SDA=1;}
#define		CH455_SDA_CLR		{CH455_SDA=0;}
#define		CH455_SDA_IN		 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)     //  读取SDA输入电平
#define		CH455_SDA_D_OUT	  	{GPIOB->CRL&=0XFF0FFFFF;GPIOB->CRL|=(u32)3<<(5*4);}   // 设置SDA为输出方向,对于双向I/O需切换为输出
#define		CH455_SDA_D_IN		{GPIOB->CRL&=0XFF0FFFFF;GPIOB->CRL|=(u32)8<<(5*4);}   // 设置SDA为输入方向,对于双向I/O需切换为输入

/* ********************************************************************************************* */
// 设置系统参数命令

#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级亮度


// 加载字数据命令
#define CH455_DIG0		0x1400			// 数码管位0显示,需另加8位数据
#define CH455_DIG1		0x1500			// 数码管位1显示,需另加8位数据
#define CH455_DIG2		0x1600			// 数码管位2显示,需另加8位数据
#define CH455_DIG3		0x1700			// 数码管位3显示,需另加8位数据



// 读取按键代码命令
#define CH455_GET_KEY	0x0700					// 获取按键,返回按键代码


// CH455接口定义
#define		CH455_I2C_ADDR		0x40			// CH455的地址
#define		CH455_I2C_MASK		0x3E			// CH455的高字节命令掩码

// 对外子程序
extern void CH455_Init(void);           //初始化函数
extern	UINT8 CH455_Read( void );	// 从CH455读取按键代码
extern  void CH455_Write( UINT16 cmd );	// 向CH455发出操作命令
UINT8  CH455_I2c_RdByte( void );
void CH455_I2c_WrByte(unsigned char IIC_Byte);
void CH455_I2c_Stop();
void CH455_I2c_Start();

#endif	/* CH455_H */


ch455.c

/*
 * File:   CH455.c
 * Author: JiangXiaowei
 */

#include "ch455.h"		// 修改该文件以适应硬件环境/单片机型号等
#include "delay.h"

//定义
#define I2C_DELAY 5

void CH455_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟

	
	//stm32f103中PB3、PB4、PA15为JTAG引脚,若要作为普通IO口来使用的话,要禁用JTAG功能。
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);  
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_5); 	
	 
	CH455_Write( CH455_SYSON_8 );		//八段式
}

/*
 * 函数功能:IIC产生起始信号函数
 * 输入参数:无
 * 输出参数:无
 */
void CH455_I2c_Start()
{
    CH455_SDA_D_OUT;
    CH455_SCL = high;   //SCL = high;
    DelayUs(I2C_DELAY);
    CH455_SDA = high;   //SDA = high;
    DelayUs(I2C_DELAY);
    CH455_SDA = low;    //SDA = low;
    DelayUs(I2C_DELAY);
    CH455_SCL = low;    //SCL = low;
    DelayUs(I2C_DELAY);
}

/*
 * 函数功能:IIC产生停止信号
 * 输入参数:无
 * 输出参数:无
 */
void CH455_I2c_Stop()
{
    CH455_SDA_D_OUT;
    CH455_SCL = low;     //SCL = low;
    DelayUs(I2C_DELAY);
    CH455_SDA = low;     //SDA = low;
    DelayUs(I2C_DELAY);
    CH455_SCL = high;    //SCL = high;
    DelayUs(I2C_DELAY);
    CH455_SDA = high;    //SDA = high;
    DelayUs(I2C_DELAY);
}

/*
 * 函数功能:IIC发送一个字节
 * 输入参数:一个字节
 * 输出参数:无
 */
void CH455_I2c_WrByte(unsigned char IIC_Byte)
{
    unsigned char i;
    CH455_SDA_D_OUT;
    for(i = 0; i < 8; i++)
    {
        if(IIC_Byte & 0x80)
            CH455_SDA = high;   //SDA=high;
        else
            CH455_SDA = low;   //SDA=low;
        DelayUs(I2C_DELAY);
        CH455_SCL = high;      //SCL=high;
        DelayUs(I2C_DELAY);
        CH455_SCL = low;       //SCL=low;
        DelayUs(I2C_DELAY);
        IIC_Byte<<=1;
    }
    DelayUs(I2C_DELAY);
    CH455_SDA = high;          //SDA=1;
    DelayUs(I2C_DELAY);
    CH455_SCL = high;          //SCL=1;
    DelayUs(I2C_DELAY);
    CH455_SCL = low;           //SCL=0;
    DelayUs(I2C_DELAY);
}

unsigned char  CH455_I2c_RdByte( void )		//读一个字节数据
{    
    unsigned char i, bytedata;
    CH455_SDA_D_IN;     //将数据设置为输入模式
    DelayUs(I2C_DELAY);
    CH455_SDA = 1;      //数据线拉高
    DelayUs(I2C_DELAY);
    CH455_SCL = 0;
    DelayUs(I2C_DELAY);
    for(i = 0; i < 8; i++)      //读8位数据
    {
        CH455_SCL = 1;
        DelayUs(I2C_DELAY);
        bytedata <<= 1;
        DelayUs(I2C_DELAY);
        bytedata |= (CH455_SDA_IN);
        DelayUs(I2C_DELAY);
        CH455_SCL = 0;
        DelayUs(I2C_DELAY);
    }
    CH455_SDA_D_OUT;            //数据线设置回输出模式
    CH455_SDA = high;          //SDA=1;
    DelayUs(I2C_DELAY);
    CH455_SCL = high;          //SCL=1;
    DelayUs(I2C_DELAY);
    CH455_SCL = low;           //SCL=0;
    DelayUs(I2C_DELAY);
    return(bytedata);//返回数据
}

void CH455_Write( UINT16 cmd )	//写命令
{
	CH455_I2c_Start();               //启动总线
   	CH455_I2c_WrByte(((UINT8)(cmd>>7)&CH455_I2C_MASK)|CH455_I2C_ADDR);
   	CH455_I2c_WrByte((UINT8)cmd);     //发送数据
  	CH455_I2c_Stop();                 //结束总线 
}

UINT8 CH455_Read( void )		//读取按键
{
	UINT8 keycode;
   	CH455_I2c_Start();                //启动总线
   	CH455_I2c_WrByte((UINT8)(CH455_GET_KEY>>7)&CH455_I2C_MASK|0x01|CH455_I2C_ADDR);
   	keycode=CH455_I2c_RdByte();      //读取数据
	CH455_I2c_Stop();                //结束总线
	return keycode;
}

main.c  (部分)
//单片机头文件
#include "stm32f10x.h"

//
#include "delay.h"
#include "usart.h"
#include "timer.h"
#include "exti.h"

//硬件驱动
#include "Oled_IIC.h"
#include "sim800.h"
#include "ch455.h"
#include "led.h"

//C库
#include <string.h>


//全局变量
unsigned char usart1Len = 0;				//usart1接收的数据长度
unsigned char usart1Buf[64];				//usart1接收缓存

unsigned char usart2Len = 0;				//usart2接收的数据长度
unsigned char usart2Buf[64];				//usart2接收缓存
 
int main(void)
{
	unsigned char i,j;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		//中断控制器分组设置 
	Delay_Init();						//Systick初始化,用于普通的延时 
	OLED_Init();
	CH455_Init();
	UsartPrintf(USART1, "\r\nJiangXiaowei Design 2018-07-08 1358801713x\r\n");		//串口1打印
	OLED_P8x16Str(0,0,"2018-07-08");
	OLED_P8x16Str(0,2,"CH455 Test");

	while(1)
	{		
		CH455_Write( CH455_SYSON );         //抗干扰,定时刷新CH455寄存器
		CH455_Write( CH455_DIG0 | 0XFF );
		
		switch((CH455_Read()/8)%8)	
		{
			case 0:OLED_P8x16Str(0,4,"0x00 Stop      ");break;
			case 1:OLED_P8x16Str(0,4,"0x01 Head   Up ");break;
			case 2:OLED_P8x16Str(0,4,"0x02 Head Down ");break;
			case 3:OLED_P8x16Str(0,4,"0x03 Foot   Up ");break;
			case 4:OLED_P8x16Str(0,4,"0x04 Head Down ");break;
			case 5:OLED_P8x16Str(0,4,"0x05 Both   Up ");break;
			case 6:OLED_P8x16Str(0,4,"0x00 Both Down ");break;
			default:;//OLED_P8x16Str(0,6,usart2Buf);
		}
	}

}


  • 12
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
HC32L13X是一款32位ARM Cortex-M3内核的微控制器,而CH455H是一款4位5段共阳数码管驱动芯片。在使用HC32L13X驱动CH455H数码管时,可以采用以下步骤: 1. 确定连接方式 CH455H数码管有共阳和共阴两种接法,需要确定使用的是哪一种接法,并将数码管连接到HC32L13X的GPIO引脚上。 2. 编写初始化代码 在使用HC32L13X驱动CH455H数码管前,需要先对GPIO口进行初始化。可以通过以下代码实现: ```c // 初始化IO口 void init_gpio(void) { stc_gpio_init_t stcGpioCfg; // 使能GPIO外设时钟 CLK_FcgPeriphClockCmd(CLK_FCG_GPIO, Enable); // 配置引脚 stcGpioCfg.u16PinAttr = PIN_ATTR_OUTPUT; GPIO_Init(GPIO_PORT, GPIO_PIN, &stcGpioCfg); } ``` 3. 编写驱动代码 接下来,需要编写一个函数来驱动CH455H数码管的显示。可以通过以下代码实现: ```c // 数码管显示 void display(uint8_t data) { uint8_t i; // 设置数码管 GPIO_ResetPins(GPIO_PORT, GPIO_PIN); GPIO_SetPins(GPIO_PORT, 1 << (data & 0x0F)); // 延时 for (i = 0; i < 10; i++) { __NOP(); } // 清空数码管 GPIO_ResetPins(GPIO_PORT, GPIO_PIN); } ``` 4. 编写矩阵键盘代码 如果需要实现矩阵键盘的功能,可以通过以下代码实现: ```c // 矩阵键盘扫描 uint8_t scan_key(void) { uint8_t i, j; uint8_t key_val = 0xFF; // 设置行为高电平 for (i = 0; i < ROWS; i++) { GPIO_SetPins(GPIO_PORT_ROW, 1 << i); // 判断列是否有按键按下 for (j = 0; j < COLS; j++) { if (GPIO_GetBit(GPIO_PORT_COL, j) == 0) { key_val = i * COLS + j; break; } } // 复位行 GPIO_ResetPins(GPIO_PORT_ROW, 1 << i); if (key_val != 0xFF) { break; } } return key_val; } ``` 以上就是使用HC32L13X驱动CH455H数码管及矩阵键盘的实现示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值