返回介绍

实验五 键盘和 LED 发光二极管显示电路

发布于 2023-05-14 20:35:30 字数 17701 浏览 0 评论 0 收藏 0

一.实验说明

在DSP的应用系统中,为实现人――机对话,显示和键盘是两个必不可少的功能配置。在本实验程序设计中,用键盘的响应作I/O端口的输入,用I/O端口的输出点亮发光二极管,形成的键盘、LED电路如图4.1所示。

二.实验目的

1. 学会配合使用键盘与发光二极管的编程方法。

2. 进一步认识TMS320LF2407芯片的I/O端口的功能及控制方法。

三.实验内容

1.用TMS320LF2407芯片设计并调试一个能使8只发光二极管按8种花样显示。

2.给按键定义各种不同功能,以实现对发光二极管循环顺序和点亮个数的控制。

四.实验参考程序清单

通过编程,使8只发光二极管实现如下显示功能:按下K1键,可点亮8种不同组合的发光二极管花样模式显示,按8次为一个循环周期;当按下一次K2键,将使设定的发光二极管显示的个数加1;当按下一次K3键,将使设定的发光二极管的位置往右移1位;当按下K4键或不按键时,返回到循环点亮发光二极管模式。

用通用定时器1产生10ms作为时基,用中断编程方法实现延时,再用软件计数得到10s延时。

C程序

I/O端口作为输入和输出使用

源程序代码:

(2) 所需的复位和中断向量定义文件“vectors.asm”同于前。在这以后的所有例程中,如果没有特别说明,vectors.asm都是相同的。

(3) 主程序

// 该程序用于键盘的识别,按键情况通过LED表示.

#include "register.h"

// 初始化子程序

initial()

{

asm(" setc SXM"); // 抑制符号位扩展

asm(" clrc OVM"); // 累加器中结果正常溢出

asm(" clrc CNF"); // B0被配置为数据存储空间

*SCSR1=0x81FE; // CLKIN=6M,CLKOUT=4*CLKIN=24M

*WDCR=0x0E8; // 不使能看门狗,因为SCSR2中的WDOVERRIDE

// 即WD保护位复位后的缺省值为1,故可以用

// 软件禁止看门狗

*IMR=0x0000; // 禁止所有中断

*IFR=0x0FFFF; // 清除全部中断标志,"写1清0"

*MCRA=*MCRA&0x0FF; // IOPB端口配置为一般的I/O功能

*PBDATDIR=*PBDATDIR|0x0FF00;// IOPB端口设置为输出方式

*MCRC=*MCRC&0x03FF; // IOPF2端口和IOPF3~6配置为一般的I/O功能

*PFDATDIR=*PFDATDIR|0x0400;// IOPF2端口为输出端口,IOPF3-IOPF6为输入端口

*PBDATDIR=*PBDATDIR&0x0FF00; // 熄灭全部的LED灯

*PFDATDIR=*PFDATDIR|0x0404; // IOPF2 设置为输出方式,且IOPF2=1

*PFDATDIR=*PFDATDIR&0x0FFFB; // IOPF2=0

// 以上的操作产生一个脉冲,使LED全部熄灭

}

// 屏蔽中断子程序

void inline disable()

{

asm(" setc INTM");

}

int keyscan( )

{

int k,j; // 定义局部变量

k=*PFDATDIR&0x0078; // 读入键盘状态并屏蔽掉相应的位

if(k == 0x0078) k=0;

else k=1; // 有键按下,则k=1

if(k == 1) // 若无键按下,则直接返回

{

for(j=30000;j>0;j--) j=j; // 若有键按下,则延时消抖动

k=*PFDATDIR&0x0078; // 读入键盘状态并屏蔽掉相应的位

if(k == 0x0078) k=0;

else k=1; // 有还有键按下,则k=1

}

return(k); // 返回K值

}

int keyserve( ) // 键服务子程序

