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