单片机原理及其嵌入式应用 实 验

291
1 单单单单单单单单单单单单 基基基基 基基基基 <<<

Upload: evelia

Post on 12-Jan-2016

107 views

Category:

Documents


0 download

DESCRIPTION

单片机原理及其嵌入式应用 实 验. 基本实验 综合实例.

TRANSCRIPT

1

单片机原理及其嵌入式应用实 验

• 基本实验

• 综合实例

<<<

2

基本实验

• 程序框架• (开关量输入输出 IO)实验• 串行通信及AD转换实验• 键盘编程实验• 液晶显示实验

• 数码管显示实验• FLASH编程实验• 定时器溢出中断实验• 定时器输入中断捕捉

实验

<<<

3

程序框架

• 实验目的• 实验器材• 硬件接线

• 软件功能• 程序清单• 备注说明

<<<

4

实验目的 :

了解程序基本框架

5

实验器材 :

1.SD-1 型在线编程实验仪

2. 导线若干

6

硬件接线 :

VCC

PTC3

PTA7

PTA6

PTA5

PTA4

PTA3

PTA2

PTA1

PTA0PTC0

PTC1

PTC2

MO

TO

RO

LA

GP

32 MC

U PTC4

PTB7

PTB6

PTB5

PTB4

PTB3

PTB2

PTB1

PTB0

7

软件功能 :

• PTA 口的模拟量输出,控制指示灯

• 程序执行指示灯闪烁

8

程序清单:• 文件说明• 口地址定义• 数据区定义• 主程序• 系统初始化及中断矢量• 延时子程序

9

*--------- 文件说明 ------------------------------------

* 文件名 :PrgFrame.ASM

* 硬件连接 :PTA.1 接指示灯

* 程序描述 : 指示灯 PTA.1 闪烁

* 目的 : 第一个 Motorola MCU 程序框架

* 说明 : 提供 Motorola MCU 的编程框架,供教学入门使用

*-----------------------------------------------------

10

*---- 口地址定义 ----------------------------PTA EQU $0000 ;A 口数据寄存器

DDRA EQU $0004 ;A 口数据方向寄存器

11

RAMstartAddr equ $0040 ;RAM 的起始地址(因芯片不同可以更改)

FlashStartAddr equ $8000 ; 程序开始地址(因芯片不同可以更改)

* 数据区定义(变量名定义)——————————————————

org RAMstartAddr ;RAM 的起始地址

N1 rmb 1 ; 变量 N1, 缓冲使用

12

* 主程序—————————————————————————————— org FlashStartAddr ; 程序起始地址MainInit: ; 复位后程序从此开始执行 ; 系统初始化 SEI ; 禁止所有中断 LDHX #$023F ; 堆栈初始化,放入 GP32的 RAM 最高端 TXS JSR Init0 ; 调系统初始化子程序 Init0 ,初始学习时跳过此处 ;I/O 初始化 BSET 1,DDRA ; 设置 PTA.1 为输出 BSET 1,PTA ; 初始时, PTA.1 指示灯 " 暗 "MainLoop: ; 程序总循环入口 BCLR 1,PTA ;PTA.1 指示灯“亮” MOV #$2,N1 ; 延时子程序 DelaySub 的时间长度入口 JSR DelaySub ; 调用延时子程序 BSET 1,PTA ; 初始时, PTA.1 指示灯 " 暗 " MOV #$4,N1 ; 延时子程序 DelaySub 的时间长度入口 JSR DelaySub ; 调用延时子程序 ;------------------------------------------------------- JMP MainLoop ; 转总循环入口处

13

Init0: ; 系统初始化 Init0 子程序 LDA #%00000001 ; 初始化 CONFIG2

STA $001E

LDA #%00111101 ; 初始化 CONFIG1

STA $001F

CLR $0036 ; 初始化 PTCL

MOV #$01,$0036

MOV #$01,$0038

MOV #$2C,$0039

MOV #$80,$003A

BSET 5,$0036

BSET 7,$0037

BSET 4,$0036

RTS

*---- 中断矢量 --------------------------------- ORG $FFFE ; 复位矢量 DW MainInit

14

延时子程序DelaySub: ; 延时 0.1 秒 PSHH ; 保据寄存器 HX PSHX DelaySub1: LDHX #$FFFF DelaySub2: PSHA ; 保护寄存器 A LDA #$FFDelaySub3: DBNZA DelaySub3 PULA DBNZX DelaySub2 DBNZA DelaySub1 PULX PULH RTS

15

开关量输入输出 (IO) 实验• 实验目的• 实验器材• 硬件接线• 程序功能• 程序清单• 备注说明 <<<

16

实验目的 :

掌握掌握 I/OI/O 口的基本使用方法口的基本使用方法

17

实验器材 :1.SD-1 型在线编程实验仪

2. 导线若干

1818

vcc

vcc

PTC0

PTA7PTA6PTA5PTA4PTA3PTA2

PTA1

PTA0

vcc

PTB1

PTC1

PTB0

MO

TO

RO

LA

GP

32 MC

U

黄线为学生接线黄线为学生接线

硬件接线硬件接线 ::

19

程序功能 :• 开关 PTA7-4 分别控制着指示灯 PTA3-0

亮暗• 开关 PTB0\PTC0 其中之一闭合 , 指示灯

PTB7-1与 PTC1 交替暗亮 ;

若两个均未闭合 , 则指示灯 PTB1与 PTC1

均不亮 ;

若两个均闭合 , 则两个指示灯均亮 .

20

程序清单 :• 程序说明• 口地址定义• 变量定义• 主程序• 初始化子程序• 复位矢量

21

*------ 程序说明 --------------------------------** 文件名 :IOEXMA.ASM

* 硬件连接 :PTA7-4 接开关 ,PTA3-0 接指示灯 *PTB1 接指示灯 ,PTB0 接开关 *PTC1 接指示灯 ,PTC0 接开关 * 程序描述 :① 开关 PTA7-4 分别控制着指示灯 PTA3-

0 暗* ② 开关 PTB0、 PCT0 其中之一闭合指示 PTB7-1

* 与 PTC1 交替暗亮,若两个均未闭合则指示灯 * PTB1与 PTC1 均不亮,若两个均闭合则两排 * 指示灯均亮。* 目的 :I/O 口的基本使用方法 * 说明 : 仅作为基本教学例程 *----------------------------------------------*

22

*----- 口地址定义————————————————— DDRA equ $0004 ;A 口数据方向寄存器 PTA equ $0000 ;A 口数据寄存器 PTAPUE equ $000D ;A 口上拉电阻允许寄存器 DDRB equ $0005 ;B 口数据方向寄存器 PTB equ $0001 ;B 口数据寄存器 DDRC equ $0006 ;C 口数据方向寄存器 PTC equ $0002 ;C 口数据寄存器RAMstartAddr equ $0040 ;RAM 的起始地址(因芯片不同

可以更改)FlashStartAddr equ $8000 ; 程序开始地址(因芯片不同可

以更改)

*----- 数据区定义(变量名定义)——————————

org RAMstartAddr

TmpVar rmb 1 ; 变量 TmpVar ,缓冲使用 Light_BC rmb 1 ;BC 口灯的状态

23

*------ 主程序———————————————— org FlashStartAddr ; 程序起始地址

MainInit:

NOP ; 初始化—————— SEI ; 禁止所有中断

LDHX #$023F ; 堆栈初始化,

;放GP32的 RAM 最高端

TXS

JSR Init0 ; 调系统初始化子程序 Init0,

; 初始学习时跳过此处

24

LDA #%00001111 ; 定义 A 口 7-4 为输入, 3-0为输出

STA DDRA

LDA #%11110000 ; 定义 A 口 7-4 有上拉电阻

STA PTAPUE

LDA #%11111110 ; 定义 B 口 7-1 为输出, 0为输入

STA DDRB

STA DDRC ; 定义 C 口 7-1 为输出, 0 为输入

MOV #$FF,Light_BC ;BC 口灯的状态赋初值

25

Start: ; 程序总循环入口——

NOP

LDA PTA ; 读取 A 口状态

NSA ;A 口 7-4 输入控制 A 口 3-0 输出

; 刚好为 A.7-4->A.3-0

COMA

STA PTA

LDA PTB ; 取开关 PTB0 状态 ,0- 闭合

AND #%00000001 ; 剩下 PTB0 位

STA TmpVar ; 放入变量 TmpVar

26

NOP

LDA PTC ; 取开关 PTC0 状态 ,0- 闭合

AND #%00000001 ; 剩下 PTC0 位

NOP

ADD TmpVar ; 经过此运算 若 A=0, 两个均闭合

; 若 =1, 有一个闭合 ;=2, 均未闭合

CBEQA #$0,Light0 ; 比较 , 相等转移 ,A=0 转向Light0

27

NOP

CBEQA #$1,Light1 ;A=1转 Light1

NOP ;A=2, 两排均不亮

LDA #$FF ; 两排灯均不亮 1- 不亮

STA PTB

STA PTC

BRA IO_End ; 转 IO_END, 延时

28

Light0:

LDA #$00 ; 两排灯均亮 0- 亮 STA PTB

STA PTC

BRA IO_End ; 无条件转 IO_END

Light1:

LDA Light_BC ; 两排灯之一亮 0- 亮 STA PTB ; 驱动 B 口灯 NEGA ; 求补命令 STA PTC ; 驱动 B 口灯 STA Light_BC ; 保存状态

29

IO_End:

LDA #$FE ; 延时Delay1:

LDX #$FC

Delay2:

NOP

NOP

NOP

DBNZX Delay2

DBNZA Delay1

BRA Start ; 无条件转开始处*-------------------------------------------

30

*------ 子程序 --------------------------*Init0: ; 系统初始化 Init0 子程序 LDA #%00000001 ; 初始化 CONFIG2

STA $001E LDA #%00111101 ; 初始化 CONFIG1

STA $001F CLR $0036 ; 初始化 PTCL

MOV #$01,$0036

MOV #$01,$0038

MOV #$2C,$0039

MOV #$80,$003A

31

BSET 5,$0036 BSET 7,$0037 BSET 4,$0036 RTS*-------- 复位矢量 ---------------------------- ORG $FFFE ; 复位矢量 DW MainInit

32

备注说明 :

• 仅作为基本教学例程

33

串行通信及 AD 转换实验

• 实验目的• 实验器材• 硬件接线•VB界面

• 软件功能• 程序清单• 备注说明

<<<

34

实验目的 :

A/D 转换,单片机异步串行通信

35

实验器材 :

1.SD-1 型在线编程实验仪

2. 导线若干

36

硬件接线 :

VCC

PTC3

PTA7

PTA6

PTA5

PTA4

PTA3

PTA2

PTA1

PTA0PTC0

PTC1

PTC2

MO

TO

RO

LA

GP

32 MC

U

PTC4

PTB7

PTB6

PTB5

PTB4

PTB3

PTB2

PTB1

PTB0

VCC

37

VB 界面:

38

软件功能 :•由 PORTB 口的模拟量输入,通过单片

机的 A/D 转换器采集 8 路数据,并放在ADBUF 开始的地址中。

• 再在 INBUF 中放开关量。• 发 86给 PC 机作为握手信号,进行通信

测试, PC 机判断后确认,发 86 作为确认信号,单片机收到 86 后,把模拟量0-7和开关量送 PC 机显示。

39

程序清单:• 文件说明• 口地址定义• SCI寄存器• A/D寄存器• 数据区定义• 主程序• A/D转换• 串行通信输出

• 串行通信输入• 从PC

机接收数据,并存储后送PTA输出

• 把在INBUF和ADBUFF的数据送PC

机输出• 中断矢量

40

*--------- 文件说明 -------------------------------------------** 文件名: sci.as

* 硬件连接: PORTA 口输出它的 PTA7-0接OUT 的 7-0 号* 指示灯( A0 作为运行指示不受其它数据控制) PORTB 作为 AD 输入连接,*PORTB 口为模拟量输入口 ,PORTC的C0-4接 IN 的 5个拨位开关 0-4 作为

开关* 输入串行口与微机串行口相接( 9600,N, 8, 1)

* 程序描述: 1.由PORTB 口的模拟量输入,通过单片机的 A/D 转换器采集 8* 路数据,并放在 ADBUF 开始的地址中* 2.再在 INBUF 中放开关量* 3.发 86给PC 机作为握手信号,进行通信测试 ,PC 机判断后确* 认 , 发 86 作为确认信号,单片机收到 86 后 ,把模拟量 0-7和* 开关量送PC 机显示* 目的: A/D 转换,单片机异步串行通信 *------------------------------------------------------------*

41

*---- 口地址定义 ----------------------------PTA EQU $0000 ;A 口数据寄存器

PTB EQU $0001 ;B 口数据寄存器

PTC EQU $0002 ;C 口数据寄存器

PTD EQU $0003 ;D 口数据寄存器

DDRA EQU $0004 ;A 口数据方向寄存器

DDRB EQU $0005 ;B 口数据方向寄存器

DDRC EQU $0006 ;C 口数据方向寄存器

DDRD EQU $0007 ;D 口数据方向寄存器

DDRE EQU $0008 ;E 口数据寄存器

42

*----SCI 寄存器 -----------------------------SCS1 EQU $0016 ;SCI 状态寄存器 1B-SCTE EQU 7 ; 发送缓冲区空标志位B-TC EQU 6 ; 发送完成标志位B-SCRF EQU 5 ; 接收器满标志位SCDR EQU $0018 ;SCI 数据寄存器*---A/D 寄存器 -----------------------------ADSCR EQU $003C ;A/D 转换状态和控制寄存器B-COCO EQU 7 ; 转换完成标志位ADR EQU $003D ;A/D 转换数据寄存器ADCLK EQU $003E ;A/D 转换输入时钟寄存器RAMstartAddr equ $0040 ;RAM 的起始地址(因芯片不同可

以更改)FlashStartAddr equ $8000 ; 程序开始地址(因芯片不同可以

更改)

43

*---- 数据区定义(变量定义) -------------- ORG RAMstartAddr ;RAM 的起始地址

INBUF RMB 1 ;1字节存放 5位开关量

ADBUF RMB 8 ;8字节存放 8路 A/D 转换结果

ONOFF RMB 1 ;1字节存放从 PC 的数据

TMPVAR RMB 1 ; 暂存使用

44

*---- 主程序 --------------------------------- ORG FlashStartAddr ; 程序起始地址MainInit:: NOP LDA #$3E ;A/D 初始化 2 分频、使用内部总线时钟 STA ADCLK LDA #$FF ; 定义 PORTA 输出 STA DDRA LDA #$00 STA PTA STA ONOFF ;ONOFF=0

LDA #$00 ; 定义 PORTB, PORTC 作为输入 STA DDRB STA DDRC

45

*-------A/D 转换 ------------------------------Main: NOP ; 循环获得 8路 AD 值 LDHX #$0 ;H: X=0

GA-REPEAT: TXA ;X 寄存器送到累加器 STA ADSCR ; 选定一路 A/D ,启动转换 BRCLR 7,ADSCR,* ; 等待 A/D 转换完成 LDA ADR ;A/D 转换结果给 A