{

int k; // 定义局部变量

k=*PFDATDIR&0x0078; // 读入键盘状态并屏蔽掉相应的位

switch(k)

{

case 0x0070:*PBDATDIR=(*PBDATDIR&0xFF00)|0X0001;break;

// 若按下K1键,则显示"1"

case 0x0068:*PBDATDIR=(*PBDATDIR&0xFF00)|0X0002;break;

// 若按下K2键,则显示"2"

case 0x0058:*PBDATDIR=(*PBDATDIR&0xFF00)|0X0003;break;

// 若按下K3键,则显示"3"

case 0x0038:*PBDATDIR=(*PBDATDIR&0xFF00)|0X0004;break;

// 若按下K4键,则显示"4"

default:*PBDATDIR=*PBDATDIR;

}

*PFDATDIR=*PFDATDIR|0x0404; // IOPF2 设置为输出方式,且IOPF2=1

*PFDATDIR=*PFDATDIR&0x0FFFB; // IOPF2=0

// 以上给一个脉冲,使B端口的值显示出来

}

main( )

{

disable( ); // 屏蔽所有中断

initial( ); // 系统初始化

while(1)

{

int i; // 定义局部变量

i=0;

i=keyscan(); // 键盘扫描,若有键按下,则返回值为"1",否则返回值为"0"

if(i==1) keyserve(); // 如果有键按下,则进行键服务程序

}

}

// 直接返回中断服务子程序

void interrupt nothing()

{

return;

}

汇编程序

st0_temp .usect ".b20",1 ;60

st1_temp .usect ".b20",1 ;61

context .usect ".b20",7 ;62-68

STACK . usect ".stack",40

IOSFT_REG .usect ".data0",1 ;280 ; IOPB SHIFT REG

IO_COUNT .usect ".data0",1 ;281 ; IO COUNT REG

IO_DATA .usect ".data0",1 ;282 ; I/O临时数据缓冲区

LEDXS .usect ".data0",1 ;283 ; LED显示的数据

LEDFLAG .usect ".data0",1 ;284 ; LED显示标志

K1FLAG .usect ".data0",1 ;285 ; K1 标志寄存器

KEYDATA .usect ".data0",1 ;286

KEYTIMER .usect ".data0",1 ;287

DP_USER .set 5

.include "F2407REGS.H"

.def _c_int0

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.sect ".vectors" ;定义主向量段

RSVECT B _c_int0 ; PM 0 Reset Vector 1

INT1 B PHANTOM ;GISR1 ; PM 2 Int level 1 4

INT2 B GISR2 ; PM 4 Int level 2 5

INT3 B PHANTOM ; PM 6 Int level 3 6

INT4 B PHANTOM ; PM 8 Int level 4 7

INT5 B PHANTOM ;GISR5; PM A Int level 5 8

INT6 B PHANTOM ; PM C Int level 6 9

RESERVED B PHANTOM ; PM E (Analysis Int) 10

SW_INT8 B PHANTOM ; PM 10 User S/W int -

SW_INT9 B PHANTOM ; PM 12 User S/W int -

SW_INT10 B PHANTOM ; PM 14 User S/W int -

SW_INT11 B PHANTOM ; PM 16 User S/W int -

SW_INT12 B PHANTOM ; PM 18 User S/W int -

SW_INT13 B PHANTOM ; PM 1A User S/W int -

SW_INT14 B PHANTOM ; PM 1C User S/W int -

SW_INT15 B PHANTOM ; PM 1E User S/W int -

SW_INT16 B PHANTOM ; PM 20 User S/W int -

TRAP B PHANTOM ; PM 22 Trap vector -

NMI B PHANTOM ; PM 24 Non maskable Int3

EMU_TRAP B PHANTOM ; PM 26 Emulator Trap 2

SW_INT20 B PHANTOM ; PM 28 User S/W int -

SW_INT21 B PHANTOM ; PM 2A User S/W int -

SW_INT22 B PHANTOM ; PM 2C User S/W int -

SW_INT23 B PHANTOM ; PM 2E User S/W int -

SW_INT24 B PHANTOM ; PM 30 User S/W int -

SW_INT25 B PHANTOM ; PM 32 User S/W int -

SW_INT26 B PHANTOM ; PM 34 User S/W int -

