吉林大学单片机实验一:投币机 [预备知识+电路图+代码+思考题]

1.预备知识

        学过微机系统,我们知道,汇编语言与硬件结构是紧密绑定的,要写汇编程序,须先深谙要运行此程序的机器的硬件结构。

        关于MCS-51单片机的硬件结构,最核心就是得掌握RAM的结构,因为寄存器在RAM里,写汇编代码主要就得熟悉各种寄存器的功能,学校资料附录里讲的略有一点不清楚。

        首先“寄存器在RAM里”是怎么回事?RAM是数据存储器,寄存器是寄存器,我们曾学过的8086,也自己用logisim搭建过CPU,我们知道CPU中有一个组件叫“寄存器堆”,Regs,而RAM是存储器,如今怎么将二者混为一谈?

        因为MCS-51是单片机,和我们曾接触过的CPU不太一样,

        1.它没有寄存器堆,

        是RAM中的部分单元来充当寄存器的,所以说“寄存器在RAM里”。

        RAM的具体结构如下:

        工作寄存器区:

        内部 RAM 的 0-1FH 为 4 组工作寄存器区,每个区有 8 个工作寄存器(R0 -R7)。在同一时刻,只能使用一组工作寄存器,这是通过程序状态字 PSW 的地 3,4 位来控制的。例如当此两位为 00 时,使用第 0 组工作寄存器,对应于 00H 到 07H 的内部 RAM 空间。也就是说,这时指令中使用 R0 与直接使用 00 单元是 等价的,不过使用工作寄存器的指令简单,且执行快。

        位寻址区:

        内部 RAM 的 20H-2FH 为位寻址区域,这 16 个单元的每一位都对应一个位 地址,占据位地址空间的 0-7FH。每一位都可以独立置位、清除、取反等操作,

        堆栈区:

        栈顶指针SP的初始值为07H,恰好和R7是重的,所以我们要使用堆栈必须设定SP的值