STA ADBUF,X ;A给 {ADBUF+X} ,储存数据

AIX #1 ; 下一存储单元 CPX #$08 ; 判断 8 路转换是否完成 BNE GA-REPEAT ; 循环 8次转换 8 个通道模拟

46

*---- 串行通信输出 -------------------------------GET-IN:

LDA PTC ;5 位开关量采集 STA INBUF ; 暂放 INBUF

NOP

LDA #$56 ; 把 86 ( 16 进制数 56 )为握 ; 手信号送出到 PC 中 BRCLR 7,SCS1,* ; 等待以前数据全部发出, ;SCTE 置 1 ,发送缓冲区空 STA SCDR ; 发送缓冲区空时, ; 可向 SCI 数据寄存器送数

47

*---- 串行通信输入 ----------------------------- NOP LDHX #0WS-REPE1: BRSET 5,SCS1,WS-RECE1 ; 测试 SCRF 位, ; 判断接收缓冲器是否满 NOP NOP AIX #1 ; 延时等待 CPHX #$FFFF BNE WS-REPE1 BRA DISP1 ; 超时退出WS-RECE1: LDA SCDR ; 读取收到的数据

48

CMP #$56 ; 判断是否为确认信号 86

BNE DISP1 ; 不是退出,是就开始通信 NOP

LDHX #0

WS-REPE2: BRSET 5,SCS1,WS-RECE2 ; 测试 SCRF 位, ; 判断接收缓冲器是否满 NOP

NOP AIX #1 ; 延时等待 CPHX #$6688 BNE WS-REPE2 ; 超时退出 BRA DISP1

49

*----从 PC 机接收数据,并储存后送 PTA 输出 ----------*----( A.0 不受影响) ----------------------------WS-RECE2

LDA SCDR

NOP AND #$FE ;A0=0

STA TMPVAR ; 暂时缓存 LDA ONOFF AND #$1 ; 留下 A.0

ORA TMPVAR ; 处理接收的数据,放在 A 中 STA ONOFF ; 储存接收数据在 ONOFF 中

NOP ; 送 A/D 值

50

*----把在 INBUF和 ADBUFF 的数据送 PC 机输出 --------

LDHX #$0

SA-REPEAT:

LDA INBUF,X

BRCLR 7,SCS1,* ;SCTE 置 1 ,

; 发送缓冲区空

STA SCDR ;A给 SCDR ,发送出去

AIX #1

CPX #$09 ;9 个数据输出

BNE SA-REPEAT

51

DISP1:

NOP

LDA ONOFF

EOR #$1 ; 把原 A.0 取反,使灯闪烁 STA ONOFF

STA PTA

BRA MAIN

**********************************************

*---- 中断矢量 --------------------------------- ORG $FFFE ; 复位矢量 DW MainInit:

52

备注说明 :

单片机与 PC 机使用串行异步通信。在此程序下,通过 PC机下的 VB6.0 控制程序构成一定功能的微机控制系统。

53

键盘编程实验• 实验目的• 实验器材• 硬件接线• 软件功能• 程序清单• 备注说明

<<<

54

实验目的 :

键盘查询,键盘中断,键值识别,键盘编码 .

55

实验器材 :1.SD-1 型在线编程实验板

2. 导线若干

56

硬件接线 :

红线为学生接线

PTC3

PTA7PTA6PTA5PTA4PTA3PTA2PTA1PTA0PTC0PTC1PTC2

MO

TO

RO

LA

GP

32 MC

UPTC4

内置电阻

VCC

57

2 DE

键值表 :

1 EE

3 BE

4 7E

5 ED

6 DD

7 DD

8 7D

9 EB

0 DB

A BB

B 7B

C E7

D D7

E B7

F 77

键值

定义

58

软件功能 :• 开始运行时,指示灯 7 亮,等待键盘按键。• 按下“ D”键进入运行状态,指示灯 7 闪烁。• 在指示灯 7 闪烁状态,按“ 0-9”任意一键,指示灯 3-0 显示对应的二进制值( 0为灯亮, 1 为灯暗,如 1 的二进制为 0001 ,显示应为“亮亮亮暗”),按“ A-F”任意一键,指示灯 3-0全暗。

59

程序清单 :• 程序说明• 口地址定义• 数据区定义• 主程序• 键盘中断初始化

子程序

• 扫描读键值子程序• 键盘中断子程序• 键盘转化为具体值

子程序• 延时程序子程序• 中断矢量

60

*--------- 程序说明 ----------------------------------------** 文件名: key.asm* 使用 4*4键盘实现输入控制* 硬件连接:* PTA7-4 接 4根键盘列线( X4-1), PTA3-0 接 4根键盘行

线* ( Y4-1)* PTC4 接指示灯 7(OUT7), PTC3-0 分别接指示灯 3-0(OUT3-0)

* 程序描述: 1.开始运行时,指示灯 7 亮,等待键盘按键* 2. 按下“ D”键进入运行状态,指示灯 7 闪烁* 3.在指示灯 7 闪烁状态,按“ 0-9”任意一键,指示灯 3-0* 显示对应的二进制值( 0 为灯亮, 1 为灯暗,如 1 的二进制为 0001* 显示应为“亮亮亮暗”),按“ A-F”任意一键,指示灯 3-0全暗。* 目的:键盘查询,键盘中断,键值识别,键盘编码*---------------------------------------------------------*

61

*---- 口地址定义 -------------------------------------------------

DDRA EQU $0004 ;A 口数据方向寄存器PTA EQU $0000 ;A 口数据寄存器PTAPUE EQU $000D ;A 口上拉电阻允许寄存器

DDRC EQU $0006 ;C 口数据方向寄存器PTC EQU $0002 ;C 口数据寄存器

INTKBSCR EQU $001A ; 键盘状态和控制寄存器INTKBIER EQU $001B ; 键盘中断允许寄存器

62

*----- 数据区定义(变量定义) ----------------- ORG $0090

TMPVAR1 RMB 1 ; 变量 TMPVAR1 ,缓冲使用

TMPVAR2 RMB 1 ; 变量 TMPVAR2 ,缓冲使用

KBVALUE RMB 1 ; 存放键盘按键值

PTCSTATE RMB 1 ;PTC 口状态变量

RAMstartAddr equ $0040 ;RAM 的起始地址(因芯片不同可以更改)FlashStartAddr equ $8000 ; 程序开始地址(因芯片不同可以更改)

*********************************************

63

ORG FlashStartAddr ; 程序起始地址*---- 主程序 ----------------------------------------MainInit:

NOP

LDA #$00 ; 定义 C 口之前复位 PTC

STA PTC

LDA #%00011111 ; 定义 C 口 4-0 为输出 STA DDRC ;C 口接指示灯 STA PTC ; 初始时指示灯熄灭 BCLR 4,PTC ;PTC4 为 0 ,指示灯 7点亮 ;表示进入开始状态

64

;--------A 口接键盘,查询等待按键 ----------- LDA #$00 ; 定义 A 口前复位 PTA

STA PTA

LDA #%00001111

STA DDRA

LDA #%11110000

STA PTAPUE

65

MainIni1:

JSR KBA ; 取得键值在 A 中 STA KBVALUE ; 键值放在 KBVALUE 中 ; 作为 KBdef 的入口 JSR KBdef ; 具体值在 A 中 cmp #$46 ;ASCII “( F” )是否为 $46 BNE MainIni1 ; 不是等待“ F”键;------- 设置键盘中断 ----------------------------JSR KBInit ; 已按“ F”键,进入运行状态, ; 执行键盘中断初始化子程序 BCLR 1,INTKBSCR ; 开放键盘中断 CLI

66

;---- 开始总循环处理键盘 ------------------Start:

NOP

;---- 使灯闪烁 ----------------------------- BCLR 4,PTC ;PTA4=0 ,电亮指示灯 7

LDA #$08

JSR Delaysub

BSET 4,PTC ;PTA4=1 ,熄灭指示灯 7

LDA #$08

JSR Delaysub

67

JSR Kbde ; 执行键盘转化为具体值子程序, ; 转成键定义值 CMP #$39 ; 测试是否是 0-9 BHI Start1 ; 大于 ASCII “( 9” )到 Start1

SUB #$30 ; 数字实际值 =ASCII 值 -$30 STA PTC ; 送 PTC 口 ,由指示灯 3-0 显示 BRA Start

Start1:

LDA #$FF ; 大于 ASCII “( 9”) ,消灭指示灯 STA PTC

JMP Start ; 继续循环处理

68

*-键盘中断初始化子程序(从 KBInit 开始) ---------------* 功能:对被定义为键盘中断的引脚初始化,但未开放键盘中断*占用 CPU内寄存器: A*---------------------------------------------------KBInit: LDA #$00 ; 定义 A 口之前复位 PTA STA PTA LDA #%00001111 ; 定义 A 口 7-4 输入作为列, ;3-0 输出作为行 STA DDRA LDA #%11110000 ; 定义 A 口 7-4 有上拉电阻 STA PTAPUE BSET 1,INTKBSCR ; 屏蔽键盘中断 LDA #%11110000 ; 允许 KBIE7-4PIN 中断进入 STA INTKBIER BSET 2,INTKBSCR ; 清除键盘中断 RTS

69