SW_INT27 B PHANTOM ; PM 36 User S/W int -

SW_INT28 B PHANTOM ; PM 38 User S/W int -

SW_INT29 B PHANTOM ; PM 3A User S/W int -

SW_INT30 B PHANTOM ; PM 3C User S/W int -

SW_INT31 B PHANTOM ; PM 3E User S/W int -

;===========================================================

;中断子向量入口定义pvecs

;===========================================================

.sect ".pvecs" ;定义子向量段

PVECTORS B PHANTOM ; 保留向量地址偏移量-00

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-05

B PHANTOM ;SCI_RX_ISR ; 保留向量地址偏移量

B PHANTOM ;SCI_TX_ISR ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-0a

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-10

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-15

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-1a

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-20

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-25

B PHANTOM ; 保留向量地址偏移量

B T1GP_ISR ; 保留向量地址偏移量-0027 T1PINT

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-2a

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; pvector addr offset 0x02f - T3PINT

B PHANTOM ; 保留向量地址偏移量-30

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-35

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-3a

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-3f

B PHANTOM ;CANMBX_ISR ; 保留向量地址偏移量

B PHANTOM ; 保留向量地址偏移量-41

;程序段

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; 引脚定义:键盘K1=IOPF3,K2=IOPF4, K3=IOPF5, K4=IOPF6, LED的片选信号:IOP

; 此程序为4个键盘与8个发光二极管组合程序,再无键按下或K4按下时用定时器1的方式,循环点亮8个发光二极管

; K1 按下则为功能模式,按键的次数不同显示的发光二极管也不同

; K2 按下则为“+”键模式,按一次加一,点亮不同的发光二极管

; K3 按下则为移位模式,按一次往右移一位,即 LED7=LED6....LED1=LED0, LED0=LED7

; 注意 LED 显示时要关闭 LCD 的块选 E1和E2

.text

_c_int0

CALL INIT

CALL KEYLEDINIT

LDP #DP_USER

SPLK #01H,IOSFT_REG ;显示数据移位寄存器

SPLK #00H,IO_COUNT ;延时计数寄存器

SPLK #001H,IO_DATA ;I/O临时数据缓冲区

SPLK #001H,LEDXS ;LED显示的数据

SPLK #00H,LEDFLAG ; LED显示标志寄存器LEDFLAG.0=1表示

; K1,K2,K3 按下

; LEDFLAG.0=0表示 K4 按下

SPLK #01H,K1FLAG ;K1标志寄存器

CALL INIT_TIME1

LOOP:

CALL KEY

LDP #DP_USER

BIT LEDFLAG,15

BCND LEDBD1,TC

LACL IO_COUNT

SUB #030H

BCND WAIT,LEQ

LEDBD1:

SPLK #00H,IO_COUNT

LDP #DP_PF2

LACL PFDATDIR

OR #0004H ; IOPF2 输出1

SACL PFDATDIR ;开74HC273片选信号

LDP #DP_USER

LACL LEDXS

OR #0FF00H ; IOPB 是输出

LDP #DP_PF2

SACL PBDATDIR ; 送要显示的数据

LDP #DP_PF2

LACL PFDATDIR

AND #0FFFBH ;IOPF2 输出0

SACL PFDATDIR ;关74HC273片选信号

LDP #DP_USER

BIT LEDFLAG,15

BCND LEDBD2,TC

LACL LEDXS

SFL ;要显示的数左移一位

SACL LEDXS

LACL IOSFT_REG

SFL

SACL IOSFT_REG

BIT IOSFT_REG,BIT8 ;判是否循环完一次

BCND LOOP1,TC

B WAIT

LOOP1:

LDP #DP_USER

SPLK #01H,IOSFT_REG

LEDBD2:

LACL IO_DATA

SACL LEDXS

WAIT:

NOP

B LOOP

INIT: ;系统初始化

SETC INTM ;关全局中断

CLRC SXM ;抑止符号扩展

CLRC OVM

CLRC CNF ; B0 配置为数据空间

LDP #0E0H

