返回介绍

实验四 按键计数器

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

一.实验说明

在控制电路中,通常需要以按键来控制程序执行流程或是输入数据。在图4.1中,4个按键K1~K4分别对应TMS320LF2407芯片的引脚IOPF3~IOPF4作为I/O端口的输入,8只发光二极管LED1~I LED8通过SW-DIP8拨码开关和74HC273锁存器芯片分别对应TMS320LF2407芯片的引脚IOPF0~IOPF7作为I/O端口的输出。本实验仅使用一条I/O引脚,借助软件查询方法点亮8只发光二极管。

本实验箱中的K1键对应的TMS320LF2407输入I/O引脚为IOPF3,当按下K1键,则将所对应的端口F数据和方向控制寄存器(PFDATDIR)的第3位为(IOPF3引脚)0,同时点亮发光二极管。

二.实验目的

1.掌握按键的工作原理、按键和TMS320LF2407芯片的接口技术以及按键输入程序的设计和调试方法。

2.掌握输出端发光二极管的工作原理、显示的信息与程序的设计和调试方法。

三.实验内容

1.设计并调试用于TMS320LF2407芯片的计数程序,要求由按键K1作输入并对其进行计数,计数的结果由LED7~LED0发光二极管以二进制方式显示。 

2.对程序稍作改动,用K4按键完成上述功能。

四.实验硬件电路

图4.1 TMS320LF2407与键盘、LED接口电路

五.实验参考程序清单

通过编程,设计一个按键计数器,要求刚接通电源时,8只发光二极管都不亮,表示计数器的初始值为0,即二进制数的00000000B;当按下K1键时,计数器的值加1,发光二极管LED0点亮,表示二进制数的00000001B,然后松开按键;再次按下K1键时,计数器的值又加1,发光二极管LED1点亮,表示二进制数的00000010B,然后再松开按键;依次类推。直到按动了255次按键时,发光二极管LED7~LED0会全部点亮,其后的一次K1键按下时将使计数器回0,就这样循环往复。

C语言程序

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

(2) 主程序

源程序代码:

#include "register.h"

int m=0x0001;

initial()

{

asm("setc SXM");

asm("clrc OVM");

asm("clrc CNF");

*SCSR1=0x81FE;

*WDCR=0x0E8;

*IMR=0x0000;

*IFR=0x0FFFF;

*MCRA=*MCRA&0x0FF;

*PFDATDIR=*PFDATDIR|0x0400;

*PBDATDIR=*PBDATDIR|0x0FF00;

*PFDATDIR=*PFDATDIR|0x0404;

*PFDATDIR=*PFDATDIR&0xFFFB;

}

void inline disable()

{

asm(" setc INTM");

}

int keyscan()

{

int k,j;

k=*PFDATDIR&0x0008;

if(k==0x0008)

k=0;

else

k=1;

if(k==1)

{

for(j=30000;j>0;j--)

j=j;

k=*PFDATDIR&0x0008;

if(k==0x0008)

k=0;

else

k=1;

}

return(k);

}

int keyserve()

{

int k;

k=*PFDATDIR&0x0008;

if(k==0x0000)

*PBDATDIR=(*PBDATDIR&0xFF00)+m++;

else

*PBDATDIR=*PBDATDIR;

*PFDATDIR=*PFDATDIR|0x0404;

*PFDATDIR=*PFDATDIR&0xFFFB;

}

main()