·       通用数据区:

        初始为空的数据区,专门用于给用户存储中间结果等数据

        特殊功能寄存器区:

        

        学校的附录中并没有给出SFR的具体结构,只是简略带过,差评(手动狗头

        2.程序和数据分开存储,

        我们曾经接触过的CPU,存储器就是电脑的内存,内存是连续的一大块存储区域,内部分区为代码区、数据区、堆区、栈区,而如今的单片机,有完全分离的两个存储器——代码存储器RAM&数据存储器ROM。我们曾经接触的CPU,是应用于现代完整个人电脑的CPU,而如今学的是单片机,更为微型,两者架构存在差别。

        

        当然单片机与常规PC的CPU还有诸多不同,不过本人觉得最显著就这两点,至少知道这些已经足够我们建立对单片机的初步认识和完成实验1了。

2.题目要求

一.画图

二.编程 

3.答案(仅供参考)

电路图:

 代码:

$NOMOD51
$INCLUDE (8051.MCU)

ORG 0000H  ; 程序的起始地址

    CLR LED2
    MOV P2, #3FH

START:
    CALL READ_SWITCHES
    CJNE A, #0, LIGHT_LED1 ; 检查是否点亮LED1
    CLR LED1  ; 如果没有开关被激活,则熄灭LED1
    JMP WAIT

LIGHT_LED1:
    SETB LED1
    JMP WAIT

WAIT:
    CALL CALCULATE_TOTAL
    CALL DISPLAY_AMOUNT    ;展示总金额

CHECK_VALUE:
    ; 检查总金额是否大于预定值
    MOV B, #PREDEFINED_VALUE  ; 将预定值加载到寄存器B中
    SUBB A, B                  ; 比较累加器A与B的值
    JC RETURN_TO_START   ; 如果累加器A的值大于B的值,则跳转到GREATER_THAN_VALUE
    JMP GREATER_THAN_VALUE

GREATER_THAN_VALUE:
    ; 总金额大于预定值
    JMP FLASH_LED2

FLASH_LED2:
    SETB LED2
    CALL DELAY
    CLR LED2
    CALL DELAY

RETURN_TO_START:
    JMP START

; 子程序:读取开关状态
READ_SWITCHES:
    ; 读取开关状态并存储到寄存器
    MOV A, P1
    ANL A, #0FH  ; 只保留低四位,因为开关连接在P1.0至P1.3
    RET

; 子程序:计算总金额
CALCULATE_TOTAL:
    ; 根据开关状态计算总金额并存储到累加器ACC
    MOV B, #0  ; 使用寄存器B来累计金额
    JNB BIT0, SKIP1  ; 如果开关1为高电平,则加上其价值
    MOV A, B
    ADD A, #SWITCH1_VALUE
    MOV B, A
SKIP1:
    JNB BIT1, SKIP2  ; 如果开关2为高电平,则加上其价值
    MOV A, B
    ADD A, #SWITCH2_VALUE
    MOV B, A
SKIP2:
    JNB BIT2, SKIP3  ; 如果开关3为高电平,则加上其价值
    MOV A, B
    ADD A, #SWITCH3_VALUE
    MOV B, A
SKIP3:
    JNB BIT3, SKIP4  ; 如果开关4为高电平,则加上其价值
    MOV A, B
    ADD A, #SWITCH4_VALUE
    MOV B, A
SKIP4:
    MOV A, B  ; 将累加器B的值复制到累加器A
    RET
    
; 子程序:显示总金额
DISPLAY_AMOUNT:
    ; 根据累加器ACC中的值显示相应的数字
    MOV DPTR, #CODE_TABLE
    MOV B, A
    MOVC A, @A+DPTR
    MOV P2, A
    MOV A, B
    RET

; 子程序:延时
DELAY:
    ; 延时子程序
    MOV R1, #5
DELAY_LOOP1:
    MOV R2, #200
DELAY_LOOP2:
    DJNZ R2, $  ; 内部循环
    DJNZ R1, DELAY_LOOP1  ; 外部循环
    RET

; 数据表:7段数码管显示代码
CODE_TABLE: DB 0C0H, 0F9H, 0A4H, 0B0H, 099H, 092H, 082H, 0F8H, 080H, 090H

; 预定义值
PREDEFINED_VALUE   EQU 5  ; 预定金额值

; LED端口号
LED1 EQU P1.4  ; LED1连接到P1.4
LED2 EQU P1.5  ; LED2连接到P1.5

; 开关对应的值
SWITCH1_VALUE  EQU 1
SWITCH2_VALUE  EQU 2
SWITCH3_VALUE  EQU 2
SWITCH4_VALUE  EQU 5

; 开关状态检查位
BIT0 EQU P1.0
BIT1 EQU P1.1
BIT2 EQU P1.2
BIT3 EQU P1.3

END
;====================================================================

4.思考题

        像一二问这种完全可以交给GPT啦

        

1.MCS-51中可存取单元及存取方式

MCS-51单片机中,可供程序访问的单元主要包括:

1. 内部RAM

  • 作用: 用于存放程序运行时需要频繁访问的数据,如变量、中间结果等。
  • 组成: 包括通用寄存器组(R0-R7)、特殊功能寄存器(SFR)和位寻址区。
  • 存取方式:
    • 直接寻址: 通过寄存器或立即数直接指定地址。
    • 寄存器间接寻址: 使用寄存器作为地址指针,间接访问存储单元。
  • 特点: 访问速度快,但容量有限。

2. 外部RAM

  • 作用: 扩展内部RAM的容量,用于存放大量数据。
  • 存取方式: 通过数据指针寄存器(DPTR)间接寻址。
  • 特点: 容量大,但访问速度比内部RAM慢。

3. ROM

  • 作用: 存放程序代码和常量数据。
  • 存取方式: 通常只读,不能修改。
  • 特点: 内容非易失,掉电后数据不会丢失。

4. 特殊功能寄存器(SFR)

  • 作用: 控制单片机的各种功能,如定时器、中断、I/O端口等。
  • 存取方式: 直接寻址。
  • 特点: 每个SFR都有特定的功能,不能随意修改。

5. I/O端口

  • 作用: 与外部设备进行数据交换。
  • 存取方式: 直接寻址。
  • 特点: 可以读写外部设备的数据。

各单元之间的区别和联系

单元主要功能存取方式特点
内部RAM存放变量、中间结果直接寻址、寄存器间接寻址访问速度快,容量有限
外部RAM扩展存储空间DPTR间接寻址容量大,访问速度相对较慢
ROM存放程序代码、常量只读内容非易失
SFR控制单片机功能直接寻址每个SFR都有特定功能
I/O端口与外部设备交互直接寻址可读写外部设备数据

总结

  • 内部RAM 是程序运行时最常用的存储单元,用于存放变量和中间结果。
  • 外部RAM 用于扩展存储空间,存放大量数据。
  • ROM 存放程序代码和常量数据,是程序的灵魂。
  • SFR 控制单片机的各种功能,是硬件与软件的接口。
  • I/O端口 用于与外部设备进行数据交换。

选择合适的存储单元,是编写高效、可靠的MCS-51程序的关键。在编写程序时,需要根据数据的类型、访问频率和存储空间的需求,合理地分配各个存储单元。

例如:

  • 频繁访问的数据 应该放在内部RAM中,以提高访问速度。
  • 程序代码和常量数据 应该放在ROM中,以保证数据的安全性。
  • 大量的数据 可以放在外部RAM中。

2.MOVC指令的使用方式

MOVC A, @A+DPTR
  • A: 累加器A。
  • @A+DPTR: 表示对累加器A和数据指针DPTR的内容相加,得到一个程序存储器的地址,然后从该地址读取数据。

3.数码管由共阳极换成共阴极

        首先我们应知道共阳极和共阴极的区别:

共阳极数码管

  • 特点: 所有段的阳极(正极)连接在一起,作为公共端。要点亮某一段,则需要将该段的阴极接地(低电平)。
  • 驱动方式: 通常采用低电平有效的方式驱动。
  • 形象比喻: 可以想象成一个水池,水池底部有许多孔。要让某个孔喷水,就要打开对应的阀门,让水流出。

共阴极数码管

  • 特点: 所有段的阴极(负极)连接在一起,作为公共端。要点亮某一段,则需要将该段的阳极接高电平。
  • 驱动方式: 通常采用高电平有效的方式驱动。
  • 形象比喻: 可以想象成一个灯泡,灯泡的底座是公共端。要让某个灯泡亮,就要给对应的灯丝通电。

所以,只要修改code table,把原来的全取反就可以了:

CODE_TABLE: DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 00H, 6FH

4.控制显示数码管的亮度 

直接调整数码管属性

  • 找到数码管元件: 在Proteus元件库中找到你使用的七段数码管模型。
  • 打开属性窗口: 右键单击数码管元件,选择“Properties”或“属性”选项。
  • 查找亮度设置: 在属性窗口中,可能会找到一个名为“Brightness”或“亮度”的选项。直接调整该选项的值即可改变数码管的亮度。

        这个答案可能有点草率,不过目前我不知道如何用“高端”的方法来实现。

5.点个赞呗:

        好啦,这就是单片机实验1的内容啦,都是一个学校的,看完给个点赞收藏关注三连呗:)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值