*----扫描读键值子程序(从 KBA 开始) ----------------* 功能 :扫描一次接在 PTA 口的 4*4键盘( PTA7-4 接 4根键盘*(X4-1), PTA3-0 接 4根键盘行线( Y4-1 )上的按键(使* 用行扫描法),键值放在 A 中 , 若无按键, A 中值 $FF*占用内存: TMPVAR1 (缓冲使用)* 出口: A=键值*-------------------------------------------------KBA: MOV #%11111110,TMPVAR1 ; 第一根行线为 0 LDX #$04 ;扫描 4根行线KB1: LDA PTA ;取 PTA给A ORA #%00001111 ;PTA7-4 保留原态, PTA3-0为 1 AND TMPVAR1 ;令

PTAn=0, n=0, 1, 2, 3 STA PTA ; 处理后给 PTA 以便查询

70

NOP NOP LDA PTA ; 查第 n 列上是否有键按下 AND #%11110000 ; 保留 PTA7-4列值,令低

PTA3-0=0 CBEQA #$F0,KB2 ;A 等于 $F0 ,本行线没键按下 ;A 不等于 $F0, 本行有键按下 LDA PTA ;A 放键值 BRA KB3 ; 转到 KB3结束中断KB2: SEC ; 令 C=1 ROL TMPVAR1 ; 使下一个行线为 0 ,查下一行 DBNZX KB1 ; 对行线循环 LDA #$FF ; 没有键被按下为 $FFKB3:RTS

71

*---键盘中断子程序(从 KBint 开始) ----------------* 功能:键盘中断程序,键值放入内存 KBVALUE 中* 调用子程序:扫描法读键值子程序( KBA),* 键盘中断初始化子程序( KBInit)* 出口:第 0页内存单元 KBVALUE 中为键值*------------------------------------------------Bint:

PSHH ; 保护H SEI

BSET 1,INTKBSCR ; 禁止键盘中断;---- 以下为中断程序任务 -------------------------- JSR KBA ; 调子程序 KBA ,键值放在 A 中 STA KBVALUE ; 放入内存 KBVALUE;---- 以上为中断程序任务 --------------------------

72

PULH ;H 出栈 JSR KBInit ; 调用键盘中断初始化子程序 BCLR 1,INTKBSCR ; 开放键盘中断 CLI RTI

****************************************************

*----键盘转化为具体值子程序(从 KBdef 开始) ----------* 功能:键值转为键盘表面具体的字符或符号代表值* 入口:内存第 0页中 KBVALUE 为键值,使用键值编号表*占用 CPU 寄存器: X (存放相对地址)* 出口: A=键定义值

*---------------------------------------------------KBdef: LDHX #$0000

73

KBkey1:

LDA KBTABLE,X

BEQ KBkey3 ;=0 ,表示表中未定义此键值 CMP KBVALUE ; 与 KBVALUE 入口键值相比

较 BNE KBkey2 ; 不等,未找到转 KBkey2

INCX ; 找到地址加 1 LDA KBTABLE,X ; 取键定义值给 A

BRA KBkeyr

KBkey2:

INCX

INCX

BRA KBkey1

74

KBkey3:

LDA #$FF ; 未定义键用 FF标志

KBkeyr: RTS

KBTABLE FCB $EE,"1",$DE,"2",$BE,"3",$7E,"4"

FCB $ED,"5",$DD,"6",$BD,"7",$7D,"8"

FCB $EB,"9",$DB,"0",$BB,"A",$7B,"B"

FCB $E7,"C",$D7,"D",$B7,"E",$77,"F"

FCB $00

***********************************************

75

*----- 程序延时程序子程序( Delaysub) -----------

* 功能 : 程序方法延时,延时长短由入口 A 中的数值决定

* 入口: A= 延时长度*占用内存 : 无*占用寄存器 :A

*----------------------------------------------

Delaysub:

PSHH

PSHX

Delay1:

LDHX #$5588

76

Delay2: NOP AIX #-1 CPHX #$0000 BNE Delay2 DBNZA Delay1 PULX PULH RTS*********************************************------ 中断矢量 ------------------------------- ORG $FFE0 ; 键盘中断矢量 DW KBint ORG $FFFE ; 复位矢量 DW MainInit

77

液晶显示实验

• 实验目的• 实验器材• 硬件接线• VB界面

• 软件功能• 程序清单• 备注说明

<<<

78

实验目的 :

不使用单片机串行外设接(SPI) 进行点阵字符型液晶显示(LCD) 编程

79

实验器材 :

1. SD-1 型在线编程实验仪

2. LCD(HD44780)

3. 导线若干

80

硬件接线 :

16151413121110090807060504030201

LC

D(H

D4478

0)

PTA7PTA6PTA5PTA4PTA3PTA2PTA1PTA0PTC2PTC1PTC0

MC

68H

C908G

P3

2

VCC

81

VB 界面:

82

程序功能 :

•开始运行时 ,LCD 显示“ Wait Receiving..”

•等待接收字符,当收到 16 个字符时,显示之,重复此功能

83

程序清单:• 程序说明• 口地址定义• SCI串行通信口地址• 变量定义• 主程序• 系统初始化

• 串行口初始化• LCD初始化子程序• LCD命令执行子程序• LCD显示子程序• 中断矢量

84

*------ 程序说明 -------------------------------------** 文件名: LCD.ASM

* 硬件连接 :1.LCD的DB0-7与单片机的 PORTA的 PTA0-7 连接作为

* 输出* 2.LCD的RS,R/W,E与单片机的 PTC0,PTC1,PTC2 连接* 程序描述 :1.开始运行时 ,LCD 显示“ Wait Receiving..”

* 2. 等待接收字符,当收到 16 个字符时显示之,重复* 此功能* 实验目的:不使用单片机串行外设接口 (SPI) 进行点阵字符* 型液晶显示 (LCD) 编程*--------------------------------------------------*

85

*------ 口地址定义 --------------------------------PTA EQU $0000 ;A 口数据寄存器

DDRA EQU $0004 ;A 口数据方向寄存器

PTC EQU $0002 ;C 口数据寄存器

DDRC EQU $0006 ;C 口数据方向寄存器

LCD-RS EQU 0 ;LCD 寄存器选择信号接 PTC0

LCD-RW EQU 1 ; 读写信号接 PTC1

LCD-E EQU 2 ;LCD 使能信号接 PTC2

86

*----SCI 串行通信口地址 -----------------------------SCC1 EQU $0013 ;SCI 控制寄存器 1SCC2 EQU $0014 ;SCI 控制寄存器 2SCS1 EQU $0016 ; 串行通信接口状态寄存器地址SCDR EQU $0018 ; 串行通信接口数据寄存器地址SCBR EQU $0019 ;SCI波特率寄存器FULL EQU 5 ; 用于 SCI 接收缓冲器是否满标志位RAMstartAddr equ $0040 ;RAM 的起始地址(因芯片不同可

以更改)FlashStartAddr equ $8000 ; 程序开始地址(因芯片不同可以

更改)*----- 变量定义 ---------------------------------------- ORG RAMstartAddr ;RAM 的起始地址LCD-BUFFER RMB 16 ; 存放 16字节

87

*************************************************

*----- 主程序 -------------------------------------

ORG FlashStartAddr ; 程序起始地址MAININIT:

NOP

LDA #%11111111 ;A 口为输出

STA DDRA

LDA #%00010111 ;C 口的 PTC0-2 为输出

STA DDRC

88

*---- 串行口初始化 ------------------------------- LDA #%01000000 ;D6(ENSCI)=1, 允许 SCI,

; 其它位为 0,正常码输出

;8 位数据 , 无检验

STA SCC1

LDA #%00001100 ; 允许发送器 , 允许接收器 ,

; 不允许发送与接收中断

STA SCC2

LDA #%00000010 ; 波特率为 9600

STA SCBR

89

LDHX #$00

DISPLAY1: ; 把要显示的 16 个初始字符 ; 放入 LCD-BUFFER 中 LDA DISPLAYBYTES,X

STA LCD-BUFFER,X

AIX #1

CPHX #$10

BNE DISPLAY1 ; 循环 16次 BRA START

DISPLAYBYTES FCB "WAIT RECEIVING.."

START:

JSR INIT-LCD ;LCD 初始化 JSR SHOW-LCD-BUFFER ; 把 LCD-BUFFER 中的 16

个字符 ;送 LCD 显示

90

LDHX #$00

DISPLAY2: ; 从 PC 机接收 16 个字符放入 ;LCD-BUFFER 开始的内存中 BRCLR FULL,SCS1,* ; 与 PC 机串行通信 , ; 判断接收器是否满 LDA SCDR ; 读 SCI 数据寄存器 STA LCD-BUFFER,X

AIX #1

CPHX #$10

BNE DISPLAY2

JMP START

*************************************************

91

*---INIT-LCD(LCD 初始化子程序 )-------------------

* 入口 : 无

* 功能 : 初始化 LCD(HD44780)

* 调用子程序 :LCDCOMMAND(LCD 命令执行子程序 )

*占用 CPU内部寄存器 :A,X

*------------------------------------------------

INIT-LCD:

BCLR LCD-RS,PTC ;令 LCD的RS=0,R/W=0, 进行LCD 初始化

BCLR LCD-RW,PTC

LDA #%00111000 ; 功能设置 :8 位数据接口 ,

;2 行显示 ,5*7点阵模式

92

JSR LCDCOMMAND

LDA #%00001000 ; 显示开关控制 : 关显示,

; 关光标显示 , 不闪烁

JSR LCDCOMMAND

LDHX #$0020 ; 等待 40us

DBNZX *

BCLR LCD-RS,PTC ;RS,RW 清零开始清屏

BCLR LCD-RW,PTC

LDA #%00000001 ; 清屏指令

JSR LCDCOMMAND

LDHX #$2DF ; 等待清屏完毕 , 时间 >1.6ms

93

CLR-LCD-2-MS: ; 延时 AIX #-1

CPHX #0

LDA #%00000110 ; 输入方式设置 : 数据读写操作后 ,

;AC自动增 1, 显示不动 ,光标左 JSR LCDCOMMAND

LDA #%00010100 ; 光标移位设置 :光标右移一个 ;字符位 ,AC自动加 1 JSR LCDCOMMAND

LDA #%00001100 ; 显示开关设置 : 开显示 , ; 关光标显示 , 不闪烁 JSR LCDCOMMAND

RTS

94

*----LCDCOMMAND(LCD 命令执行子程序 )-----------------

* 入口 :A

* 功能 : 对 A 中指令使用 PORTA 作为输出口 ,* 到 LCD 进行命令执行或字符显示*占用 CPU内部寄存器 :A

*--------------------------------------------------

LCDCOMMAND:

PSHH ; 保护现场 PSHX

LDHX #$0020 ; 等待 40us

DBNZX *

STA PTA ; 把指令码送到 A 口

95

NOP

NOP

BSET LCD-E,PTC ;LCD 开始接受数据 , 置使能位为 1 NOP

NOP

BCLR LCD-E,PTC ;LCD结束接受数据 , 置使能位为 0 LDHX #$0020 ; 等待 40us

DBNZX *

PULX ; 恢复现场 PULH

RTS

****************************************************

96

*----SHOW-LCD-BUFFEER(LCD 显示子程序 )-----------------* 入口 :内存 LCD-BUFFER 开始的 16 个地址中存放要显示的字符

* 编码* 功能 : 显示内存 LCD-BUFFER 开始的 16字节数据* 调用 :LCDCOMMAND 子程序*占用 CPU内部寄存器 :A,HX

*----------------------------------------------------

SHOW-LCD-BUFFER: ; 进行显示数据寄存器 (DD RAM) 地址设置

BCLR LCD-RS,PTC

BCLR LCD-RW,PTC ; 设置前 8 个字符首DD RAM 地址 LDA #%10000000

JSR LCDCOMMAND

LDHX #$0 ; 显示前 8 个字符

97

SHOW-FIRST-8BYTE:

BSET LCD-RS,PTC ; 令 LCD的 RS=1,R/W=0,写入数

; 据到 DD RAM 中

BCLR LCD-RW,PTC

LDA LCD-BUFFER,X ; 将 {LCD-BUFFER+X} 的数据 ; 放入 A 作为入口

JSR LCDCOMMAND

AIX #1

CPHX #$8

BNE SHOW-FIRST-8BYTE

98

LDA #%11000000 ; 设置后 8 个字符首DD RAM地址

BCLR LCD-RS,PTC

BCLR LCD-RW,PTC

JSR LCDCOMMAND

LDHX #$08 ; 显示后 8 个字符

SHOW-NEXT-8BYTE:

BSET LCD-RS,PTC ; 令 LCD的 RS=1,R/W=0,

; 写入数据到 DD RAM 中

BCLR LCD-RW,PTC

99

LDA LCD-BUFFER,X ; 将 {LCD-BUFFER+X}的数据

; 放入 A 作为入口

JSR LCDCOMMAND

AIX #1

CPHX #$10

BNE SHOW-NEXT-8BYTE

RTS

*--- 中断矢量 --------------------------------------* ORG $FFFE ; 复位向量

DW MAININIT

100

系统初始化Init0: ; 系统初始化 Init0 子程序 LDA #%00000001 ; 初始化 CONFIG2 STA $001E LDA #%00111101 ; 初始化 CONFIG1 STA $001F CLR $0036 ; 初始化 PTCL MOV #$01,$0036 MOV #$01,$0038 MOV #$2C,$0039 MOV #$80,$003A BSET 5,$0036 BSET 7,$0037 BSET 4,$0036 RTS

101

不使用单片机串行外设接口(SPI)和 74HC164( 移位寄存器 ), 使用 A 口作为输出在 LCD上显示。

备注说明 :

102

数码管显示实验• 实验目的• 实验器材• 硬件接线• VB 界面

• 软件功能• 程序清单• 备注说明

<<<

103

实验目的 :

数码管的显示

104

实验器材 :1. SD-1 型在线编程实验仪

2. 数码管

3. 导线若干

105

硬件接线 :PTB0

PTB1

PTB2

PTB3

PTB4

PTB5

PTB6

PTB7

PTC0

PTC1

PTC2

PTC3

MC

68H

C908G

P3

2

LA

LB

LC

LD

LE

LF

LG

LDP

L11

L12

L13

L14

LE

D

106

LED的 VB 界面 :

107

软件功能 : 从 PC 机收到数字 (整数或小数 ), 使

4 个数字并排在一个数码管上显示 ,由PC 机的 VB 界面控制显示。

108

程序清单 :• 程序说明• 口地址定义• 串行口地址定义• 内存变量定义• 主程序• 串行口初始化

• 子程序• 显示子程序 • 转码子程序• 延时子程序• 中断矢量

109

*-------- 程序说明 ---------------------------------------------------

* 文件名 :LED.ASM

* 使用数码管对数字 (整数或小数 ) 进行显示* 硬件连接 :PTB0,1,2,3,4,5,6,7 分别接 * LA,LB,LC,LD,LE,LF,LG,LDP

* PTC0,1,2,3 分别接 L11,L12,L13,L14

* 功能描述 :从 PC 机收到数字 (整数或小数 ), 使 4 个数字并排

* 在一个数码管上显示 ,由 PC 机的 VB 界面显示控制* 目的 : 数码管的显示*------------------------------------------------------------------------

110

*---- 口地址定义 ----------------------------------------------

PTB EQU $0001 ;B 口数据寄存器

DDRB EQU $0005 ;B 口数据方向寄存器

PTC EQU $0002 ;C 口数据寄存器

DDRC EQU $0006 ;C 口数据方向寄存器

PTD EQU $0003 ;D 口数据寄存器

DDRD EQU $0007 ;D 口数据方向寄存器

111

*---- 串行口地址定义 -------------------------------------

SCS1 EQU $0016 ;SCI 状态寄存器 1

SCDR EQU $0018 ;SCI 数据寄存器SCC1 EQU $0013 ;SCI 控制寄存器 1

SCC2 EQU $0014 ;SCI 控制寄存器 2

SCBR EQU $0019 ;SCI波特率寄存器RAMstartAddr equ $0040

;RAM 的起始地址(因芯片不同可以更改)FlashStartAddr equ $8000

; 程序开始地址(因芯片不同可以更改)*---内存变量定义 ------------------------------------------

ORG RAMstartAddr

PC_Buffer RMB 4 ; 存放从 PC 接收的数据 Show_Buffer RMB 4 ; 存放待显示的数据Cs RMB 1 ; 位选信号

112

*------ 主程序 -------------------------------------------------

ORG FlashStartAddr ; 初始化

Main:

LDA #$FF ; 定义 B 口为输出

STA DDRB

LDA #$FF ; 定义 C 口为输出

STA DDRC

LDA #$FF ; 定义 D 口为输出

STA DDRD

113

*---- 串行口初始化 -------------------------------------------

LDA #%01000000 ;D6(ENSCI)=1, 允许 SCI,

; 其它位为 0,正常码输出 ,

;8 位数据 , 无检验

STA SCC1

LDA #%00001100 ; 允许发送器 , 允许接收器 ,

; 不允许发送与接收中断

STA SCC2

LDA #%00000010 ;波特率为 9600

STA SCBR

114

Display_Init: ; 起始数据赋值

MOV #$1,PC_Buffer

MOV #$2,{PC_Buffer+$1}

MOV #$3,{PC_Buffer+$2}

MOV #$4,{PC_Buffer+$3}

Start:

JSR Translate_Num ; 起始数据转码 JSR Show_Num ; 显示起始数据

BRSET 5,SCS1,Rece_Num ; 等待接受数据 , 有

;就跳向 Rece_Num

BRA Start

115

Rece_Num: LDHX #$0000 ; 清空缓冲区Rece_Num1: BRCLR 5,SCS1,* ; 等待数据 , 无就转向自己 ,

; 有就往下执行 LDA SCDR ; 取数据寄存器中内容放入 A

STA PC_Buffer,X ;将 PC_Buffer 中的数据 ;依次存入 A

INCX CPX #!4 ; 接收满 4 个数就开始显示 BLO Rece_Num1

BRA Start

116

*----- 显示子程序(Show_Num)-------------------------------------

* 入口 :以 Show_Buffer首地址的内存区 ,共 4 个字节* 出口 : 无*占用寄存器 :HX,A

*占用内存 :CS

* 调用子程序 :Delay_ns

* 描述 : 显示 Show_Buffer 中的四个字符*--------------------------------------------------------------------------

Show_Num: PSHH ; 进栈 , 保存 HX,A 中内容 PSHX

PSHA LDHX #$00 ; 清空缓冲区 LDA #$01 ;先取第一位 STA CS

117

Show_Num_Loop: LDA Show_Buffer,X ; 取出 Show_Buffer 中 ; 第一个字符放入 A

STA PTB ; 再将 A 中内容存入 B 输出 LDA CS STA PTC ;将 A 中内容存入 C 中输出 LDA #!100 ; 延时 100毫秒 JSR Delay_ns ASL CS ; 算术左移 ,修改位选信号 INCX CPX #!4 ; 判断是否已经扫描完毕 BLO Show_Num_LOOP ;小于则循环

118

PULA ; 出栈 PULX

PULH

RTS

*----------- 转码子程序 (Translate_Num)-----------------------

* 子程序名 :Translate_Num

* 入口 :以 PC_Buffer 为首地址的内存区四个字节* 出口 :以 Show_Buffe 为首地址的内存区四个字节*占用寄存器 :HX,A

*占用内存 :Show_Buffer

* 调用子程序 : 无* 描述 :将 PC_Buffer 中字符转换为相应的字型码* 放入 Show_Buffer 中*------------------------------------------------------------------------

119

Translate_Num: PSHH ; 进栈 , 保存 HX,A 中内容

PSHX

PSHA LDHX #$0000 ; 清空缓冲区

Translate_Num1: LDA PC_Buffer,X ;取 PC_Buffer 中一个数 ; 放入 A

PSHH ; 进栈 , 保存 HX内容

PSHX

120

TAX ;将 A 中内容放入 X 中 LDA Table,X ; 取出对应的字形码

PULX

PULH STA Show_Buffer,X ;将 Show_Buffer 中字符 ;依次放入 A 中

INCX

CPX #$4 BLO Translate_Num1 ;小于四个字符则循环

121

PULA ; 出栈

PULX

PULH

RTS

Table FCB $C0,$CF,$A4,$B0,$99,$92,$82,$F8,$80, $90

; 显示码表 0 1 2 3 4 5 6 7 8 9

;0 1 2 3 4 5 6 7 8 9

FCB $40 ,$4F ,$24,$30,$19,$12,$02,$78,$00 ,$10

; 显示码表 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.

; 10 11 12 13 14 15 16 17 18 19

122

*------------ 延时子程序( Delay_ms )---------------------------

* 入口 :HX(表示要延时的毫秒数 ) HX=1 延时 1毫秒*占用内部寄存器: A

*占用内存:无*-------------------------------------------------------------------------

Delay_ms: LDA #!248 ;0.5ms

JSR Delay_ns LDA #!248 ;0.5ms

JSR Delay_ns

AIX #-!1

CPHX #!0 BNE Delay_ms ;4Cycles

RTS ;4Cycles

123

*----------- 延时子程序( Delay_ns )------------------------

* 入口: A

*占用内部寄存器:无*占用内存:无* 使用方法:设延时 10μs, A=(T-4)/2=3

* LDA #!3 ; 延时 10μs

* BSR Delay_nus

*--------------------------------------------------------------------

Delay_ns: NOP ;1Cycles

NOP ;1Cycles

DBNZA Delay_ns ;3Cycles

RTS ;4Cycles

124

************************************************

*--- 中断矢量 -------------------------------------------------------

ORG $FFFE

DW MAIN

125

FLASH 编程实验

• 实验目的• 实验器材• 硬件接线

• VB 界面• 软件功能• 程序清单

<<<

126

实验目的 :

将由用户输入的一串数字写入单片机中读出所写的内容

<<<

127

实验器材 :

1.SD-1 型在线编程实验仪2. 导线若干

<<<

128

硬件接线 :

<<<

129

VB 界面 :

<<<

130

软件功能 :① 系统初始化: CONFIG2、 1、 PTCL、串行口、堆

栈 ② 进行通信握手,即与 PC 机进行通信测试,发出 86 ,

收到 56 ,则表明握手成功 ③ 等待接收 PC送来N1+1 个数,其中 N1 为要写入

Data8000 开始 Flash 区的数据 ④ 擦除以 Data8000 为首地址的 Flash 区的一页,将

N1 个数据写入 ⑤ 从以 Data8000 为首地址的 Flash 区读取 N1 个数据,由串行口发送到 PC 机

⑥ PTA1 为通信指示灯 , 通信握手时闪动,表明正在与PC 机握手 <<<

131

程序清单 :• 口地址定义•内存变量定义• 程序初始化• 主循环• 握手子程序• 系统初始化子程序• 中断矢量

<<<

132

口地址定义• DDRA equ $0004 ;A 口数据方向寄存器• PTA equ $0000 ;A 口数据寄存器• FLCR EQU $FE08 ;Flash 控制寄存器• FLBPR EQU $FF7E ;Flash 块保护寄存器• SCC1 EQU $0013 ;SCI 控制寄存器 1• SCC2 EQU $0014 ;SCI 控制寄存器 2• SCBR EQU $0019 ;SCI 波特率寄存器• SCS1 EQU $0016 ;SCI 状态寄存器 1• SCDR EQU $0018 ;SCI 数据寄存器• RAMstartAddr equ $0040 • ;RAM 的起始地址(因芯片不同可以更

改)• FlashStartAddr equ $8000 • ; 程序开始地址(因芯片不同可以更改)<<<

133

内存变量定义• org RAMstartAddr• Address1 RMB 2 ; 地址缓冲单元• N1 RMB 1 ; 写入数据的个数• I1 RMB 1 ; 计数变量• FlashAddress RMB 2 ;Flash 页的首地址• DATA1 RMB !64 ; 数据区• P_AddressInRAM RMB !90 ;FLASH 中程序移入 RAM 后的首地址• *---------Flash 数据区 ( 一页 128 字节 )-------------------------------------------• ORG FlashStartAddr• ; 设写入区为 $8000 ~ $807F 一页• Data8000: FCB !11,!12,!13,!14,!15,!16,!17,!18,!66 ; 几个初始值,仅为实

验对比• *--------- 程序区 -------------------------------------------------------------• ORG $9000• * 包含子程序 =============================================

=====================• $INCLUDE "Writesub.asm"• $INCLUDE "EraseSub.asm" <<<

134

程序初始化• ;---------- 主程序开始 ------------------------------------------------• MainInit:• : ; 复位后程序从此开始执行 • ; 系统初始化• SEI ; 禁止所有中断• LDHX #$023F ; 堆栈初始化,放入 GP32的 RAM 最高端• TXS• JSR Init0 ; 调系统初始化子程序 Init0 ,初始学习时跳过此处• BSET 1,DDRA ; 定义 PTA.1 为输出(通信指示灯)• ;------ 串行口初始化 --------------------------------------------------• LDA #%01000000 ;D6( ENSCI) =1 ,允许 SCI 。其它位为 0 ,• STA SCC1 ; 即正常码输出、 8 位数据、无校验等• LDA #%00001100 ;D3( TE) =1 ,允许发送器; D2(RE)=1, 允

许接收器。• STA SCC2 ; 其它位为 0, 查询方式收发• LDA #%00000010 ; 例如: fBUS= 2.4576MHz ,取 PD=1 (即

SCP1、 SCP0=00)、• STA SCBR ;BD=2(即 SCR2、 SCR1、 SCR0=010),• ; 则波特率 =2457600 /(64*1*4) = 9600• ;-------------------- 初始化结束 -------------------------------------