SPLK #81FEH,SCSR1 ; CLKIN=6M,CLKOUT=24M

SPLK #0E8h,WDCR ; 关闭看门狗 WDT

LDP #0

SPLK #0002h,IMR ; 使能 interrupt 2

SPLK #0FFFFh,IFR ; 清中断标志

RET

INIT_TIME1: ;定时器1初始化子程序

LDP #DP_EVA

SPLK #80H,EVAIMRA ;开定时器1周期中断

SPLK #0FFFFh,EVAIFRA;清EVA所有的中断标志(写1清除)

SPLK #0,GPTCONA ;不启动AD,禁止定时器1比较输出

SPLK #0BBH,T1PR ;使定时器每1ms产生一次中断

SPLK #00H,T1CNT ;清定时器1计数单元

SPLK #0174CH,T1CON ;TMODE=10(连续增模式),

;TPS=111 X/128,,CLOCK=Internal, 启动定时器1

CLRC INTM

RET

KEYLEDINIT: ;键盘LED初始化子程序

LDP #DP_PF2

LACL MCRC

AND #083FFH ; IOPF2--IOPF6 配置为一般的I/O口

SACL MCRC

LACL MCRA

AND #000FFH ; IOPB[0-7] 配置为一般的I/O口

SACL MCRA

LACL PFDATDIR

OR #0400H ; IOPF2 为输出方式

AND #087FBH ;IOPF[3-6] 为输入方式

SACL PFDATDIR

LACL #0FF00H ;IOPB[0-7] 为输出方式

SACL PBDATDIR

RET

;********************************************************************

KEY:

CALL READKEY ;读键盘值

LACL KEYDATA

BCND KEYRET,EQ ; ACC=0?

CALL KEYDELAY ; KEYDATA不等于0,表示有键按下,延时消抖动

CALL READKEY ;键盘软件延时子程序

BCND KEYRET,EQ

LDP #DP_USER ;判断按键情况(考虑只有一个键按下)

BIT KEYDATA,15

BCND KEY1,NTC

CALL K1 ; KEY1功能键

B KEYRET

KEY1:

BIT KEYDATA,14

BCND KEY2,NTC

CALL K2 ;KEY2"+"键

B KEYRET

KEY2:

BIT KEYDATA,13

BCND KEY3,NTC

CALL K3 ;KEY3 "移位"键

B KEYRET

KEY3:

BIT KEYDATA,12 ;KEY4 确认键

BCND KEYRET,NTC

CALL K4

KEYRET:

LACL KEYDATA ;清KEYDATA的低4位

AND #0fff0h

SACL KEYDATA

RET

;*****************读键盘子程序*******************************************

READKEY: ; 判键盘状态子程序

LDP #DP_PF2 ; DP-->7080h-70FFh

LACL PFDATDIR ; 取出键值PFDATDIR.3--PFDATDIR.6

RPT #2

SFR ;右移3位

OR #0fff0h ; 屏蔽高4位(用到4个键)

CMPL ;有键盘按下时对应位为低,按位取反之后为高

LDP #DP_USER

SACL KEYDATA ;键值保存在KEYDATA中

RET

KEYDELAY:

LACC #6000 ; 键盘延时子程序 86ms(20000) 30mS(6000)

KEYD1:

SUB #1 ; 延时30mS消抖动

RPT #080H

NOP

BCND KEYD1, NEQ

LDP #5

RET

; ******************** 功能键子程序 *****************************

K1:

NOP

READK1:

CALL READKEY

CALL KEYDELAY

LDP #DP_USER ; 判断按键 K1 是否松开

BIT KEYDATA,15

BCND READK1,TC

LDP #DP_USER ; 可扩展成16个或更多分支

SPLK #01H,LEDFLAG

BIT K1FLAG,15

BCND GN_KEY1,TC

BIT K1FLAG,14

BCND GN_KEY2,TC

BIT K1FLAG,13

BCND GN_KEY3,TC

BIT K1FLAG,12

BCND GN_KEY4,TC

BIT K1FLAG,11

BCND GN_KEY5,TC

BIT K1FLAG,10