{

disable();

initial();

while(1)

{

int i;

i=0;

i=keyscan();

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 ;显示数据移位寄存器

IO_COUNT .usect ".data0",1 ;延时计数寄存器

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

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

LEDFLAG .usect ".data0",1 ;LED显示标志寄存器

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

KEYDATA .usect ".data0",1 ;读得键盘值存放寄存器

DP_USER .set 5

.include "F2407REGS.H" ;引用头部文件

.def _c_int0

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

;(1)建立中断向量表

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

RSVECT B _c_int0 ;PM 0 Reset Vector 1

INT1 B PHANTOM ;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 ;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 Trap2

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 ;保留向量地址偏移量-0000h

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

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 ; 保留向量地址偏移量-0026h

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

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

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 ;保留向量地址偏移量-0041h

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

;(2)主程序

.text

_c_int0

CALL SYSINIT ;调系统初始化程序

CALL KEYLEDINIT ;调键盘和LED初始化程序

LDP #DP_USER ;指向0280h~0300h区

SPLK #01H,IOSFT_REG ;寄存器和标志初始化

SPLK #00H,IO_COUNT

SPLK #001H,IO_DATA

SPLK #001H,LEDXS

SPLK #00H,LEDFLAG ;LEDFLAG.0=1表示 K1,K2,K3 按下

;LEDFLAG.0=0表示 K4 按下

SPLK #01H,K1FLAG

CLRC INTM ;开总中断

LOOP: CALL KEY ;调键盘程序,即扫描键盘

LDP #DP_USER

BIT LEDFLAG,15

BCND LEDBD1,TC

LACL IO_COUNT

SUB #03E8H

BCND WAIT,LEQ ;判10 s延时到否

LEDBD1: SPLK #00H,IO_COUNT

LDP #DP_PF2

LACL PFDATDIR

OR #0404H ;IOPF2=1

SACL PFDATDIR ;开74HC273片选信号

LDP #DP_USER

LACL LEDXS

OR #0FF00H ;IOPB口为输出方式

LDP #DP_PF2

SACL PBDATDIR ;送要显示的数据到IOPB口

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

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

;(3)系统初始化程序

SYSINIT:

SETC INTM

CLRC SXM

CLRC OVM

CLRC CNF ;B0区被配置为数据空间

LDP #0E0H ;指向7000h~7080h区

SPLK #81FEH,SCSR1 ;时钟4倍频,CLKIN=6 M,CLKOUT=24 M

SPLK #0E8H,WDCR ;不使能WDT

LDP #0

SPLK #02H,IMR ;使能中断优先级INT2

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

LDP #DP_EVA ;指向7400h~7480h区

SPLK #80H,EVAIMRA ;使能T1PINT 中断

SPLK #0FFFFh,EVAIFRA ;清EVA中断标志

SPLK #0,GPTCONA

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

SPLK #0,T1CNT

SPLK #0164CH,T1CON ;设置通用定时器1

RET

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

;(4)键盘和发光二极管初始化程序

KEYLEDINIT:

LDP #DP_PF2

LACL MCRC

AND #083FFH ;IOPF2,IOPF[3~6] 配置为一般的I/O口

SACL MCRC

LACL MCRA

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

SACL MCRA

LACL PFDATDIR

OR #0400H ;IOPF2为输出方式

AND #08787H ;IOPF[3~6] 为输入方式

SACL PFDATDIR

LACL PBDATDIR

OR #0FF00H ;IOPB[0~7] 为输出方式

SACL PBDATDIR

RET

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

;(5)键盘程序

KEY:

CALL READKEY ;调读键程序

LACL KEYDATA

BCND KEYRET,EQ ;ACC=0?

CALL KEYDELAY ;延时消抖动

CALL READKEY ;再一次读键值

LACL KEYDATA

BCND KEYRET,EQ

LDP #DP_USER ;判断按键情况

BIT KEYDATA,15

BCND KEYRET,NTC

CALL K1 ; "+"键按下

B KEYRET

KEYRET: LACL KEYDATA

AND #0FFF0H ;清读取的键值寄存器

SACL KEYDATA

RET

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

;(6)读键子程序

READKEY:

LDP #DP_PF2

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

RPT #2

SFR ;右移3位

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

CMPL

LDP #DP_USER

SACL KEYDATA ;存放键值

RET

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

;(7)用软件延时30mS消抖动

KEYDELAY:

LACC #6000

KEYD1: SUB #1

RPT #80

NOP

BCND KEYD1,NEQ

RET

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

;(8)键子程序

K1: ;"+"键子程序

READK1: CALL KEYDELAY

CALL READKEY

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

BIT KEYDATA,15

BCND READK1,TC

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

LACL IO_DATA

ADD #1

SACL IO_DATA

RET

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

;(9)中断程序

GISR2: ;优先级INT2中断人口

; 保护现场

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

LACC PIVR,1 ;读取外设中断向量寄存器(PIVR),并左移一位

ADD #PVECTORS ;加上外设中断入口地址

BACC ;跳到相应的中断服务子程序

T1GP_ISR: ;通用定时器1中断入口

LDP #DP_USER

LACL IO_COUNT

ADD #1

SACL IO_COUNT

; 恢复现场

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

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

;(10)假中断程序

PHANTOM

KICK_DOG ;复位看门狗

RET

END

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

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

发布评论

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