<<<

135

主循环• MainLoop: • BRCLR 1,PTA,PTA1SET ; 指示灯状态变换• BCLR 1,PTA• BRA PTA1CLR• PTA1SET:• BSET 1,PTA• PTA1CLR:• JSR CommunicateTest ; 调用“通信握手子程序”• BCC MainLoop ;C= 0 表明握手未成功,继续握手• ;-------- 接收要写入的字符个数 (N1<=128) 及字符 ----------------------• BRCLR 5,SCS1,* ; 测试位 5, 直到为 1 (等待接收一个数据)• LDA SCDR ; 取收到的数据 ->A• STA N1 ; 放入内存 N1 中• LDHX #$0000• ReceiveData:• BRCLR 5,SCS1,* ; 测试位 5, 直到为 1 (等待接收一个数据) • LDA SCDR ; 取收到的数据 ->A• STA DATA1,X ; 放入内存 {DATA1+X} 中• AIX #$1• CPX N1 <<<

136

主循环续• BLO ReceiveData ; 是否收到 N1 个数据,若没收到,则继续收• ;------- 擦除要写入的 Flash 区 (1 页 ,GP32:128Bytes))--------------------• LDHX #Data8000 ; 擦除程序的入口参数 FlashAddress• STHX FlashAddress ; 要擦除 Flash 区首地址• JSR EraseSub ; 执行擦除子程序• ;------------------------------------------------------------------ • LDHX #DATA1 ; 写入程序的入口参数① • STHX Address1 ; 内存数据首地址放入 Address1~ Address1+1 中• ; 写入程序的入口参数② :N1 为写入的数据个数,已放入• LDHX #Data8000 ; 写入程序的入口参数③ :Flash 的首地址• STHX FlashAddress • JSR WriteSub ; 执行写入程序• ;------------------------------------------------------------------• ;向 PC 机发送写入 Flash 区的数据 N1 个,共 PC 机接收并比较• LDHX #Data8000• SendData:• LDA ,X ; 取内存数据 ->A• BRCLR 7,SCS1,* ; 测试第 7 位直到为 1, 即发送出去• STA SCDR ;A->SCDR• AIX #$1 ;HX=HX+1• DBNZ N1,SendData ;N1-1 不等于 0, 则再继续发送写入的数• MainError1:• MainExit:• JMP MainLoop ; 转总循环 <<<

137

握手子程序CommunicateTest: LDA #!86 ; 发送握手信号:数字 86 BRCLR 7,SCS1,* ; 测试第 7 位直到为 1, 即发送出去 STA SCDR ;A→SCDR, 发送出去 LDHX #$0000 ;0→H:XReceive56: BRSET 5,SCS1,Receive561 ; 测试位 5, 看它是否为 1 ,即收到数据转 AIX #1 ; 未收到数据, HX+1 计数 CPHX #$AABB ; 延时等待时间常数 BNE Receive56 ; 等待时间未到,继续监测 JMP Test_Fail ; 等待时间到,转通信息检测失败Receive561: ; 收到数据情况 LDA SCDR ; 读取收到的数据 CMP #!56 ; 与约定数 "56" 进行比较 BNE Test_Fail ; 不等,转通信息检测失败 JMP Test_Success ; 相等,转 Test_Success Test_Fail: CLC ; 通信息检测失败 C= 0 JMP Test_Exit ; 跳转至总退出处Test_Success: SEC ; 通信息检测成功 C= 1Test_Exit: RTS

<<<

138

系统初始化子程序Init0: ; 系统初始化 Init0 子程序 LDA #%00000001 ; 初始化 CONFIG2 STA $001E LDA #%00111101 ; 初始化 CONFIG1 STA $001F CLR $0036 ; 初始化 PTCL MOV #$01,$0036 MOV #$01,$0038 MOV #$2C,$0039 MOV #$80,$003A BSET 5,$0036 BSET 7,$0037 BSET 4,$0036 RTS

<<<

139

中断矢量• org $FFFE ; 复位矢量• dw MainInit

<<<

140

定时器溢出中断实验

• 实验目的• 实验器材• 硬件接线

• 软件功能• 程序清单• 备注说明

<<<

141

实验目的 :

熟悉定时器接口模块的使用

142

实验器材 :

1.SD-1 型在线编程实验仪2. 导线若干

143

硬件接线 :

PTA1

MO

TO

RO

LA

GP

32 MC

U

VCC

144

软件功能 :

① 系统初始化:CONFIG2、 1、 PTCL、堆栈

② 以定时中断方式 ,每 5秒取反指示灯PTA1 ,使其闪动

145

程序清单 :• 程序说明• 寄存器地址定义• 内存变量定义• 主程序• 系统初始化• 主循环• 定时器1溢出中断子程序• 向量区

146

*----------------- 程序说明 -----------------------------------------*

* 文件名称 : Timer_5s.asm( 定时器接口模块编程实验)* 硬件连接 : PTA1 接指示灯 D1

* 程序描述 : ① 系统初始化: CONFIG2、 1、* PTCL、堆栈 * ② 以定时中断方式 ,每 5秒取反指示灯

PTA1 ,* 使其闪动 * 实验目的 : 熟悉定时器接口模块的使用 *----------------------------------------------------------------------*

147

*---------- 寄存器地址 -----------------------------------------------

DDRA equ $0004 ;A 口数据方向寄存器PTA equ $0000 ;A 口数据寄存器*T1SC EQU $0020 ; 定时器 1 状态和控制寄存器T1CNTHEQU $0021 ; 定时器 1计数寄存器 ( 高位 )

T1CNTL EQU $0022 ; 定时器 1计数寄存器 (低位 )

T1MODH EQU $0023 ; 定时器 1 模数寄存器 ( 高位 )

T1MODL EQU $0024 ; 定时器 1 模数寄存器 (低位 )

RAMstartAddr equ $0040 ;RAM 的起始地址(因芯片不同可以更

改)RAMstartAddr equ $8000 ; 程序开始地址(因芯片不同可以更改)

148

*---------内存变量 ---------------------------------------------

org RAMstartAddrFiv RMB 1

org RAMstartAddr ;---------- 主程序开始 ----------------------------------

MainInit: SEI ; 禁止所有中断 LDHX #$023F ; 堆栈初始化, ; 放入 GP32的 RAM 最高端 TXS

149

;---------- 系统初始化 ----------------------------------------------

MOV #%00000001,$001E ; 初始 CONFIG2

MOV #%00111101,$001F ; 初始化 CONFIG1

MOV #%00110001,$0036 ; 初始化 PTCL

BSET 7,$0037 ;PBWC 第 7 位为 1

MOV #$01,$0038 ;PMSH

MOV #$2C,$0039 ;PMSL

MOV #$80,$003A ;PMDS

BSET 1,DDRA ; 定义 PTA.1 为输出(指示灯)

BSET 1,PTA

; 定时器 1 初始化

150

LDA #%01100110 ; 允许溢出中断、不启动计数、 ; 分频因子 =64

STA T1SC LDHX #$0000 ;计数寄存器初值 =$0000

STHX T1CNTH LDHX #$9600 ; 设 1秒产生 1次溢出中断 STHX T1MODH ; 模数寄存器设定值 ;=1×(2457600/64)=$9600

BCLR 5,T1SC ; 允许定时器 1计数寄存器计数 MOV #!0,Fiv CLI ; 开放中断 ;-------------------- 初始化结束 -----------------------------

151

*======== 主循环开始处 ========================

MainLoop:

NOP ; 仅为实验例程,无其它事务处理 JMP MainLoop ; 转总循环

152

*---------- 定时器 1溢出中断子程序 -------------------------

Timer1overflow:

INC Fiv

LDA #!5

CMP Fiv

BHI PTA1CLR

MOV #!0,Fiv

BRCLR 1,PTA,PTA1SET ; 指示灯状态变换 BCLR 1,PTA

BRA PTA1CLR

153

PTA1SET:

BSET 1,PTA

PTA1CLR:

;LDA T1SC ; 清除定时器溢出标志位 BCLR 7,T1SC

RTI ; 中断返回

154

*---------- 向量区 ----------------------------------------ORG $FFF2 ; 定时器 1溢出中断向量

DW Timer1overflow

ORG $FFFE ; 复位向量 DW MainInit

155

综合实例实验

• 定时数码管显示实验• 定时液晶显示实验• 液晶显示164接口实验• 硬件检测

<<<

156

定时数码管显示实验• 实验目的• 实验器材• 硬件接线• 软件功能• 程序清单

<<<

157

实验目的:

• LCD与定时中断的联合编程,• 显示时钟

158

实验器材:

1.SD-1 型在线编程实验仪2. 导线若干

159

硬件接线:

• 使用实验板固定接线( PTB0,1,2,3,4,5,6,7 分别接

LA,LB,LC,LD,LE,LF,LG,LDP

PTC0,1,2,3 分别接L11,L12,L13,L14)

160

软件功能:

• 手动设置当前时间• 显示时钟

161

程序清单:• 口地址定义• 寄存器地址• 内存变量定义• 主程序• 扫描子程序

• 转码子程序• 显示子程序• 延时子程序• 定时器1溢出中断子程序• 中断矢量

162

软件功能:

• 运行时请与标准时间进行校对

163

口地址定义PTA EQU $0000 ;A 口数据寄存器DDRA EQU $0004 ;A 口数据方向寄存器PTB EQU $0001 ;B 口数据寄存器DDRB EQU $0005 ;B 口数据方向寄存器PTC EQU $0002 ;C 口数据寄存器DDRC EQU $0006 ;C 口数据方向寄存器PTD EQU $0003 ;D 口数据寄存器DDRD EQU $0007 ;D 口数据方向寄存器

PTDPUE EQU $000F

164

寄存器地址T1SC EQU $0020 ; 定时器 1 状态和控制寄存器T1CNTH EQU $0021 ; 定时器 1 计数寄存器 ( 高位 )T1CNTL EQU $0022 ; 定时器 1 计数寄存器 ( 低位 )T1MODH EQU $0023 ; 定时器 1 模数寄存器 ( 高位 )T1MODL EQU $0024 ; 定时器 1 模数寄存器 ( 低位 )RAMstartAddr equ $0040 ;RAM 的起始地址(因芯片不同可以更改)FlashStartAddr equ $8000 ; 程序开始地址(因芯片不同可以更改)

