我的HD7279学习笔记
Created on: 2012-9-7
Author: zhang bin
学习笔记
for msp430g2553
redesigned by zhang bin
2012-09-07
versions:12_09_01
HD7279的基本说明如下:
HD7279是一片具有串行接口的,可同时驱动8位共阴式数码管(或64只独立led)的智能显示驱动芯片,该芯片同时还可连接多达64键的键盘矩阵,单片即可完成led显示、键盘接口的全部功能。
HD7279内部含有译码器,可直接接受BCD码或16进制码,并同时具有2种译码方式。此外,还具有多种控制指令,如消隐、闪烁、左移、右移、段寻址等。
HD7279具有片选信号,可方便地实现多于8位的显示或多于64键的键盘接口。
典型应用:
仪器仪表,工业控制,条形显示器,控制面板
特点:
1 串行接口,无需外围元件可直接驱动led
2 各位独立控制译码/不译码及消隐和闪烁属性
3 (循环)左移/(循环)右移指令
4 具有段寻址指令,方便控制独立led
5 64键键盘空盒子器,内含去抖动电路
6 有DIP和SOIC两种封装形式供选择
引脚说明:
2.引脚说明:
VDD: 正电源 VSS: 地
CS: 片选 CLK: 时钟输入端
DATA: 串行数据输入/输出端 CLK0: 振荡输出端
KEY: 按键有效输出端 RES: 复位端
SG-SA: 段g—段a驱动输出
DP: 小数点驱动输出 DIG0-7: 数位0-7驱动输出
RC: RC振荡器连接端
HD7279A的控制指令分为二大类——纯指令和带有数据的指令
具体的这两种指令的详解,参考数据手册。
上面的说明是摘录数据手册上的,只介绍了HD7279的基本大概情况,更详细的介绍如:读写时序、详细命令等,就要参考数据手册了。
用单片机对各种外围芯片、器件进行操作的时候,主要是处理好相互的通信。那么就要特别注意手册上介绍的操作的时序,写程序的时候,要严格按照时序写就行了。
下面是我写的对HD7279进行操作的一个程序,是基于msp430g2553单片机的,可以控制4*4的16矩阵键盘。目前对led的操作还没有实现,需要继续完善程序,程序贴在了下面,注释的也比较详细:
//本程序是为了测试键盘、led驱动芯片HD7279所写的,主要完成HD7279读,写操作,控制4*4矩阵键盘和4led
//4个led分别接到了DIG0~DIG3
//目前这4个led还没有控制得住,要继续努力
#include <msp430g2553.h>
#include "ser_12864.h"
//HD7279各个管脚定义
#define SET_CS P1OUT |= BIT0;
#define CLR_CS P1OUT &= ~BIT0;
#define SET_CLK P1OUT |= BIT1;
#define CLR_CLK P1OUT &= ~BIT1;
#define DATA_IN P1DIR &= ~BIT2; //data脚设为输入
#define DATA_OUT P1DIR |= BIT2; //data脚设为输出
#define SET_DATA P1OUT |= BIT2;
#define CLR_DATA P1OUT &= ~BIT2;
//#define DATA P1IN&BIT2;
//#define KEY P1IN&BIT3;
//HD7279基本命令定义
#define CMD_RESET 0xa4 //复位(清除)指令
#define CMD_TEST 0xbf //测试指令
#define RTL_UNCYL 0xa1 //左移指令
#define RTR_UNCYL 0xa0 //右移指令
#define RTL_CYCLE 0xa3 //循环左移指令
#define RTR_CYCLE 0xa2 //循环右移指令
#define DECODE0 0x80 //方式0译码
#define DECODE1 0xc8 //方式1译码
#define UNDECODE 0x90 //不带小数点显示
#define BLINKCTL 0x88 //闪烁控制
#define ACTCTL 0x98 //消隐控制
#define SEGON 0xe0 //段点亮指令
#define SEGOFF 0xc0 //段关闭指令
#define CMD_READ 0x15 //读取键盘数据指令
//long_delay short_delay 延时57us 延时11us
#define long_delay() delay_us(57);
#define short_delay() delay_us(11);
uint key_code[]={61,36,37,38,44,45,46,52,53,54}; //键盘上的数字键对应的键值,在程序中要进行处理,要转化为0~9
//数组中为数字0~9对应的键值,顺序不能变
uchar key=0; //按下的键码
//向HD7279中发送指令 相当于写纯指令
void send_byte(uchar com)
{
uchar i=0;
CLR_CS;
long_delay();
for (i=0;i<8;i++) //发送命令,高位在前 一个时钟脉冲,送一位数据到7279中
{
if (com&0x80) //高位在前
{
SET_DATA;
}
else
{
CLR_DATA;
}
SET_CLK; //发生脉冲
short_delay();
CLR_CLK;
short_delay();
com <<= 1; //左移一位
}
CLR_DATA;
}
//从7279中读取数据
uchar receive_byte(void)
{
unsigned char i, in_byte;
SET_DATA; // set to input mode
long_delay();
for (i=0;i<8;i++)
{
SET_CLK;
short_delay();
in_byte = in_byte<<1;
DATA_IN; //把DATA脚设为输入 DATA为P12
if (P1IN&BIT2)
{
in_byte=in_byte|0x01;
}
CLR_CLK;
short_delay();
}
DATA_OUT; //把data设为输出
CLR_DATA;
return (in_byte);
}
//向7279中写入带数据的指令
void wr_data_com(uchar com,uchar data) //先发送指令,再发送数据
{
send_byte (com); //发送指令
send_byte (data); //发送数据
}
//从7279中读取键盘数据函数
uchar rd_key()
{
send_byte(CMD_READ); //先写入读取键盘数据的指令
return(receive_byte()); // 返回 接收到的数据,即为键值
}
//7279的初始化函数
void hd7279_init()
{
delay_ms(50); //上电延迟
P1DIR |= BIT0+BIT1+BIT2; //单片机相关IO口设置
// P1DIR &= ~BIT3; //KEY为输入
send_byte(CMD_RESET); //输入清除指令
delay_ms(50);
}
//因为当HD7279A检测到有效的按键时,KEY引脚从高电平变为低电平,并一直保持到按键结束,所以可以用下降沿出发,也可以用上升沿出发
void interrupt_init()
{
//在本程序中,按键按下于不按下,key的电平要么为高,要么为低,是确定的,不会有悬空浮动状态,所以下面两句内部拉电阻的设置可以不用要
// P1REN |= BIT3; // pullup 内部上拉电阻使能
//// //使用中断时,使能内部的上拉电阻这样当该脚悬空是,电平不会跳变,防止悬空时电平跳变不停的触发中断
// P1OUT = BIT3; // 当引脚上的上拉或下拉电阻使能时,PxOUT选择是上拉还是下来
//// //0:下拉,1:上拉
P1IE |= BIT3; // P1.3 interrupt enabled P13中断使能
P1IES |= BIT3; // P1.3 Hi/lo edge 下降沿中断
P1IFG &= ~BIT3; // P1.3 IFG cleared 中断标志位清零
}
void main(void)
{
unsigned char s1[] ={"key:"};
WDTCTL = WDTPW+WDTHOLD; // 停止看门狗定时器
BCSCTL1 = CALBC1_12MHZ; //设定cpu时钟DCO频率为12MHz
DCOCTL = CALDCO_12MHZ;
P2DIR |=BIT5+BIT4; //液晶的两条线
init_lcd();
hd7279_init();
interrupt_init(); //IO中断初始化
P1DIR |= BIT6;
P1OUT &= ~BIT6;
wr_string(0,0,s1); //第一行第一个位置显示s1
_BIS_SR(LPM4_bits + GIE); //进入LPM4 开中断
}
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
uchar i=0;
_DINT();
P1OUT |= BIT6;
key=rd_key(); //读取键值
// while((P1IN&BIT3)==0); //等待按键松开
for(i=0;i<10;i++)
{
if(key==key_code[i]) //利用数组进行键值转化
key=i; //转化为了对应的数字
}
wr_int(1,0,key); //显示
P1IFG &= ~BIT3; //中断标志位清零
_EINT(); //打开中断
}
//下面是用死循环检测按键按下,这种方法可以,但是不灵敏,并且浪费cpu资源 改进是用key出发IO口中断,然后进行键盘处理
//for(;;) //用死循环检测按键按下
//{
// if((P1IN&BIT3)==0) //当HD7279A检测到有效的按键时,KEY引脚从高电平变为低电平,并一直保持到按键结束。在此期间,
// //如果HD7279A接收到‘读键盘数据指令’,则输出当前按键的键盘代码; 如果在收到‘读键盘指令’时没有有效按键,HD7279A将输出FFH。
//
// {
// key=rd_key(); //读取键值
// while((P1IN&BIT3)==0); //等待按键松开
// }
// wr_int(2,0,key); //显示
//}
//对应键值:1-36 2-37 3-38 4-44 5-45 6-46 7-52 8-53 9-54 0-61 *-60 #-62 A-39 B-47 C-55 D-63