BCND GN_KEY6,TC

BIT K1FLAG,9

BCND GN_KEY7,TC

BIT K1FLAG,8

BCND GN_KEY8,TC

B K1_RET

GN_KEY1:

SPLK #01H,IO_DATA ;K1按第1次时显示1H

B K1_LOOP1

GN_KEY2:

SPLK #03H,IO_DATA ;K1按第2次时显示3H

B K1_LOOP1

GN_KEY3:

SPLK #05H,IO_DATA ;K1按第3次时显示5H

B K1_LOOP1

GN_KEY4:

SPLK #007H,IO_DATA ;K1按第4次时显示7H

B K1_LOOP1

GN_KEY5:

SPLK #11H,IO_DATA ;K1按第5次时显示11H

B K1_LOOP1

GN_KEY6:

SPLK #33H,IO_DATA ;K1按第6次时显示33H

B K1_LOOP1

GN_KEY7:

SPLK #55H,IO_DATA ;K1按第7次时显示55H

B K1_LOOP1

GN_KEY8:

SPLK #77H,IO_DATA ;K1按第8次时显示77H

B K1_LOOP1

K1_LOOP1:

LACL K1FLAG

SFL ;K1FLAG左移一位

SACL K1FLAG

BIT K1FLAG,7

BCND K1_LOOP2,TC

B K1_RET

K1_LOOP2:

SPLK #01H,K1FLAG

K1_RET:

NOP

RET

;======= "+"键子程序 ===========================

K2:

NOP

READK2:

CALL READKEY

CALL KEYDELAY

LDP #DP_USER ; 判断按键 K2 是否松开

BIT KEYDATA,14

BCND READK2,TC

LDP #DP_USER

SPLK #01,LEDFLAG ; 关闭LED左移标志,即LED对同一个数不刷新

LACL IO_DATA

ADD #1

SACL IO_DATA

RET

;======= "移位"键子程序 ===========================

K3:

NOP

READK3:

CALL READKEY

CALL KEYDELAY

LDP #DP_USER ; 判断按键 K3 是否松开

BIT KEYDATA,13

BCND READK3,TC

LDP #DP_USER

SPLK #01H,LEDFLAG

LACL IO_DATA

SFR

SACL IO_DATA

BCND K3_LOOP1,NC ; C=1 则IO_DATA+80H

LACL #80H

ADD IO_DATA

K3_LOOP1:

SACL IO_DATA

RET

;======= 确认键子程序 ===========================

K4:

NOP

READK4:

CALL READKEY

CALL KEYDELAY

LDP #DP_USER ; 判断按键 K4 是否松开

BIT KEYDATA,12

BCND READK4,TC

LDP #DP_USER

SPLK #00H, LEDFLAG ; 恢复LED左移标志

SPLK #01H, IO_DATA

RET

;*************************定时器中断子程序*******************************

GISR2: LDP #0 ; 保存机器上下文

SST #0, st0_temp ; 使用自动寻址,DP-0

SST #1, st1_temp ; 保存状态寄存器到B2 DARAM.

SACL context ; 保存ACC的低16位

SACH context+1 ; 保存ACC的高16位

SAR AR1,context+2

SAR AR2,context+3

SAR AR3,context+4

SAR AR4,context+5

SAR AR5,context+6

LDP #0E0h ; 为PIVR控制寄存器改变DP

LACC PIVR,1 ; 读 EVIVRB, 左移1位

ADD #PVECTORS ; 加偏移向量到基向量

BACC

T1GP_ISR:

LDP #DP_USER

LACL IO_COUNT

ADD #1

SACL IO_COUNT

GISR2_RET:

LDP #DP_EVA

SPLK #0FFFFH,EVAIFRA

LDP #0

LAR AR5,context+6

LAR AR4,context+5

LAR AR3,context+4

LAR AR2,context+3

LAR AR1,context+2

LACC context+1,16

ADDS context

LST #1, st1_temp

LST #0, st0_temp

CLRC INTM

RET

;*******************************************************************

PHANTOM

KICK_DOG ; Resets WD counter

RET

END

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文