165

内存变量定义

ORG RAMstartAddr

Show_Buffer RMB 8 ; 存放待显示的数据Cs RMB 1 ; 位选信号Sec RMB 1

Min RMB 1

Hou RMB 1

I1 RMB 1

166

主程序*------ 主程序 --------------------------------------- ORG FlashStartAddr ; 初始化 NOP ; 初始化——————————— SEI ; 禁止所有中断 LDHX #$023F ; 堆栈初始化,放入 GP32的 RAM 最高端 TXS ; 系统初始化 MOV #%00000001,$001E ; 初始化 CONFIG2, 内部总线时钟用作 SCI 的时钟 MOV #%00111101,$001F ; 初始化 CONFIG1, 允许 LVI 复位信号 , ; 禁止 LIV 模块的电源 ,LIV 工作在 5V, ;经过 32 个周期退出 STOP 模式 , 禁止 COP 模块 CLR $0036 ; 清零 , 初始化 PCTL, MOV #$01,$0036 MOV #$01,$0038 MOV #$2C,$0039 MOV #$80,$003A BSET 5,$0036 BSET 7,$0037 ;自动方式 BSET 4,$0036 ; 选择 PLL 为系统时钟源

167

主程序续 LDA #$FF ; 定义 A 口为输出 STA DDRA LDA #$FF ; 定义 B 口为输出 STA DDRB LDA #$FF ; 定义 C 口为输出 STA DDRC LDA #$00 ; 定义 A 口之前复位 PTA STA PTD ;D 口 STA DDRD ; 输入 LDA #$FF ; 定义 D 口有上拉电阻 STA PTDPUE ;STA PTD ; 定时器 1 初始化 LDA #%01100110 ; 允许溢出中断、不启动计数、分频因子 =64 STA T1SC LDHX #$0000 ; 计数寄存器初值 =$0000 STHX T1CNTH LDHX #$9600 ; 设 1 秒产生 1次溢出中断 STHX T1MODH ; 模数寄存器设定值 =1×(2457600/64)=$9600 ; 设置初始时间 MOV #$7F,{Show_Buffer+2} MOV #$7F,{Show_Buffer+5} MOV #$00,Sec

168

主程序续 MOV #$00,Min MOV #$00,Hou ;--------- 设置当前时间 -------------SetUp: JSR Scan SetSec: BRSET 0,PTD,SetMin INC Sec LDA Sec CMP #!59 BNE SetMin MOV #!0,SecSetMin: BRSET 1,PTD,SetHou INC Min LDA Min CMP #!59 BNE SetHou MOV #!0,Min

169

主程序续SetHou: BRSET 2,PTD,SetExit INC Hou LDA Hou CMP #!23 BNE SetExit MOV #!0,Hou SetExit: BRCLR 3,PTD,SetExit2 Mov #$FF,I1ScanDlay: JSR SCAN DBNZ I1,ScanDlay JMP SetUpSetExit2: BCLR 5,T1SC ; 允许定时器 1 计数寄存器计数 CLI

170

扫描子程序Scan:

LDA Hou

LDHX #Show_Buffer

JSR Trans1

LDA Min

LDHX #{Show_Buffer+3}

JSR Trans1

LDA Sec

LDHX #{Show_Buffer+6}

JSR Trans1

JSR Show_Num ; 显示起始数据 RTS

171

转码子程序Trans1: PSHA PSHH PSHX LDHX #$000A DIV LDHX #$0000 TAX LDA Table,X PULX PULH STA ,X AIX #$1 PULA

172

转码子程序续 PSHH PSHX LDHX #$000A DIV PSHH PULA LDHX #$0000 TAX LDA Table,X PULX PULH STA ,X RTS Table FCB $C0,$F9,$A4,$B0,$99,$92,$82,$F8,$80,$90,$40,$4F,

$24,$30,$19,$12,$02,$78,$00,$10,$7f ; 显示码表 0 1 2 3 4 5 6 7 8 9 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. . ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

173

显示子程序Show_Num:

PSHH ; 进栈 , 保存 HX,A 中内容 PSHX

PSHA

LDHX #$0000 ; 清空缓冲区 MOV #$01,CS ;先取第一个数Show_Num_Loop:

LDA Show_Buffer,X ; 取出 Show_Buffer 中一个字符放入 A

STA PTB

PSHX

PSHH

AIX #$4

LDA Show_Buffer,X ; 取出 Show_Buffer 中一个字符放入 A

STA PTA

174

显示子程序续LDA CS ;将 A 中第一个数存入 C 中输出 STA PTC

LDA #!100 ; 延时 100毫秒 JSR Delay_ns

ASL CS ;算术左移 ,修改位选信号 PULH

PULX

AIX #!1

CPX #!4 ;判断扫描是否完毕 BLO Show_Num_Loop ;小于 4 则循环 ;-----------------

PULA ; 出栈 PULX

PULH

RTS

175

延时子程序 1

Delay_ms: LDA #!248 ;0.5ms JSR Delay_ns LDA #!248 ;0.5ms JSR Delay_ns AIX #-!1 CPHX #!0 BNE Delay_ms ;4Cycles RTS ;4Cycles

176

延时子程序 2

Delay_ns:

NOP ;1Cycles

NOP ;1Cycles

DBNZA Delay_ns ;3Cycles

RTS ;4Cycles

177

定时器 1 溢出中断子程序Timer1OvF: INC Sec LDA Sec CMP #!60 BLO Tim1OvF_Exit CLR Sec INC Min ; 一分到 LDA Min CMP #!60 BLO Tim1OvF_Exit CLR Min INC Hou ; 一小时到 LDA Hou CMP #!24 BLO Tim1OvF_Exit CLR Sec CLR Min CLR HouTim1OvF_Exit: LDA T1SC ; 清除定时器溢出标志位 BCLR 7,T1SC RTI

178

中断矢量

ORG $FFF2

DW Timer1OvF

ORG $FFFE

DW MainInit

179

定时液晶显示实验

• 实验目的• 实验器材• 硬件接线

• 软件功能• 程序清单• 备注说明

<<<

180

实验目的:

• LCD与定时中断的联合编程• 显示时钟

181

实验器材:

1.SD-1 型在线编程实验仪2. 导线若干

182

硬件接线: 使用实验板 LCD固定接线 (1. 单片机的 PTB0-PTB7 作为输出与 LCD的 D0-D7 连接 ;

2. 单片机的 PTC0,PTC1,PTC2 分别接LCD的 RS R/W E;

3. 单片机的 PTA7-4 接 4根键盘列线( X4-1),

PTA3-0 接 4根键盘行线( Y4-1) )

183

软件功能:

• 开始时 ,LCD 显示两行“ Current Time is:

00:00:00 SUDA ”

“*”键为设置键 ,按下后可设置时 , 分 ,秒 , 随后

按“ #” 时钟开始运行 。

184

程序清单:• 口地址定义• 定时器的寄存器地址

定义• 变量定义• 系统初始化• 总循环• 扫描读键值子程序• 键盘中断子程序• 定时器溢出子程序

• 键盘中断初始化子程序

• 键盘转化为具体值子程序

• LCD初始化子程序• LCD命令执行子程序• LCD显示子程序• 转码子程序• 中断矢量

185

备注说明:

• 运行时请与标准时间进行校对

186

口地址定义• * 单片机的 PTA7-4 接 4根键盘列线( X4-1), PTA3-0 接 4根键盘

行线( Y4-1)• DDRA EQU $0004 ;A 口数据方向寄存器• PTA EQU $0000 ;A 口数据寄存器• PTAPUE EQU $000D ;A 口上拉电阻允许寄存器• * 单片机的 PTB0-PTB7 作为输出与 LCD的 D0-D7连接• DDRB equ $0005 ;B 口数据方向寄存器 • PTB equ $0001 ;B 口数据寄存器• * 单片机的 PTC0,PTC1,PTC2分别接 LCD的 RS R/W E• PTC EQU $0002 ;C 口数据寄存器• DDRC EQU $0006 ;C 口数据方向寄存器• LCD-RS EQU 0 ;LCD 寄存器选择信号接 PTC0• LCD-RW EQU 1 ; 读写信号接 PTC1• LCD_E EQU 2 ;LCD使能信号接 PTC2• INTKBSCR EQU $001A ; 键盘状态和控制寄存器• INTKBIER EQU $001B ; 键盘中断允许寄存器 <<<

187

定时器的寄存器地址定义

• T1SC EQU $0020 ; 定时器 1 状态和控制寄存器• T1CNTH EQU $0021 ; 定时器 1 计数寄存器 (高

位 )• T1CNTL EQU $0022 ; 定时器 1 计数寄存器 (低

位 )• T1MODH EQU $0023 ; 定时器 1 模数寄存器 (高

位 )• T1MODL EQU $0024 ; 定时器 1 模数寄存器 (低

位 ) <<<

188

变量定义• RAMstartAddr equ $0040 ;RAM 的起始地址(因芯片不同可以更

改)• FlashStartAddr equ $8000 ; 程序开始地址(因芯片不同可以更改)

• ORG RAMstartAddr• LCD_Buffer1 RMB 16 ; 存放 16 字节显示缓冲数据(第一行)• LCD_Buffer2 RMB 16 ; 存放 16 字节显示缓冲数据(第二行)• Sec RMB 1 ; 时钟的秒 • Min RMB 1 ; 时钟的分• Hou RMB 1 ; 时钟的小时• BeginRun RMB 1 ; • SetByte RMB 1 ;• KBValue RMB 1 ; 执行键盘中断程序后,存放键值的内存

KbValue• Tmpvar1 RMB 1 ; 变量 Tmpvar1 ,缓冲使用• Tmpvar2 RMB 1 ; 变量 Tmpvar2 ,缓冲使用• Tmpvar3 RMB 1 ; 变量 Tmpvar3• Tmpvar4 RMB 1 ; 变量 Tmpvar4

<<<

189

初始化• 系统初始化• PLL 初始化• 口初始化• 定时器 1 初始化• 设定初始时间• 键盘中断初始化

<<<

190

系统初始化

NOP ; 初始化开始 SEI ; 禁止所有中断 LDHX #$023F ; 堆栈初始化,放入 GP32的 RAM 最高端 TXS MOV #%00000001,$001E ; 初始化 CONFIG2, 内部总线

时钟用作 SCI 的时钟 MOV #%00111101,$001F ; 初始化 CONFIG1, 允许 LVI

复位信号 , ;禁止 LIV 模块的电源 ,LIV 工作在 5V, ; 经过 32个周期退出 STOP 模式 ,禁止 COP

模块

<<<

191

PLL 初始化

; 外接晶阵32.768KHz, 初始化成总线频率为 2.4576MHz CLR $0036 ; 清零 ,初始化 PCTL, MOV #$01,$0036 MOV #$01,$0038 MOV #$2C,$0039 MOV #$80,$003A BSET 5,$0036 BSET 7,$0037 ;自动方式 BSET 4,$0036 ; 选择 PLL 为系统时钟源

<<<

192

端口初始化

LDA #%11110000 STA PTAPUE LDA #%11111111 ;B 口为输出 STA DDRB LDA #%00000111 ;C 口的 PTC0-2 为输出 STA DDRC

<<<

193

定时器 1 初始化

LDA #%01100110 ; 允许溢出中断、不启动计数、分频因子 =64

STA T1SC LDHX #$0000 ; 计数寄存器初值 =$0000

STHX T1CNTH LDHX #$9600 ; 设 1 秒产生 1次溢出中

断 STHX T1MODH ; 模数寄存器设定值 =1×(2457600/64)=$9600

<<<

194

设定初始时间 LDHX #$0000Display1: ;把要显示的 16 个初始字符放入

LCD_Buffer1—2 中 LDA DisplayBytes1,X STA LCD_Buffer1,X LDA DisplayBytes2,X STA LCD_Buffer2,X AIX #1 CPHX #$10 BNE Display1 ; 循环 16次 JSR Init_LCD ;LCD 初始化 JSR Show_LCD ;将内存 LCD_Buffer1—2 的 32字节

ASCII 字符送 LCD 显示 MOV #$00,SEC MOV #$00,MIN MOV #$00,HOU

<<<

195

键盘中断初始化

JSR KBInit ; 执行键盘中断初始化子程序

------- 初始化完毕 ---------------------------------

<<<

196

总循环

;允许定时器 1 计数寄存器计数, ;开放定时中断 ,开放键盘中断 BCLR 1,INTKBSCR ; 开放键盘中断 BCLR 5,T1SC ; 允许定时器 1 计数寄存器计数 CLI ; 开放中断 ;总循环Start_1: ; 总循环开始处 NOP ; 仅为实验例程,主循环无实际工作 BRA Start_1

<<<

197

扫描读键值子程序(从 KBA 开始)

功能:扫描一次接在 PTA 口的 4*4 键盘 ( PTA7-4 接 4根键盘列线( X4-1), PTA3-0 接 4根键盘行线( Y4-1 )上的按键(使用行扫描法), 键值放在A 中若无按键 , A 中值 $FF

占用内存: Tmpvar1 (缓冲使用) 出口: A= 键值 -------------------------------------------------------------------

<<<

198

扫描读键值子程序

KBA: MOV #%11111110,Tmpvar1 ; 第一根行线为 0 LDX #$04 ; 扫描 4根行线KB1: LDA PTA ;取 PTA给 A ORA #%00001111 ;PTA7-4 保留原态, PTA3-0 为 1 AND Tmpvar1 ;令 PTAn=0, n=0, 1, 2, 3 STA PTA ; 处理后给 PTA 以便查询 NOP NOP LDA PTA ; 查第 n 列上是否有键按下 AND #%11110000 ; 保留 PTA7-4列值,令低 PTA3-0=0 CBEQA #$F0,KB2 ;A 等于 $F0 ,本行线没键按下,转到 KB2 ;A 不等于 $F0, 本行有键按下 LDA PTA ;A 放键值 BRA KB3 ; 转到 KB3 结束中断KB2: SEC ;令 C=1 ROL Tmpvar1 ;使下一个行线为 0,查下一行 DBNZX KB1 ; 对行线循环 LDA #$FF ; 没有键被按下为 $FFKB3:RTS

<<<

199

键盘中断初始化子程序(从 KBInit 开始)

功能:对被定义为键盘中断的引脚进行初始化, 但未开放 键盘中断 占用 CPU 内寄存器: A

<<<

200

键盘中断初始化子程序

KBInit: LDA #$00 ; 定义 A 口之前复位 PTA STA PTA LDA #%00001111 ; 定义 A 口 7-4 输入(作为列), 3-0 输出(作为

行) STA DDRA LDA #%11110000 ; 定义 A 口 7-4 有上拉电阻 STA PTAPUE BSET 1,INTKBSCR ;屏蔽键盘中断 LDA #%11110000 ; 允许 KBIE7-4PIN 中断进入 STA INTKBIER BSET 2,INTKBSCR ; 清除键盘中断 RTS <<<

201

键盘中断子程序(从 KBint 开始)

