1) CH451简介
CH451可用于LED数码管显示驱动、键盘扫描控制、μP监控电路等领域。芯片封装包括双列直插DIP28、SOP28以及DIP24S封装。其内置RC振荡电路,可以直接动态驱动8位数码管或者64位LED,具有BCD译码或不译码功能,可实现数据的左移、右移、左循环、右循环、各数字独立闪烁等控制功能。CH451内置大电流驱动级,段电流不小于30 m A,字电流不小于160mA,并有16级亮度控制功能。该器件内置64键键盘控制器,可实现8×8矩阵键盘扫描,并内置去抖动电路,可提供按键中断与按键释放标志位等功能。CH451可选择简洁的1线串行接口或高速4线串行接口,且内置上电复位,可提供高电平有效复位和低电平有效复位两种输出,同时内置看门狗电路。整合了数码管显示驱动和键盘扫描控制以及μP监控的多功能外围芯片。用CH45l扩展键盘显示接口,具有接口简单、占用CPU资源少、外围器件简单、性价比高等优点,可在各种单片机系统中得到广泛的应用。
2)CH451操作命令介绍
CH451共有11条操作命令,每条操作命令均为12位,其中高4位为标识码,低8位为参数,x可为任意值(下同)
空操作(0000xxxxxxxxB)
空操作命令对CH451不产生任何影响,该命令可以在多个CH451级联的应用中透过前级CH451向后级cH451发送操作命令,而不影响前级cH451的状态。例如,要将操作命令001000000001B发送给两级级联电路中的后级CH45l(后级CH451的DIN引脚连接到前级CH451的DOUT引脚),只要在该操作命令后添加空操作命令000000000000B再发送,那么,该操作命令将经过前级cH451到达后级cH451,而空操作命令留给了前级CH451。另外,为了在不影响CH45l的前提下变化DCLK以清除看门狗计时器,也可以发送空操作命令。在非级联的应用中,空操作命令可只发送高4位。
芯片内部复位(001000000001B)
内部复位命令可将CH451的各个寄存器和各种参数复位到默认的状态。芯片上电时,CH45l均被复位,此时各个寄存器均复位为0,各种参数均恢复为默认值。
字数据左移(001100000000B)
字数据左移命令将CH45l的字数据左移一次,即从DIGO向DIG7移动一位,然后最右边的DIG0补进数据00H。例如,在数码管DIG7~I)IGO显示“87654321”时,执行字数据左移命令,显示变为“765432l”(不译码方式)或者“76543210”(BCD译码方式)。
字数据右移(001100000010B)
字数据右移命令将cH45l的字数据右移一次,即从DIG7向DIGO移动一位,然后最左边的DIG7补进数据00H。例如,在数码管DIG7~DIGO显示“8”7654321”时,执行字数据右移命令,显示变为“8765432”(不译码方式)或者“08765432”(BCD译码方式)。
字数据左循环(001100000001B)
字数据左循环命令将CH451的字数据左循环一次,即从DIGO向DIG7移动一位,然后最右边的DIGO补进原DIG7的数据。例如,在数码管DIG7-DIGO显示“8”765432l”时,执行字数据左循环命令,显示变为“76543218”。
字数据右循环(001100000011B)
字数据右循环命令将CH451的字数据右循环一次,即从DIG7向DIGO移动一位,然后最左边的DIG7补进原DIG0的数据。例如,在数码管DIG7-DIGO显示“8765432l”时,执行字数据右循环命令,显示变为“18765432"。
设定系统参数(010000000WDOG][KEYB][DIsP]B)
该命令用于设定cH451的系统级参数,如看门狗使能wDOG,键盘扫描使能KEYB,显示驱动使能DISP。各个参数均可通过1位数据来进行控制,将相应的数据位置为1可启用该功能,否则关闭该功能(默认值)。
设定显示参数(0101[MoDE][LIMIT][INTENSITY]B)
此命令用于设定CH45l的显示参数,如译码方式MODE(1位)、扫描极限LIMIT(3位)、显示亮度INTENSITY(4位)等。译码方式MODE为1时选择BcD译码方式,为0时选择不译码方式。CH451默认工作于不译码方式,此时8个数据寄存器中字节数据的位7-位0分别对应8个数码管的小数点和段G~段A,当数据位为1时,对应的数据段(或发光管)点亮;数据位为O时熄灭。cH451工作于BcD译码方式主要应用于数码管驱动,单片机只要给出二进制数的BcD码,便可由CH451将其译码,并直接驱动数码管以显示对应的字符。BcD译码方式是对数据寄存器中字节数据的位4~位0进行兼容BcD的译码,可用于控制段驱动引脚SEG6~SEGO的输出,它们对应于数码管的段G-段A,同时可用字节数据的位7控制段来驱动引脚SEG7的输出以对应数码管的小数点,字节数据的位6和位5不影响BcD译码的输出,它们可以是任意值。将位4~位0进行BCD译码可显示以下28个字符,其中00000B-0ll11B分别对应于“0~F”,10000B-11010B分别对应于“”空格、“+”、+或加号、“一”或减号、“=”等于号、“左方括号”、“右方括号”、“一”下划线、“H”、“L”、“P”、“.”小数点、其余值为空格。
扫描极限uMIT控制位00lB~1l1B和000B(默认值)可分别设定扫描极限1~7和8。显示亮度INTENSITY控制位的0001B~1111B和0000B(默认值)则用于分别设定显示驱动占空比1/16~15/16和16/16,以实现16级显示亮度控制。
设定闪烁控制(0110[D7s1][D6S][D5s][D4S][D3S][D2S][D1S][D0S]B)
设定闪烁控制命令用于设定CH451的闪烁显示属性,其中D7s-130S分别对应于8个字驱动DIG7~DIGO。闪烁属性D7s-DOS分别通过l位数据控制,将相应的数据位置为1可使能闪烁显示,否则为正常显示,不闪烁(默认值)。
加载字数据(1[DIG-ADDR]DIG—DATAlB)
加载字数据命令用于将字节数据DIG_DATA(8位)写入DIG_ADDR(3位)指定的数据寄存器中。DIG_ADDR的000B-111B分别用于指定数据寄存器的地址O~7,并分别对应于DIGO-DIG7引脚驱动的8个数码管。DIG_DATA为待写入的字节数据。
读取按键代码(0111xxxxxxxxB)
读取按键代码命令用于获得cH451最近检测到的有效按键的按键代码。该命令是唯一的具有数据返回的命令,CH451通常从DOUT引脚输出按键代码,按键代码总是7位数据,最高位是状态码,位5~位O是扫描码。读取按键代码命令的位数据B7-B0可以是任意值,所以控制器可以将该操作命令缩短为4位数据Bl1~B8。例如,CH451检测到有效按键并中断时,如按键代码是5EH,则先向CH451发出读取按键代码命令011lB,然后再从DOUT获得按键代码5EH。
CH451所提供的按键代码为7位,位2一位O是列扫描码,位5~位3是行扫描码,位6是状态码(键按下为1,键释放为O)。例如,连接DIG3与SEG4的键被按下时,按键代码为63H,键被释放后,按键代码是23H。单片机可以在任何时候读取按键代码,但一般在CH451检测到有效按键而产生键盘中断时读取按键代码,此时按键代码的位6总是1。另外,如果需要了解按键何时释放,单片机可以通过查询方式定期读取按键代码,直到按键代码的位6为0。表1是连接在DIG7-DIGO与SEG7-SEGO之间的键被按下时,CH451所提供的按键代码。这些按键代码具有一定的规律,如果需要键被释放时的按键代码,可将表2中的按键代码的位6置0,也可将表中的按键代码减去40H。应注意的是CH451不支持组合键,也就是说,同一时刻,不能有两个或者更多的键被按下。
表1 CH451按键代码
3) 硬件连接
CH451能够一次性驱动8位数码管,与单片机串行通信。支持数码管的左移,右移,左循环,右循环,独立闪烁,16级亮度控制等功能。是单片机控制多个数码管的得力助手,现将MEGA16单片机(MEGA16是AVR单片机,改程序稍加修改可以应用到8051单片机,PIC单片机,MSP430单片机上)驱动CH451的程序发布,希望能有所用。CH451的详细资料可去官方网站下载。图1为硬件连接电路图。
图1: CH451与LED数码管连接电路图
四)程序实例
AVRCH451驱动程序头文件
#ifndef_CH451_H
#define_CH451_H
#include<avr/io.h>
//CH451命令宏定义
#defineCH451_RESET0x0201//复位
#defineCH451_LEFT MOV 0x0300//设置移动方式-左移
#defineCH451_LEFTCYC0x0301//设置移动方式-左循
#defineCH451_RIGHT MOV 0x0302//设置移动方式-右移
#defineCH451_RIGHTCYC0x0303//设置移动方式-右循
#defineCH451_SYSOFF0x0400//关显示、键盘、看门狗
#defineCH451_SYSON10x0401//开显示
#defineCH451_SYSON20x0403//开显示、键盘
#defineCH451_SYSON30x0407//开显示、键盘、看门狗功能
#defineCH451_DSP0x0500//设置默认显示方式
#defineCH451_BCD0x0580//设置BCD译码方式
#defineCH451_TWINKLE0x0600//设置闪烁控制
#defineCH451_KEY0x0700//读键盘代码
#defineCH451_DIG00x0800//数码管位0显示
#defineCH451_DIG10x0900//数码管位1显示
#defineCH451_DIG20x0A00//数码管位2显示
#defineCH451_DIG30x0B00//数码管位3显示
#defineCH451_DIG40x0C00//数码管位4显示
#defineCH451_DIG50x0D00//数码管位5显示
#defineCH451_DIG60x0E00//数码管位6显示
#defineCH451_DIG70x0F00//数码管位7显示
//端口宏定义
#defineDCLK(1<<;PA3)
#defineDIN(1<<;PA5)
#defineLOAD(1<<;PA7)
#defineDOUT(1<<;PE5)
#defineCH451_DCLK_HIGHPORTA|=DCLK//时钟信号
#defineCH451_DCLK_LOWPORTA&=~DCLK
#defineCH451_DIN_HIGHPORTA|=DIN//数据输入
#defineCH451_DIN_LOWPORTA&=~DIN
#defineCH451_LOAD_HIGHPORTA|=LOAD//命令加载信号,上升延激活
#defineCH451_LOAD_LOWPORTA&=~LOAD
#defineCH451_DOUTPINE&DOUT//键盘中断和键值数据输出
externucharKeyValue;//键值全局声明
//函数申明
voidCH451_WriteCommand(uintCommand);//CH451写命令函数
voidCH451_Init();//CH451初始化函数
voidCH451_GetKeyValue();//CH451键盘代码读取函数
voidCH451_DisplayDig(ucharDIG,ucharData,ucharPoint);//CH451显示一位数码管函数
#endif
AVR CH451驱动程序文件
#include"CH451.h"
ucharKeyValue;//键值
//共阴数码管编码表
constucharDSYCode[18]={0x3F,0x06,0x5B,0x4F,//0,1,2,3
0x66,0x6D,0x7D,0x07,//4,5,6,7
0x7F,0x6F,0x77,0x7C,//8,9,A,b
0x39,0x5E,0x79,0x71,//C,d,E,F
0x40,0x00};//-,全灭
constuintDigCode[8]={CH451_DIG0,CH451_DIG1,CH451_DIG2,CH451_DIG3,
CH451_DIG4,CH451_DIG5,CH451_DIG6,CH451_DIG7};
//键盘编码表
constucharKeyCode[16]={0x40,0x41,0x42,0x43,//0,1,2,3
0x48,0x49,0x4A,0x4B,//4,5,6,7
0x50,0x51,0x52,0x53,//8,9,A,B
0x58,0x59,0x5A,0x5B};//C,D,E,F
//CH451写命令函数
voidCH451_WriteCommand(uintCommand){
uchari;
CH451_LOAD_LOW;//命令开始
for(i=0;i<12;i++){//送入12位数据,低位在前
if(Command&0x0001)CH451_DIN_HIGH;//输出低位数据
elseCH451_DIN_LOW;
CH451_DCLK_LOW;
Command>>=1;//数据右移一位
CH451_DCLK_HIGH;//上升沿有效
}
CH451_LOAD_HIGH;//加载数据
}
//CH451初始化函数
voidCH451_Init(){
CH451_DIN_LOW;//低电平使能串行接口
CH451_DIN_HIGH;
CH451_WriteCommand(CH451_RESET);//复位CH451
CH451_WriteCommand(CH451_SYSON2);//开显示、键盘
DDRE&=~DOUT;//PE5输入方向
EICRB|=(1<<ISC51);//PE5下降沿触发中断
EIMSK|=(1<<INT5);//PE5开外部中断
}
//CH451键值读取函数
voidCH451_GetKeyValue(){
uchari;
ucharGetKeyValue=0x00;//键盘代码
CH451_WriteCommand(CH451_KEY);//发送读取键值命令
for(i=0;i<7;i++){
GetKeyValue<<=1;
if(CH451_DOUT)GetKeyValue|=1;//从高到低读入451的数据
elseGetKeyValue|=0;
CH451_DCLK_LOW;//下降沿有效
CH451_DCLK_HIGH;
}
if(GetKeyValue==0x00)return;//读出键码为0跳过
for(i=0;i<16;i++){//查找键盘代码对应的键值
if(GetKeyValue==KeyCode){
KeyValue=i;
break;
}
}
}
//CH451显示一位数码管,DIG选择数码管,Data要显示的数字,Point是否显示小数点
voidCH451_DisplayDig(ucharDIG,ucharData,ucharPoint){
if(Point==1)CH451_WriteCommand(DigCode[DIG]|(DSYCode[Data]|0x80));
elseCH451_WriteCommand(DigCode[DIG]|DSYCode[Data]);
}