2023年12月24日发(作者:)
7279键盘和数码管
7279简介
7279是一片具有串行接口的可同时驱动8位共阴式数码管(或64只独立LED)的智能显示驱动芯片该芯片。同时还可连接多达64键的键盘矩阵,单片即可完成LED显示,键盘接口的全部功能。
7279内部含有译码器可直接接受BCD码或16进制码,并同时具有2种译码方式(参见后文),
此外还具有多种控制指令如消隐闪烁左移右移段寻址等。
7279具有片选信号可方便地实现多于8位的显示或多于64键的键盘接口。
7279的指令
7279的指令分为两类――纯指令和带有数据的指令。
纯指令
1. 复位(清除)指令0xA4H
当7279收到此指令后,将所有的显示清除,执行该指令后,芯片7279的状态与刚上电时一样。
2. 测试指令0xBFH
该指令使所有的LED全部点亮,并处于闪烁状态,该指令主要用于测试。
在我们的实验中,只用到上述两条纯指令,还有很多其他纯指令,读者有兴趣可以下载7279的芯片手册自己学习。
1
带有数据的指令
读键盘数据指令0x15H
该指令从7279读出当前的按键代码。与其他指令不同,此命令的前一个字节00010101B为控制器传送到7279的指令,而后一个字节d0-d7则为7279返回的按键代码。其范围为0-0x3FH(无按键按下时是0xFFH)。
此指令的前半段,7279的DATA引脚处于高阻输入状态,以接受来自微处理器的指令;在指令的后半段,DATA引脚从输入状态变为输出状态,输出键盘代码的值。因此,微处理器连接到DATA引脚的I/O口应有一个从输出态到输入态的过程。
当7279检测到有效的按键时,KEY引脚从高电平变为低电平,并一直保持到按键结束。在此期间如果收到“读键盘数据指令”,则输出当前按键的键盘代码。如果收到读键盘数据指令时没有有效按键,则输出“0xFFH”。
串行接口
7279采用串行方式与微处理器通信,串行数据从DATA引脚输入芯片,并由CLK端同步。当片选信号变为低后,DATA引脚上的数据在CLK的上升沿被写入7279的缓冲器。
7279的指令结构有三种类型:
1. 不带数据的纯指令,指令的宽度为8个bit,即微处理器需要发送8个CLK脉冲。
2. 带有数据的指令,宽度为16bit,即微处理器需要发送16个CLK脉冲。
3. 读取键盘数据指令,宽度为16bit,前8个为处理器发送到7279的数据,后8个比特为7279返回的键盘代码。执行此指令时,7279的DATA端在第9个上升沿变为输出态,并于第16个脉冲的下降沿恢复为输入状态,等待接收下一个指令。
串行接口的时序如下图:
1. 纯指令
2. 带数据的指令
3. 读键盘指令
2
CPU与7279的连接
由于ARM既要向7279发送数据,又要接收7279发送的键盘代码,因此数据是双向传输。CPU工作在3.3V电压下,因此CPU接收引脚上的电压不得大于3.3V,否则会烧掉CPU,因此我们使用了74HC125这个器件进行电压转换。当GPG2为低时,1通道是开启的,2通道关闭。1通道开启一位着ARM向7279发送数据。2通道开启意味着ARM接收来自7279的数据。注意,1通道和2通道的片选信号是反的,因此在同一时间只能有一个通道是开启的。74HC125通过引脚SDIO与7279相连。1通道开启时,ARM通过SDIO向7279发送数据,2通道开启时7279通过SDIO向ARM发送数据。
S3C2410的片内资源-寄存器
Register
Address R/W Description
3
Reset
Value
GPBCON
GPBDAT
GPBUP
Reserved
0x56000010 R/W 端口B的引脚的配置
0x56000014 R/W 端口B的数据寄存器
0x56000018 R/W 端口B的上拉禁止寄存器
0x5600001C
Bit
[21:20]
[19:18]
[17:16]
[15:14]
[13:12]
[11:10]
[9:8]
[7:6]
[5:4]
[3:2]
[1:0]
– 保留
0x0
未定义
0x0
未定义
GPBCON
GPB10
GPB9
GPB8
GPB7
GPB6
GPB5
GPB4
GPB3
GPB2
GPB1
GPB0
Description
00 =输入 10 = nXDREQ0 01 =输出 11 =保留
00 =输入 10 = nXDACK0 01 =输出 11 =保留
00 =输入 10 = nXDREQ1 01 =输出 11 =保留
00 =输入 10 = nXDACK1 01 =输出 11 =保留
00 =输入 10 = nXBREQ
00 =输入 10 = nXBACK
00 =输入 10 = TCLK0
00 =输入 10 = TOUT3
00 =输入 10 = TOUT2
00 =输入 10 = TOUT1
00 =输入 10 = TOUT0
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
Register
GPDCON
GPDDAT
GPDUP
Reserved
Address
0x56000030
0x56000034
0x56000038
0x5600003C
R/W Description
R/W 端口D的引脚的配置
R/W 端口D的数据寄存器
R/W 端口D的上拉禁止寄存器
– 保留
Reset
Value
0x0
未定义
0xF000
未定义
GPDCON
GPD15
GPD14
GPD13
GPD12
GPD11
GPD10
GPD9
GPD8
GPD7
GPD6
GPD5
GPD4
GPD3
Bit
[31:30]
[29:28]
[27:26]
[25:24]
[23:22]
[21:20]
[19:18]
[17:16]
[15:14]
[13:12]
[11:10]
[9:8]
[7:6]
Description
00 =输入 10 = VD23
00 =输入 10 = VD22
00 =输入 10 = VD21
00 =输入 10 = VD20
00 =输入 10 = VD19
00 =输入 10 = VD18
00 =输入 10 = VD17
00 =输入 10 = VD16
00 =输入 10 = VD15
00 =输入 10 = VD14
00 =输入 10 = VD13
00 =输入 10 = VD12
00 =输入 10 = VD11
4
01 =输出 11 = nSS0
01 =输出 11 = nSS1
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
GPD2
GPD1
GPD0
[5:4]
[3:2]
[1:0]
00 =输入 10 = VD10
00 =输入 10 = VD9
00 =输入 10 = VD8
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
Register
GPFCON
GPFDAT
GPFUP
Reserved
Address R/W Description
Reset
Value
0x0
未定义
0x0
未定义
0x56000050 R/W 端口F的引脚的配置
0x56000054 R/W 端口F的数据寄存器
0x56000058 R/W 端口F的上拉禁止寄存器
0x5600005C – 保留
GPFCON
GPF7
GPF6
GPF5
GPF4
GPF3
GPF2
GPF1
GPF0
Bit
[15:14]
[13:12]
[11:10]
[9:8]
[7:6]
[5:4]
[3:2]
[1:0]
Description
00 = 输入 10 = EINT7
00 =输入 10 = EINT6
00 =输入 10 = EINT5
00 =输入 10 = EINT4
00 =输入 10 = EINT3
00 =输入 10 = EINT2
00 =输入 10 = EINT1
00 =输入 10 = EINT0
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
01 =输出 11 =保留
Register
GPGCON
GPGDAT
GPGUP
Reserved
Address R/W Description
Reset
Value
0x0
未定义
0xF800
未定义
0x56000060 R/W 端口G的引脚的配置
0x56000064 R/W 端口G的数据寄存器
0x56000068 R/W 端口G的上拉禁止寄存器
0x5600006C – 保留
GPGCON
GPG15
GPG14
GPG13
GPG12
GPG11
GPG10 (5V 限制输入)
GPG9 (5V 限制输入)
GPG8 (5V 限制输入)
GPG7
GPG6
Bit
[31:30]
[29:28]
[27:26]
[25:24]
[23:22]
[21:20]
[19:18]
[17:16]
[15:14]
[13:12]
Description
00 =输入 10 = EINT23 01 =输出 11 = nYPON
00 =输入 10 = EINT22 01 =输出 11 = YMON
00 =输入 10 = EINT21 01 =输出 11 = nXPON
00 =输入 10 = EINT20 01 =输出 11 = XMON
00 =输入 10 = EINT19 01 =输出 11 = TCLK1
00 =输入 10 = EINT18 01 =输出 11 =保留
00 =输入 10 = EINT17 01 =输出 11 =保留
00 =输入 10 = EINT16 01 =输出 11 =保留
00 =输入 10 = EINT15 01 =输出 11 = SPICLK1
00 =输入 10 = EINT14 01 =输出 11 = SPIMOSI1
5
GPG5
GPG4
GPG3
GPG2
GPG1
GPG0
[11:10]
[9:8]
[7:6]
[5:4]
[3:2]
[1:0]
00 =输入 10 = EINT13 01 =输出 11 = SPIMISO1
00 =输入 10 = EINT12 01 =输出 11 = CD_PWREN
00 =输入 10 = EINT11 01 =输出 11 = nSS1
00 =输入 10 = EINT10 01 =输出 11 = nSS0
00 =输入 10 = EINT9
00 =输入 10 = EINT8
01 =输出 11 =保留
01 =输出 11 =保留
实验源码
主函数Main
#include "2410header.h"
#include "7279.h"
void Main(void)
{
sysinit();
while(1)
{
Uart_Printf("nn 2410 Board (MCU S3C2410) 7279 Test nn");
Test_7279(); //7279的功能测试函数
}
}
功能测试函数Test_7279
void Test_7279(void)
{
int tmr;
int j;
int wait_cnter;
int key_number;
unsigned char digit[5];
Init(); //完成初始化,配置寄存器,代码见下面解释
delay10ms(10); //延迟
send_byte(CMD_RESET); //发送RESET命令,清屏,代码见下面
delay10ms(100);
send_byte(CMD_TEST); //测试指令,数码管闪烁
delay10ms(200);
send_byte(CMD_RESET); //数码管被清屏
delay10ms(10);
6
while(1) //这段代码用来测试键盘
{
do
{
if(!key) //如果有键按下,key为0
{
key_number = read7279(CMD_READ); //读取键盘码,代码见下面
switch(key_number) //根据键盘编码得到数据
{
case 0x03:return;
case 0x0b:key_number = 1;break;
case 0x13:key_number = 2;break;
case 0x1b:key_number = 3;break;
case 0x04:key_number = 4;break;
case 0x0c:key_number = 5;break;
case 0x14:key_number = 6;break;
case 0x1c:key_number = 7;break;
case 0x05:key_number = 8;break;
case 0x0d:key_number = 9;break;
case 0x15:key_number = 10;break;
case 0x1d:key_number = 11;break;
case 0x06:key_number = 12;break;
case 0x0e:key_number = 13;break;
case 0x16:key_number = 14;break;
case 0x1e:key_number = 15;break;
default:
key_number = 0xff;
}
write7279(DECODE1+1,key_number/16);//数码管显示代码见下面,因为有两只数码管显示,因此有两个函数。
}
初始化函数Init
void Init(void) //读者可以根据寄存器定义来看该函数的功能
}
write7279(DECODE1,key_number&0x0f);
while(!key);
wait_cnter = 0;
wait_cnter++;
}while(key_number!=0 && wait_cnter<0x0f00000); //如果按下0键就会退出
{
rGPFUP |= 0x0c; //上拉
rGPGUP |= 0x00e0; //上拉
setGPG2O; //宏定义,GPG2引脚设为output
7
setGPG7O; //宏定义,GPG7引脚设为output
setGPG6O; //宏定义,GPG6引脚设为output
setGPG5I; //宏定义,GPG5引脚设为input
setGPF2I; //宏定义,GPF2引脚设为input
setGPF3O; //宏定义,GPF3引脚设为output
setcsLOW; //片选信号置低,片选使能
rGPFDAT = rGPFDAT|0x04;
rGPGDAT = rGPGDAT&0xffbf;
}
宏定义
#define setGPG2O do{rGPGCON|=0x00000010;rGPGCON&=0xffffffdf;}while(0)
#define setGPG7O do{rGPGCON|=0x00004000;rGPGCON&=0xffff7fff;}while(0)
#define setGPG6O do{rGPGCON|=0x00001000;rGPGCON&=0xffffdfff;}while(0)
#define setGPG5I do{rGPGCON&=0xfffff3ff;}while(0)
#define setGPF2I do{rGPFCON&=0xffcf;}while(0)
#define setGPF3O do{rGPFCON|=0x0040;rGPFCON&=0xff7f;}while(0)
#define setclkHIGH rGPGDAT|=0x0080
#define setclkLOW rGPGDAT&=~0x0080
#define setdatHIGH rGPGDAT|=0x0040
#define setdatLOW rGPGDAT&=~0x0040
#define setcsLOW rGPFDAT&=0xf7
#define setcsHIGH rGPFDAT|=~0xf7
#define setGPG2LOW rGPGDAT&=~0x0004
#define setGPG2HIGH rGPGDAT|=0x0004
#define dat (rGPGDAT&0x0020)>>5
#define key ((rGPFDAT&0x04)>>2)
#define cs (rGPFDAT&0x08)>>3
对照寄存器定义,读者应该能明白各个宏的意义。
发送字节数据send_byte
void send_byte(unsigned char out_byte)
{
unsigned char i;
setGPG2LOW; //GPG2使能就是ARM向7279发数据,通道开启
long_delay();
for(i=0;i<8;i++)
{
if(out_byte&0x80) //因为是串行接口,因此一位一位输出
{
setdatHIGH;
}
else
{
setdatLOW;
8
}
}
}
setclkHIGH; //时钟脉冲
short_delay(); //延迟
setclkLOW; //时钟脉冲
short_delay(); //延迟
out_byte= out_byte*2; //左移一位,因为前一位已经输出。
setdatLOW;
接收字节数据receive_byte
unsigned char receive_byte(void)
{
unsigned char i, in_byte;
setGPG2HIGH; //ARM接收7279的数据,因此GPG2置高,开启7279向ARM发送数据的通道,见电路图可以明白
short_delay();
for(i=0;i<8;i++)
{
setclkHIGH; //时钟脉冲
short_delay();
in_byte=in_byte*2;
if(dat) //数据引脚上有高电平,它的定义为#define dat
{
(rGPGDAT&0x0020)>>5
in_byte = in_byte|0x01; //如果数据引脚上是高电平,则低位置1
}
setclkLOW; //时钟脉冲
short_delay();
}
setGPG2LOW; //关闭该通道
return (in_byte); //返回
}
实验内容
根据前面的原理介绍,写一个程序来测试7279键盘和数码管。有兴趣的同学还可以实现7279控制键盘的其他功能。
实验步骤
1. 阅读前面的原理介绍,了解7279的工作原理以及与ARM的通信过程。
2. 阅读该实验的参考源码,理解源码的实现过程。更深层次理解7279的控制过程。
3. 自己编写一个程序来测试7279键盘和数码管的基本功能。
9


发布评论