--- 键盘中断子程序(从 KBint 开始) --------------

功能:键盘中断程序,键值放入内存 KbValue 中

调用子程序:扫描法读键值子程序( KBA),键盘中断初始化子程序( KBInit )

出口:第 0 页内存单元 KbValue 中为键值 -------------------------------------------------------------- <<<

202

键盘中断子程序 1KBint: PSHH ; 保护 H SEI ; 禁止中断 BSET 1,INTKBSCR ; 禁止键盘中断 JSR KBA ; 调子程序 KBA ,键值放在 A 中 STA KbValue ; 放入内存 KbValue JSR KBdef ; 执行键盘转化为具体值子程序,转成键定义值 ; 是否为 "*"? , 不是退出 KBint_Exit CMP #!42 ;ASCI "*" 键 BEQ SetUpBegin JMP KBint_Exit ; 不是 , 等待 "*" 键SetUpBegin: ; 是 "*",xx:xx:xx BSET 2,INTKBSCR ; 清除键盘中断 MOV #$0,SetByte ;赋初值 0SetUpStore: ; 保存原来每位显示的数据 LDHX #$00 LDX SetByte LDA LCD_Buffer2,X STA Tmpvar4 SetUp: LDHX #$00 LDX SetByte LDA #!32 ;" "

<<<

203

键盘中断子程序 2

STA LCD_Buffer2,X

JSR Show_LCD ;将内存 LCD_Buffer1—2 的 32 字节 ASCII 字符送 LCD 显示 LDHX #!90 ; 延时 90毫秒 JSR Delay_ms

LDHX #$00

LDX SetByte

LDA Tmpvar4 ;原来的值 STA LCD_Buffer2,X

JSR Show_LCD ;将内存 LCD_Buffer1—2 的 32 字节 ASCII 字符送 LCD 显示 LDHX #!90

JSR Delay_ms

JSR KBA ; 调子程序 KBA ,键值放在 A 中 STA KbValue ; 放入内存 KbValue

JSR KBdef ; 执行键盘转化为具体值子程序,转成键定义值放入 A 中 CMP #$23 ; 是 "#"

BEQ KBint_Exit0

CMP #$39

BHI SetUp ;>$39( 数值 >9)转 SetUp

CMP #$30

BLO SetUp ;<$30( 数值 <0)转 SetUp

<<<

204

键盘中断子程序 3 PSHA ; 保护 A(ASCII 值 ) ;判断当前位的输入是否有效 ; 第 0 位只能是 0~2 ,第 0 位和第 1 位合在一起小于 24 ; 第 3 、 6 位小于 6 LDA SetByte CMP #!0 BEQ SetUp0 CMP #!1 BEQ SetUp1 CMP #!3 BEQ SetUp2 CMP #!6 BEQ SetUp2 PULA BRA SetUp3 SetUp0: ; 第 0 位只能是 0~2(ASCII 值小于等于 32 ) PULA CMP #$32 BHI SetUp ;>$32( 数值 2) 无效 转 SetUp BRA SetUp3 <<<

205

键盘中断子程序 4SetUp1: ; 第 0 位和第 1 位合在一起小于 24 LDA LCD_Buffer2 SUB #$30 ;ASCII 值 ---> 数值 LDX #!10 MUL ;(A)*(X)-->A STA TmpVar3 ;A---->临时单元 TmpVar3 PULA PSHA SUB #$30 ;ASCII 值 ---> 数值 ADD TmpVar3 CMP #!23 PULA BHI SetUp ;>23 无效 转 SetUp BRA SetUp3 ; 有效 转 SetUp3SetUp2: ; 第 3 、 6 位小于 6(ASCII 值小于 36 ) PULA CMP #$36 BHS SetUp ;>=36( 数值 >=6) 无效 转 SetUp SetUp3: ; 是有效的数,则置于相应位置 LDHX #$00 LDX SetByte STA LCD_Buffer2,X <<<

206

键盘中断子程序 5

INC SetByte ; 设置下一位

;判断下一位是不是第 2 、 5 (:)、 8 位 LDA SetByte

CMP #!2

BEQ SetUp4

CMP #!5

BEQ SetUp4

CMP #!8 ; 是第 8 位,退出设置 BHS KBint_Exit0

BRA SetUp5

SetUp4: ; 是第 2 、 5 位(:) , 跳过该位的设置 INC SetByte

SetUp5:

JMP SetUpStore

KBint_Exit0:

;将当前的设置值放到变量 Hou、Min、 Sec 中 LDA LCD_Buffer2

SUB #$30 ;ASCII 值 ---> 数值 LDX #!10

MUL

LDHX #!1

ADD LCD_Buffer2,X <<<

207

键盘中断子程序 6 SUB #$30

STA Hou

LDHX #!3

LDA LCD_Buffer2,X

SUB #$30 ;ASCII 值 ---> 数值 LDX #!10

MUL

LDHX #!4

ADD LCD_Buffer2,X

SUB #$30

STA Min

LDHX #!6

LDA LCD_Buffer2,X

SUB #$30 ;ASCII 值 ---> 数值 LDX #!10

MUL

LDHX #!7

ADD LCD_Buffer2,X

SUB #$30

STA Sec

JSR Show_LCD ;将内存 LCD_Buffer1—2 的 32 字节 ASCII 字符送 LCD 显示<<<

208

键盘中断子程序 7

BCLR 7,T1SC ; 清除定时器溢出标志位

KBint_Exit:

PULH ;H 出栈 BSET 1,INTKBSCR ; 禁止键盘中断 BSET 2,INTKBSCR ; 清除键盘中断 JSR KBInit ; 调用键盘中断初始化子程序 BCLR 1,INTKBSCR ; 开放键盘中断 CLI

RTI<<<

209

键盘转化为具体值子程序(从 KBdef 开始)

功能:键值转为键盘表面具体的字符或符号代表值

入口:内存第 0页中 KBValue 为键值, 使用键值编号表 占用 CPU 寄存器: X (存放相对地址)

出口: A= 键定义值

<<<

210

键盘转化为具体值子程序KBdef: LDHX #$0000 KBkey1: LDA KBTABLE,X BEQ KBkey3 ;=0 ,表示表中未定义此键值 CMP KBValue ;与 KBValue 入口键值相比较 BNE KBkey2 ; 不等,未找到转 KBkey2 INCX ;找到地址加 1 LDA KBTABLE,X ; 取键定义值给 A BRA KBkeyrKBkey2: INCX INCX BRA KBkey1KBkey3: LDA #$FF ; 未定义键用 FF标志KBkeyr:RTSKBTABLE FCB $EE,"1",$DE,"2",$BE,"3",$7E,"A" FCB $ED,"4",$DD,"5",$BD,"6",$7D,"B" FCB $EB,"7",$DB,"8",$BB,"9",$7B,"C" FCB $E7,"*",$D7,"0",$B7,"#",$77,"D" FCB $00

<<<

211

Init_LCD(LCD 初始化子程序 )• 入口 : 无 • 功能 : 初始化 LCD(HD44780)

• 调用子程序 :LCD_Command(LCD 命

令执行子程序 ) •占用 CPU 内部寄存器 :A,X

<<<

212

Init_LCDInit_LCD: BCLR LCD-RS,PTC ;令 LCD的 RS=0,R/W=0, 进行 LCD 初始化 BCLR LCD-RW,PTC LDA #%00111000 ; 功能设置 :8位数据接口 ,2行显示 ,5*7 点阵模式 JSR LCD_Command LDA #%00001000 ; 显示开关控制 :关显示,关光标显示 ,不闪烁 JSR LCD_Command LDHX #$0020 ; 等待 40us DBNZX * BCLR LCD-RS,PTC ;RS,RW 清零开始清屏 BCLR LCD-RW,PTC LDA #%00000001 ; 清屏指令 JSR LCD_Command LDHX #$2DF ; 等待清屏完毕 ,时间 >1.6msCLR-LCD-2-MS: ; 延时 AIX #-1 CPHX #0 BNE CLR-LCD-2-MS LDA #%00000110 ; 输入方式设置 : 数据读写操作后 ,AC自动增 1 ;显示不动 ,光标左移 JSR LCD_Command LDA #%00010100 ;光标移位设置 :光标右移一个字符位 ,AC自动加 1 JSR LCD_Command LDA #%00001100 ; 显示开关设置 : 开显示 , 关光标显示 ,不闪烁 JSR LCD_Command RTS

<<<

213

LCD_Command(LCD 命令执行子程序 )

• 入口 :A

• 功能 :对 A中指令使用 PORTA 作为输出口 ,• 到 LCD 进行命令执行或字符显示 •占用 CPU 内部寄存器 :A

<<<

214

LCD_CommandLCD_Command: PSHH ; 保护现场 PSHX LDHX #$0020 ; 等待 40us DBNZX * STA PTB ;把指令码送到 A 口 NOP NOP BSET LCD_E,PTC ;LCD 开始接受数据 , 置使能位为 1 NOP NOP BCLR LCD_E,PTC ;LCD 结束接受数据 , 置使能位为 0 LDHX #$0020 ; 等待 40us DBNZX * PULX ;恢复现场 PULH RTS

<<<

215

Show_LCD(LCD 显示子程序 )• 入口 :A,HX

• 出口 :HX 所指的内存二字节地址为 A 中

• 描述 : 转一字节 16 进制数为二字节

ASCII 码字符

<<<

216

Show_LCD

; 第一行Show_LCD: ; 进行显示数据寄存器 (DD RAM) 地址设置 BCLR LCD-RS,PTC

BCLR LCD-RW,PTC ; 设置前 8 个字符首 DD RAM 地址 LDA #%10000000

JSR LCD_Command

LDHX #$00 ; 显示前 8 个字符Show-First-8Byte:

BSET LCD-RS,PTC ;令 LCD的 RS=1,R/W=0, 写入数据到 DD RAM 中 BCLR LCD-RW,PTC

LDA LCD_Buffer1,X ;将 {LCD_Buffer+X} 的数据放入 A 作为入口 JSR LCD_Command

AIX #1

CPHX #$8

BNE Show-First-8Byte

LDA #%10001000 ; 设置后 8 个字符首 DD RAM 地址 BCLR LCD-RS,PTC

BCLR LCD-RW,PTC

JSR LCD_Command

LDHX #$08 ; 显示后 8 个字符 <<<

217

Show_LCD1Show-Next-8Byte:

BSET LCD-RS,PTC ;令 LCD的 RS=1,R/W=0, 写入数据到 DD RAM 中 BCLR LCD-RW,PTC

LDA LCD_Buffer1,X ;将 {LCD_Buffer+X} 的数据放入 A 作为入口 JSR LCD_Command

AIX #1

CPHX #$10

BNE Show-Next-8Byte

; 第二行 , 进行 DD RAM 地址设置 BCLR LCD-RS,PTC ;令 LCD的 RS= 0、 R/W=0

BCLR LCD-RW,PTC

LDA #%11000000 ; 设置 DD RAM 地址为 #%1000000 (即 40H)

JSR Lcd_Command ; 执行设置光标在 DDRAM 位置 LDHX #$0 ; 显示前 8 个字符 Show_F_8b2:

BSET LCD-RS,PTC ;令 LCD的 RS=1,R/W=0 :写数据 BCLR LCD-RW,PTC

LDA LCD_Buffer2,x ;将 LCD_Buffer 开始的中第 x 位数据存放入 A 中 JSR Lcd_Command ; 执行命令 AIX #1

CPHX #$8

BNE Show_F_8b2 ;完成前 8 个字符的显示<<<

218

Show_LCD2

; 进行 DD RAM 地址设置

LDA #%11001000 ; 设置 DDRAM 地址为 #%1000000 (即 48H)

BCLR LCD-RS,PTC ;令 LCD的 RS= 0、 R/W=0

BCLR LCD-RW,PTC

JSR Lcd_Command ; 执行命令

LDHX #$08 ; 显示后 8 个字符

Show_N_8b2:

BSET LCD-RS,PTC ;令 LCD的 RS=1,R/W=0 :写数据

BCLR LCD-RW,PTC

LDA LCD_Buffer2,x ;将 LCD_Buffer 开始的中第 x 位数据存放入 A 中

JSR Lcd_Command ; 执行命令

AIX #1

CPHX #$10

BNE Show_N_8b2 ;完成后 8 个字符的显示

RTS <<<

219

转码子程序TimeCH: PSHA ; 进栈 , 保存 A,H,X 中的内容 PSHH PSHX LDHX #$000A ; 取 10 DIV ; 除以 10,A 中放商 ,H 中放余数 ADD #$30 ; 实际数值加上 $30(!48)变 ASCII 码 PULX ;X 出栈 PULH ;H 出栈 STA ,X ;把 A 的内容存储到以 (X) 为地址的单元中 AIX #$1 ;立即数 1加到变址寄存器 , 转下一字符 PULA PSHH PSHX LDHX #$000A DIV PSHH PULA ADD #$30 PULX PULH STA ,X RTS

<<<

220

定时器溢出中断子程序Timer1OvF: INC Sec LDA Sec CMP #!60 BLO Tim1OvF_Exit CLR Sec INC Min ; 一分到 LDA Min CMP #!60 BLO Tim1OvF_Exit CLR Min INC Hou ; 一小时到

LDA Hou CMP #!24 BLO Tim1OvF_Exit CLR Sec CLR Min CLR Hou

<<<

221

定时器溢出中断子程序 1

Tim1OvF_Exit: LDA T1SC ; 清除定时器溢出标志位 BCLR 7,T1SC SendToDisp: LDA Hou ;将小时转为两字节 ACSII 码字符放入显示缓冲区 LCD_Buffer2: LDHX #LCD_Buffer2 JSR TimeCH LDA min ;将小时转为两字节 ACSII 码字符放入显示缓冲区 LCD_Buffer2: LDHX #{LCD_Buffer2+!3} JSR TimeCH LDA SEC ;将小时转为两字节 ACSII 码字符放入显示缓冲区 LCD_Buffer2: LDHX #{LCD_Buffer2+!6} JSR TimeCH JSR Show_LCD ; 显示起始数据 RTI

<<<

222

延时子程序Delay_ms: LDA #!248 ;0.5ms JSR Delay_ns LDA #!248 ;0.5ms JSR Delay_ns AIX #-!1 CPHX #!0 BNE Delay_ms ;4Cycles RTS ;4Cycles

<<<

223

延时子程序 1

Delay_ns:

NOP ;1Cycles

NOP ;1Cycles

DBNZA Delay_ns ;3Cycles

RTS ;4Cycles

<<<

224

中断矢量 ORG $FFE0 ; 键盘中断矢量 DW KBint ORG $FFF2 ; 时钟中断矢量 DW Timer1OvF ORG $FFFE ; 复位向量 DW MainInit

<<<

225

液晶显示 164 接口实验• 实验目的• 实验器材• 硬件接线• 软件功能• 程序清单

<<<

226

实验目的 :

掌握点阵字符型液晶显示 (LCD) 编程方法

227

实验器材 :

1.单片机2.LCD( 液晶显示屏 ) 3.74HC164(8 位移位寄存器 )

228

硬件接线 :

VCC

16151413121110090807060504030201

LC

D(H

D4478

0)

Q7Q6Q5Q4Q3Q2Q1Q0

B

A

CP

CR

VCC

74H

C164

MOS1

SPSCK

PTC3

PTC2PTC1PTC0

SSVCC

MC

68H

C908G

P3

2

229

软件功能 :

•开始运行时 ,LCD 显示“ Wait Receiving..”

•等待接收字符,当收到 16个字符时,显示之,重复此功能

230

程序清单: 程序说明 口地址定义 SPI地址定义 SCI串行通信口定义 变量定义 系统初始化

主程序 LCD初始化子程序 LCD命令执行子程序 74HC164初始化 LCD显示子程序 中断矢量

231

*-------------- 程序说明 --------------------------** 文件名 LCD.ASM* 硬件连接: 74HC164的Q0-Q7 分别接 LCD的DB0-

DB7;* 74HC164的MR,CLK 接分别 MCU的

PTC3,SCK;* 74HC164的 B接MCU的VCC(+5V);* 74HC164的 A 接MCU的MOSI;* LCD的 E,R/W,RS 分别接的

PTC2,PTC1,PTC0。* 程序描述: 1.开始运行时 ,LCD 显示“ Wait Receiving..”* 2. 等待接收字符,当收到 16 个字符时显示之,* 重复此功能。* 目的:掌握点阵字符型液晶显示 (LCD) 编程方法*备注说明:从 PC 机输入被显示的 16 个字符,以串行通信方* 式发送到单片机,在液晶屏上显出这些字符。*-------------------------------------------------*

232

*----- 口地址定义 -------------------------------PTC EQU $0002 ;C 口数据寄存器LCD-RS EQU 0 ;LCD 寄存器选择信号接 PTC0

LCD-RW EQU 1 ; 读写信号接 PTC1

LCD-E EQU 2 ;LCD 使能信号接 PTC2

HC164-CR EQU 3 ;74HC164 (移位寄存器) ; 清除端接 PTC3

DDRC EQU $0006 ;C 口数据方向寄存器*----SPI( 串行外设接口 )地址定义 -------------------SPCR EQU $0010 ;SPI 控制寄存器SPSCR EQU $0011 ;SPI 状态和控制寄存器BIT-SPTE EQU 3 ;SPI 发送器空标志位SPDR EQU $0012 ;SPI 数据寄存器

233

*----SCI 串行通信口地址 ------------------------SCS1 EQU $0016 ; 串行通信接口状态寄存器地址

SCDR EQU $0018 ; 串行通信接口数据寄存器地址

*---- 变量定义 ---------------------------------ORG $0090

BYTEDISPLY RMB 1 ; 临时存放一个字符

LCD-BUFFER RMB 16 ; 存放 16字节

FlashStartAddr equ $8000

; 程序开始地址(因芯片不同可以更改)

**********************************************

234

*--------- 主程序 -------------------------------- ORG FlashStartAddr

MainInit: ; 复位后程序从此开始执行 ; 系统初始化 SEI ; 禁止所有中断 LDHX #$023F ; 堆栈初始化,放入 GP32的 RAM 最高端

TXS JSR Init0 ; 调系统初始化子程序 Init0 ,初始学习时跳过此处

;I/O 初始化 NOP ; 初始化 LDA #%00111010 ;SPI 初始化设置 : 禁止中断 , ; 主机方式 , 时钟低电平有 SPSCK启动移位、 ;脉冲 ,普通推拉模式 , 允许 SPI

STA SPCR LDA #%00000000 ; 禁止中断 , 禁止错误检测 , ; 时钟分频系数为 2 STA SPSCR

235

LDA DDRC ; 初始化 E, RW, RS 控制信号

ORA #%00001111 ;PTC3-0 为输出 STA DDRC

LDHX #$00DISPLAY1: ; 把要显示的 16 个初始字符 ; 放入 LCD-BUFFER 中 LDA DISPLAYBYTES,X

STA LCD-BUFFER,X

AIX #1

CPHX #$10 BNE DISPLAY1 ; 循环 16次 BRA START

236

DISPLAYBYTES FCB "WAIT RECEIVING.."

START:

JSR INIT-74HC164 ; 初始化 74HC164

;( 移位寄存器 )

JSR INIT-LCD ;LCD 初始化

JSR SHOW-LCD-BUFFER ; 把 LCD-BUFFER 中的

;16 个字符送 LCD 显示

237

LDHX #$00 DISPLAY2: ; 从 PC 机接收 16 个字符放入 LCD-

;BUFFER 开始的内存中 BRCLR 5,SCS1,* ; 与 PC 机串行通信 , 判断接收器 ;是否满 LDA SCDR ; 读 SCI 数据寄存器 STA LCD-BUFFER,X

AIX #1

CPHX #$10

BNE DISPLAY2

JMP START

***************************************************

238

*---INIT-LCD(LCD 初始化子程序 )------------------* 入口 : 无* 功能 : 初始化 LCD(HD44780)

* 调用子程序 :LCDCOMMAND(LCD 命令执行子程序 )*占用 CPU内部寄存器 :A,X

*----------------------------------------------

INIT-LCD: BCLR LCD-RS,PTC ;令 LCD的 RS=0,R/W=0,

; 进行 LCD 初始化 BCLR LCD-RW,PTC LDA #%00111000 ; 功能设置 :8 位数据接口 , ;2 行显示 ,5*10点阵模式 JSR LCDCOMMAND

239

LDA #%00001000 ; 显示开关控制 : 开显示, ; 关光标显示 , 不闪烁 JSR LCDCOMMAND JSR INIT-74HC164 ;74HC164( 移位寄存器 ) ; 初始化 BCLR LCD-RS,PTC ;RS,RW 清零开始清屏 BCLR LCD-RW,PTC BRCLR BIT-SPTE,SPSCR,* ; 判断发送数据寄存器 ;是否为空 LDA #%00000001 ; 清屏指令 JSR LCDCOMMAND LDHX #$2DF ; 等待清屏完毕 , 时间 >1.6ms

240

CLR-LCD-2-MS: ; 延时 AIX #-1 CPHX #0 BNE CLR-LCD-2-MS LDA #%00000110 ; 输入方式设置 : 数据读写

;操作后 ,AC自动增 1 显示不动 , ;光标左移 JSR LCDCOMMAND LDA #%00010100 ; 光标移位设置 :光标右 ; 移一个字符位 ,AC自动加 1 JSR LCDCOMMAND LDA #%00001100 ; 显示开关设置 : 开显示 , ; 关光标显示 , 不闪烁 JSR LCDCOMMAND RTS

241

*----LCDCOMMAND(LCD 命令执行子程序 )----------

* 入口 :A

* 功能 :对 A 中指令送 LCD(HD44780), 进行命令执行或

*字符显示*占用 CPU内部寄存器 :A

*-------------------------------------------

LCDCOMMAND:

PSHH ; 保护现场

PSHX

PSHA ; 保护入口指令码

BRCLR BIT-SPTE,SPSCR,* ; 测试状态 , 发送数据 ; 寄存器是否为空

242

JSR INIT-74HC164 ; 初始化 74HC164 芯片

PULA ; 弹出入口指令码

STA SPDR ; 把指令码发送出去

BRCLR BIT-SPTE,SPSCR,* ; 测试发送完毕

NOP

NOP

BSET LCD-E,PTC ;LCD 开始接受数据 , ; 置使能位为 1

243

NOP

NOP BCLR LCD-E,PTC ;LCD结束接受数据 , 置 ; 使能位为 0 LDHX #$0020 ; 等待 40us

DBNZX * PULX ; 恢复现场

PULH

RTS

********************************************

244

*---INIT-74HC164(74HC164 初始化 )--------------* 入口 : 无* 功能 : 清空 74HC164

*占用 CPU内部寄存器 :HX

*-------------------------------------------

INIT-74HC164:

BCLR HC164-CR,PTC ;CR 为 0 清除 74HC164 中的数据

BSET HC164-CR,DDRC LDHX #$0020 ; 等待 40us

DBNZX * BSET HC164-CR,PTC ; 清除完毕 ,74HC64的 CR

; 转为高电平 RTS

245

*----SHOW-LCD-BUFFEER(LCD 显示子程序 )-------*

* 入口 :内存 LCD-BUFFER 开始的 16 个地址中存放要显

* 示的字符编码* 功能 : 显示内存 LCD-BUFFER 开始的 16字节数据* 调用 :LCDCOMMAND 子程序*占用 CPU内部寄存器 :A,HX

*------------------------------------------*SHOW-LCD-BUFFER: ; 进行显示数据寄

存器 ;(DD RAM) 地址设置 BCLR LCD-RS,PTC BCLR LCD-RW,PTC ; 设置前 8 个字符 ;首DDRAM 地址

246

LDA #%10000000

JSR LCDCOMMAND LDHX #$0 ; 显示前 8 个字符

SHOW-FIRST-8BYTE: BSET LCD-RS,PTC ; 令 LCDRS=1,R/W=0,

; 写入数据到 DD RAM 中

BCLR LCD-RW,PTC LDA LCD-BUFFER,X ; 将 {LCD-

BUFFER+X}

; 的数据放入 A 作为入口

JSR LCDCOMMAND

247

AIX #1

CPHX #$8

BNE SHOW-FIRST-8BYTE LDA #%11000000 ; 设置后 8 个字符首DD

RAM 地址

BCLR LCD-RS,PTC

BCLR LCD-RW,PTC

JSR LCDCOMMAND LDHX #$08 ; 显示后 8 个字符

SHOW-NEXT-8BYTE: BSET LCD-RS,PTC ; 令 LCD的 RS=1,R/W=0,写入

; 数据到 DD RAM 中

248

BCLR LCD-RW,PTC LDA LCD-BUFFER,X ; 将 {LCD-

BUFFER+X} 的数据 ; 放入 A 作为入口 JSR LCDCOMMAND

AIX #1

CPHX #$10

BNE SHOW-NEXT-8BYTE

RTS

********************************************

-- 中断矢量 --------------------------------* ORG $FFFE ; 复位向量 DW MAININIT

249

系统初始化• Init0: ; 系统初始化 Init0 子程序• LDA #%00000001 ; 初始化 CONFIG2• STA $001E• LDA #%00111101 ; 初始化 CONFIG1• STA $001F• CLR $0036 ; 初始化 PTCL• MOV #$01,$0036• MOV #$01,$0038• MOV #$2C,$0039• MOV #$80,$003A• BSET 5,$0036• BSET 7,$0037• BSET 4,$0036• RTS

250

硬件检测实验• 实 验 目 的• 实 验 器 材• 硬 件 接 线• V B 界 面• 软 件 功 能• 程 序 清 单• 备 注 说 明

<<<

251

实验目的:

对实验板上所有硬件联合编程

252

实验器材:

1.SD-1 型在线编程实验仪2. 导线若干

253

硬件接线:

1) PTD.0--PTD.5 接指示灯 8--3 ,

2) PTC.3 接指示灯 1和 PTC.4 接拨线开关

254

软件功能:1、 LCD 上下两层每 0.5秒滚动显示以下内容

"0123456789ABCDEF""abcdefgh…xyz"

每滚动一次,都将 PTC.3 取反

2、当键盘任一键按下时, LCD 下层清屏显示该字 符, 0.5秒后,恢复“ abcdefgh…xyz”滚动 显示

3、串行口向 PC 机发送 189作为握手信号,接着发一开关信号, PC 机接收到握手信号189和开关信号回送一个握手信号 并发送一个 0 到 63 之间的数,并将发送数据在界面上用指示灯模拟显示 , 串行口接收后,送入 PTD, 并用指示灯高 6 位显示

255

VB 界面

256

程序清单:• 口地址定义• 变量定义• 系统初始化• 总循环• 扫描读键值子程序• 键盘中断子程序键盘• 中断初始化子程序

• 键盘转化为具体值子程序• LCD初始化子程序• LCD命令执行子程序• LCD显示子程序• 延时子程序• 系统初始化子程序• 中断矢量

257

口地址定义

PTA equ $0000 ;A 口寄存器

PTB equ $0001 ;B 口寄存器

PTC equ $0002 ;C 口寄存器

PTD equ $0003 ;D 口寄存器

DDRA equ $0004 ;A 口方向寄存器

DDRB equ $0005 ;B 口方向寄存器

DDRC equ $0006 ;C 口方向寄存器

DDRD equ $0007 ;D 口方向寄存器

PTAPUE equ $000D ;A 口上拉电阻允许寄存器

PTE equ $0008 ;E 数据寄存器<<<

258

寄存器及相关变量定义SCC1 EQU $0013 ;SCI 控制寄存器 1

SCC2 EQU $0014 ;SCI 控制寄存器 2

SCSR EQU $0016 ; 串行通信接口状态寄存器地址SCDR EQU $0018 ; 串行通信接口数据寄存器地址SCBR EQU $0019 ;SCI 波特率寄存器INTKBSCR EQU $001A ; 键盘状态和控制寄存器INTKBIER EQU $001B ; 键盘中断允许寄存器LCD-RS EQU 0 ;LCD 寄存器选择信号接 PTC0

LCD-RW EQU 1 ; 读写信号接 PTC1

LCD-E EQU 2 ;LCD使能信号接 PTC2

b_TDRF EQU 7 ; 发送缓冲区空标志位B_TC EQU 6 ; 发送完成标志位b_RDRF EQU 5 ; 接收器满标志位 <<<

259

内存变量定义

RAMstartAddr equ $0040 ;RAM 的起始地址(因芯片不同可以更改)

FlashStartAddr equ $8000 ; 程序开始地址(因芯片不同可以更改)

org RAMstartAddr ;RAM 的起始地址Lcd-Buffer RMB 16 ;LCD上层值Lcd-Buffer1 RMB 26 ;LCD下层值Lcd-Buffer2 RMB 16 ;LCD 键盘值TmpVar1 rmb 1 ; 变量 TmpVar1, 缓冲使用TmpVar2 rmb 1 ; 变量 TmpVar2, 缓冲使用KB_Value rmb 1 ; 键盘按键值LCD_Loop RMB 1 ;LCD 循环变量

<<<

260

主程序 org FlashStartAddr ; 程序起始地址MainInit: ; 复位后程序从此开始执行 ; 系统初始化 SEI ; 禁止所有中断 LDHX #$023F ; 堆栈初始化,放入 GP32的 RAM 最高端 TXS JSR Init0 ; 调系统初始化子程序 Init0 ,初始学习时跳过此处 ;I/O 初始化 LDA #%11111111 ;A 口为输出 STA DDRA STA DDRD STA PTD STA DDRB LDA #%00001111 ;PTC0-PTA3 为输出 ,PTC4 为输入 STA DDRC STA PTC

<<<

261

串行口初始化和键盘中断

;---- 串行口初始化 ------------------------------------------------- LDA #%01000000 ;D6(ENSCI)=1, 允许 SCI, 其它位为 0, ;正常码输出 ,8位数据 ,无检验 STA SCC1 LDA #%00001100 ;允许发送器 ,允许接收器 ,不允许发送与接收中断 STA SCC2 LDA #%00000010 ; 波特率为 9600 STA SCBR ;RAM 区 ;---- 设置键盘中断,开放键盘中断 JSR KB_Init ; 执行键盘初始化程序 BCLR 1,INTKBSCR ; 开放键盘中断 (IMASKK=0) CLI

262

主循环开始处START: JSR INIT-LCD ;LCD 初始化 JSR Display MOV #$00,LCD_loopBEGIN: LDA LCD_Loop AND #$00000001 ; 取出最后一位,判断是否为 0 CMP #$0 BNE CON BSET 3,PTC ;PTDC.3=1.PTC.4=0 BCLR 4,PTC JMP CON1 CON: BCLR 3,PTC ;PTDC.3=1.PTC.4=0 BSET 4,PTC

<<<

263

主循环 1CON1: LDA LCD_Loop ; 取出循环变量值 CMP #$10 ;判断是否大于 16 BLO LcdBuffEnd ; 若大于取模( A-16-->A) SUB #$10LcdBuffEnd: JSR Show-Lcd-Buffer1 ; 显示 LCD上层 16 字符 LDA LCD_Loop JSR Show-Lcd-Buffer2 ; 显示 LCD下层 26 字符循环 LDA #!86 ; 发送握手信号:数字 86 BRCLR 7,SCS1,* ; 测试第 7位直到为 1,即发送出 STA SCDR ;A→SCDR, 发送出去 ;取 C 口开关量 BRCLR 4,PTC,PTC4_0 ;判断 PTC4 值 LDA #!1 ;PTC4=1, 允许发送 BRA PTC4_EXITPTC4_0: LDA #!0 ;PTC4=0, 不允许发送PTC4_EXIT: ; 发送数据 BRCLR 7,SCS1,* ; 测试第 7位直到为 1,即发送出去 STA SCDR ;A→SCDR, 发送出去 LDHX #$FFFF ; 延时

<<<

264

主循环 2CommTest1: BRCLR 5,SCS1,CommTest2 ; 接收回送数据 LDA SCDR ; CMP #!86 ;判断是否为 86 BNE CommTest2 ; 不是跳出 LDA LCD_Loop ;回送本次循环值 BRCLR 7,SCS1,* ; 测试第 7位直到为 1,即发送出去 STA SCDR ;A→SCDR, 发送出去 BRCLR 5,SCS1,* ; 接收 PC 机发送用于 PTD 显示的数据 LDA SCDR ; 取数 STA PTD ; 放入 PTD 口,并送灯显示 JSR DelaySubCommTest2: AIX #-1 ;HX-1 CPHX #$0000 BNE CommTest1 ;判断延时是否结束 INC LCD_Loop ; 循环变量加 1 LDA LCD_Loop ;将循环变量送入 A CMP #!26 ;判断是否循环 26次 BNE BEGIN JMP START

<<<

265

系统初始化

Init0: ; 系统初始化 Init0 子程序 LDA #%00000001 ; 初始化 CONFIG2 STA $001E LDA #%00111101 ; 初始化 CONFIG1 STA $001F CLR $0036 ; 初始化 PTCL MOV #$01,$0036 MOV #$01,$0038 MOV #$2C,$0039 MOV #$80,$003A BSET 5,$0036 BSET 7,$0037 BSET 4,$0036 RTS

<<<

266

键盘中断初始化子程序 (KB_Init)功能:度被定义为键盘中断的引脚进行初始化,但未开放键盘中断占用 CPU 内寄存器: A *KB_Init: LDA #%00 ; 定义 A 口之前复位 PTA STA PTA LDA #%00001111 ; 定义 A 口 6-4 为输入, 3-0 为输出 STA DDRA LDA #%11110000 ; 定义 A 口 7-4 有上拉电阻 STA PTAPUE BSET 1,INTKBSCR ;屏蔽键盘中断 (IMASK=1) LDA #%11110000 ; 允许 KBIE7-4pin 中断进入 STA INTKBIER BSET 2,INTKBSCR ; 清除键盘中断请求 (ACKK=1) RTS

<<<

267

扫描读取键值 (KB_A)KB_A: MOV #%11111110,TmpVar1 ;使第一根行线为 0( 低电平 ) LDX #$04 ;将扫描 4根行线KB_A1: LDA PTA ;取 PTA->A ORA #%00001111 ;PTA7-4 保留原态, PTA3-0 令为 1 AND TmpVar1 ;令 PTAn=0,n=0、 1、 2、 3 STA PTALDA PTA ; 看第 n列是否有键按下 AND #%11110000 ;PTA7-4 保留原态,令低 4 为 =0 CBEQA #$F0,KB_A2 ;A 等于 $F0, 说明本列线上没有键家按下,在转 KB_A2

;A 不等于 $F0,找到了被按下得键取键值 -〉 A LDA PTA BRA KB_A3KB_A2: SEC ;令 C=1 ROL TmpVar1 ;使下一个列线为 0 DBNZX KB_A1 ; 对列线循环 LDA #$FF ; 没有键被按下为 $FFKB_A3: RTS

<<<

268

键值转为定义值子程序 (KB_def)KB_def: LDHX #$0000KB_def1: LDA KB_Table,X ; BEQ KB_def3 ;=0, 表示表中未定义此键值 CMP KB_Value ; 与入口键值相比较 BNE KB_def2 ; 不等,未找到转 KB_key2 INCX ;找到 LDA KB_Table,X ; 取键定义值 -〉 A BRA KB_defR KB_def2: INCX INCX BRA KB_def1KB_def3: LDA #$FF ; 未定义键用 FF标志KB_defR: RTSKB_Table FCB $EE,"1",$DE,"2",$BE,"3",$7E,"A" FCB $ED,"4",$DD,"5",$BD,"6",$7D,"B" FCB $EB,"7",$DB,"8",$BB,"9",$7B,"C" FCB $E7,"*",$D7,"0",$B7,"#",$77,"D" FCB $00

<<<

269

键盘中断子程序 (KB_Int)KB_Int: PSHH ; 保护 H( 其他 CPU 寄存器已自动保护 ) SEI BSET 1,INTKBSCR ; 禁止键盘中断 JSR KB_A ; 调子程序 KB_A 取得键值 -〉 A STA KB_Value ; 放内存 KB_Value 中 JSR KB_def STA Lcd-Buffer2 LDA #$0 JSR Show-Lcd-Buffer3 JSR DelaySub PULH ;H 出栈 ( 其他 CPU 寄存器已自动保存 ) JSR KB_Init ; 执行键盘初始化程序 BCLR 1,INTKBSCR ; 开放键盘中断 (IMASKK=0) CLI RTI

<<<

270

INIT-LCD(LCD 初始化子程序 )INIT-LCD: BCLR LCD-RS,PTC ;令 LCD的 RS=0,R/W=0, 进行 LCD 初始化 BCLR LCD-RW,PTC LDA #%00111000 ; 功能设置 :8 位数据接口 ,2 行显示 ,5*7点阵模式 JSR LcdCommand LDA #%00001000 ; 显示开关控制 :关显示,关光标显示 , 不闪烁 JSR LcdCommand LDHX #$0020 ; 等待 40us DBNZX * BCLR LCD-RS,PTC ;RS,RW 清零开始清屏 BCLR LCD-RW,PTC LDA #%00000001 ; 清屏指令 JSR LcdCommand LDHX #$2DF ; 等待清屏完毕 , 时间 >1.6msCLR-LCD-2-MS: ; 延时 AIX #-1 CPHX #0 BNE CLR-LCD-2-MS LDA #%00000110 ; 输入方式设置 : 数据读写操作后 ,AC自动增 1

JSR LcdCommand LDA #%00010100 ;光标移位设置 :光标右移一个字符位 ,AC自动加 1 JSR LcdCommand LDA #%00001100 ; 显示开关设置 : 开显示 ,关光标显示 , 不闪烁 JSR LcdCommand RTS

<<<

271

LcdCommand(LCD 命令执行子程序 )LcdCommand: PSHH ; 保护现场 PSHX LDHX #$0020 ; 等待 40us DBNZX * STA PTB ;把指令码送到 B 口 NOP NOP BSET LCD-E,PTC ;LCD 开始接受数据 ,置使能位为 1 NOP NOP BCLR LCD-E,PTC ;LCD 结束接受数据 ,置使能位为 0 LDHX #$0020 ; 等待 40us DBNZX * PULX ;恢复现场 PULH RTS <<<

272

Show-Lcd-Buffer1(LCD 显示上层子程序 )

Show-Lcd-Buffer1: ; 进行显示数据寄存器 (DD RAM) 地址设置 PSHA

BCLR LCD-RS,PTC

BCLR LCD-RW,PTC ; 设置上层 16 个字符首 DD RAM 地址 LDA #%10000000

JSR LcdCommand

LDHX #$0 ; 显示上层 16 个字符 PULA

PSHA

SHOW-FIRST-16BYTE:

PSHX

PSHA

BSET LCD-RS,PTC ;令 LCD的 RS=1,R/W=0, 写入数据到 DD RAM 中BCLR LCD-RW,PTC

TAX

<<<

273

中断矢量与复位矢量

ORG $FFE0 ; 键盘中断矢量 DW KB_Int

ORG $FFFE ; 复位矢量 DW MainInit

<<<

274

程序延时子程序 (DelaySub)DelaySub: PSHH PSHX PSHA LDA #$14DelaySub1: LDHX #$03E8DelaySub2: PSHH PSHX LDHX #$0050 ; 延时 0.1 秒 DBNZX * PULX PULH DBNZX DelaySub2 DBNZA DelaySub1 PULA PULX PULH RTS <<<

275

Show-Lcd-Buffer1(LCD 显示上层子程序 )1

LDA Lcd-Buffer,X ;将 {Lcd-Buffer+X} 的数据放入 A 作为入口 JSR LcdCommand

PULA

INCA

CMP #10

BNE SKIP1

LDA #0

SKIP1:

PULX

AIX #1

CPHX #$10

BNE SHOW-FIRST-16BYTE

PULA

RTS

<<<

276

备注说明• 本程序可用于对实验板硬件进行检测• 包括:• 键盘、 LCD 、指示灯、串行口,

PTA、 PTB、 PTC、 PTD 、蜂鸣器等

<<<

277

定时器输入中断捕捉实验

• 实验目的• 实验器材• 硬件接线

• 软件功能• 程序清单• 备注说明

<<<

278

实验目的 :

熟悉定时器接口模块的使用

279

实验器材 :

1.SD-1 型在线编程实验仪2. 导线若干

280

硬件接线 :

PTA1

MO

TO

RO

LA

GP

32 MC

U

VCC

281

软件功能 :

① 系统初始化: CONFIG2、 1 、 PTCL、堆栈

② 以输入捕捉中断方式 , 取反指示灯 PTA1 , 使其闪动

282

程序清单 :

• 程序说明• 寄存器地址定义• 内存变量定义• 主程序• 系统初始化• 主循环• 定时器1通道0输入捕捉中断子程序• 向量区

283

*----------------- 程序说明 -----------------------------------------*

* 文件名: Tim1Ch0I.ASM-- 定时器接口模块编程实验 2- 输入捕捉

* 功能: • ① 系统初始化: CONFIG2、 1 、 PTCL、堆栈 • ② 以输入捕捉中断方式 , 取反指示灯 PTA1 ,使其闪动

说明 : 本例是将定时器 1 通道 0(21脚 ) 设为“跳变沿捕捉” ( 即电平发生变化时产生中断 ),

* 验证方法是将 21脚不断接高电平、低电平,此时指示灯PTA1 状态跟随改变 *

284

*------------- 寄存器地址 ------------------------------DDRA EQU $0004 ;A 口数据方向寄存器PTA EQU $0000 ;A 口数据寄存器T1SC EQU $0020 ; 定时器 1 状态和控制寄存器T1CNTH EQU $0021 ; 定时器 1 计数寄存器 ( 高位 )T1CNTL EQU $0022 ; 定时器 1 计数寄存器 ( 低位 )T1MODH EQU $0023 ; 定时器 1 模数寄存器 ( 高位 )T1MODL EQU $0024 ; 定时器 1 模数寄存器 ( 低位 )T1SC0 EQU $0025 ; 定时器 1 通道 0 状态和控制寄存器T1CH0H EQU $0026 ; 定时器 1 通道 0 的通道寄存器 ( 高位 )T1CH0L EQU $0027 ; 定时器 1 通道 0 的通道寄存器 ( 低位 )RAMstartAddr EQU $0040 ;RAM 的起始地址(因芯片不同可以更

改)FlashStartAddr EQU $8000 ; 程序开始地址(因芯片不同可以更

改)

285

*---------内存变量 ----------------------------------------- org FlashStartAddr

MainStart: SEI ; 禁止所有中断 LDHX #$023F ; 堆栈初始化, ; 放入 GP32的 RAM 最高端 TXS

286

;------- 系统初始化 ----------------------------- MOV #%00000001,$001E ; 初始化 CONFIG2 MOV #%00111101,$001F ; 初始化 CONFIG1

MOV #%00110001,$0036 ; 初始化 PTCL BSET 7,$0037 MOV #$01,$0038 MOV #$2C,$0039 MOV #$80,$003A BSET 1,DDRA 定义 PTA.1 为输出(指示灯) BSET 1,PTA

287

; 定时器 1 通道 0 初始化 LDA #%00110000 ; 不允许溢出中断、不启动计数、 ; 分频因子 =1 STA T1SC ; 定时器 1 状态和控制寄存器 LDA #%01001100 ; 设为输入捕捉模式,允许输入捕捉中断 ,

; 跳变沿捕捉 ( 即电平发生变化时产生中断 ) STA T1SC0 ; 定时器 1 通道 0 状态和控制寄存器 BCLR 5,T1SC ; 允许定时器 1 计数寄存器计数 CLI ; 开放中断 -------------------- 初始化结束 -------------------

288

*======== 主循环开始处 ========================

MainLoop:

NOP ; 仅为实验例程,无其它事务处理 JMP MainLoop ; 转总循环

289

*---------- 定时器 1 通道 0 输入捕捉中断子程序 --------Timer1CH0In: PSHH ; 保护 h 寄存器 ; ; 至此 , 可读取计数器的值,可在此处添加用户的程序 ; 本程序仅为实验例程,用指示等状态改变,说明发生了中断 BRCLR 1,PTA,PTA1SET ; 指示灯状态变换 BCLR 1,PTA BRA PTA1CLRPTA1SET: BSET 1,PTAPTA1CLR: ; LDA T1SC0 ; 清除定时器 1 通道 0 输入捕捉中断标志位 BCLR 7,T1SC0 ; PULH ;释放 h 寄存器 RTI

290

PTA1SET:

BSET 1,PTA

PTA1CLR:

;LDA T1SC ; 清除定时器溢出标志位 BCLR 7,T1SC

RTI ; 中断返回

291

*---------------------------- 向量区 --------------------------------

ORG $FFF6 ; 定时器 1 通道 0 输入捕捉中断向量DW Timer1CH0In

ORG $FFFE ; 复位向量DW MainStart