[汇编语言计算机原理] 带开机音乐,速度、进度和行驶方向显示的出租出计费系统设计
写在前面的话:
- 这是计算机原理实验的大作业。
- 详细报告在资源“(汇编语言程序设计)带开机音乐,速度、进度和行驶方向显示的出租出计费系统设计”中,可自己下载。
- 资源中的源代码,我把音乐模块打包成子函数了,但没有经过测试。本博客中的代码是验证无误的,但音乐模块并没有从主函数独立出来。
- 本博客只提供思路,以及样例代码。运行环境在下面写的很清楚了,如果运行报错请自行调试,问为什么报错的一概不回复。
- 重申:尽管代码已经验证无误,但代码只提供思路,拿来不能用的情况很常见,自己改改就好了。代码的注释和资源的报告讲的很明白了。
题目
带开机音乐,速度、进度和行驶方向显示的出租出计费系统设计
运行环境
- 软件环境:HQFC集成开发环境
- 硬件环境:386EX计算机原理实验箱
- 设计语言:汇编语言
功能概述
模拟出租车系统的功能,除了基本起价、里程计算、费用显示等功能外,增加了开机音乐(可选)、里程及费用锁存、速度可调、直流电机转速可调、行驶方向显示、8*8 LED点阵闪烁频率可调、1km内里程显示等功能。
具体要求如下:
- 8253/8254对250kHz信号分频。
TC0工作于方式3方波发生器模式,用于将250kHz信号分频到较低频率。
TC1工作于方式2分频器模式,输出占空比可调的PWM信号。一方面用作中断触发输入,调用中断服务程序的执行;另一方面,经过非门作为直流电机的输入信号,通过占空比的调整改变直流电机的转速。
TC2工作于方式3方波发生器模式,用于改变计数初值N产生特定频率的信号,实现音乐播放的功能。
电位器控制出租车速度。
通过ADC0809读取速度,对出租车里程、费用进行控制。
六位共阴极LED数码管显示里程和费用。
六位数码管的高2位显示里程数(XX千米),低3位显示费用(显示XX.X元),两者之间的数码管显示“-”作为分隔。
出租车的速度大小同时由直流电机的转速和8*8 LED点阵的闪烁频率表示。
系统初始状态的设定。
里程数00(km),低3位显示起步价(设置为10元)。2km内价格不变,超过2km,按每公里1.2元计价。
通过5个开关实现系统控制:
- K0开关用于在乘客下车时锁存里程和费用显示。高电平时正常计数,低电平时锁存里程和费用信息。该开关连接TC1的GATE1。
- K3开关用于在乘客下车后将里程和费用重置为初始值。高电平重置,低电平正常计数。该开关连接8255的PC4。
- K4开关控制出租车行驶方向。高电平为向前行驶,低电平为向后行驶(即倒车)。该开关连接8255的PC5。
- K5开关控制音乐播放。当K6为高电平时(留有开机时间),K5为高电平则播放音乐,K5为低电平则静默。该开关连接8255的PC6。
- K6开关控制开机时间。当K6为高电平时留有开机时间,为低电平时直接开机。该开关连接TC2的GATE2。
通过3个LED灯精确显示1km内的里程。
1km内的进度由3个LED灯显示。全灭、一个灯亮、两个灯亮、三个灯亮分别表明出租出位于1km内的[0m, 250m]、[250m, 500m]、[500m, 750m]、[750m, 1000m]区间。
源代码及注释
;----------------------------------------------------------
; 出租车系统设计
;----------------------------------------------------------
.model small
.386
data segment
;---------------------设置各端口地址-------------------;8254基址值 --> 计时器i8254_0 equ 200H ;8255端口地址 --> 中间接口i8255_a equ 210h ;8255A口,初始化PA为输出i8255_b equ 211h ;8255B口,初始化PB为输入i8255_c equ 212h ;8255C口i8255_k equ 213h ;8255控制口AD_IO equ 220hled_io equ 240h ;LED灯地址;---------------------设置led编码------------------ledcode_1 db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,67h ;不带. --> 指小数点ledcode_2 db 0bfh,86h,0dbh,0cfh,0e6h,0edh,0fdh,87h,0ffh,0e7h ;带. --> 指小数点 ledcode_3 db 40h ;字符"-"
;--------------------设置变量信息------------------count_km db 00h ;转换的路程(km)price dw 100 ;起步价定为100角(10元)N db 0clear_flag db 0 ;为1则表示清零temp db 0 ;暂存clear_flag的状态km_flag db 0 ;为7则表示已达到1km,此时更新km和price,并将km_flag清零;8*8点阵updown_flag db 0led3 db 08h,0ch,0eh,7fh,7fh,0eh,0ch,08hled4 db 08h,18h,38h,7fh,7fh,38h,18h,08hcount dw 00hbz dw ? ShowProgress_flag db 0progress_0 db 00000010b;音乐模块sound_flag db 0mus_freq dw 262,262,262,196dw 330,330,330,262dw 262,330,392,392dw 349,330,294dw 294,330,349,349dw 330,294,330,262dw 262,330,294,196dw 247,294,262,-1mus_time dw 3 dup(12,12,25,25),12,12,50dw 3 dup(12,12,25,25),12,12,50data endsssg segment stackdw 100 dup(0)
ssg endscode segmentassume cs:code,ds:data,ss:ssgmain proc farmov ax, datamov ds, ax;--------------------各端口初始化----------------cli ;关中断进行初始化call clock ;时钟设置;--------------------初始化8255--------------------mov dx,i8255_kmov al,88h ;8255控制字 out dx,al ;8255为模式0,PA、PB为输出,PC高位为输入,低位为输出;--------------设置386EX主8259中断屏蔽字-------------in al,21hand al,11010111b ;开放IR3、IR5中断,IR3是里程清零,IR5是正常计数740的产生的中断out 21h,al;---------------------设置中断向量表----------------------;设置IR5push dsmov ax, 0mov ds, ax ;ds指向00000H,为中断向量表的地址范围的起始地址;中断向量表的IP值lea ax, cs:int_proc1 ;ax为中断程序入口地址的偏移地址IPmov si, 35h ;类型码35hadd si, si ;类型码*4得到中断向量add si, si ;找到中断向量表中终端类型码35h对应的位置的起始地址mov ds:[si], ax ;将中断服务程序的IP放到中断类型码的对应位置;中断向量表的CS值push cspop ax ;ax <-- 中断服务程序的段地址csmov ds:[si+2], ax ;将中断服务程序的cs放到中断类型码的对应位置pop ds;---------------------音乐模块---------------------;使得直流电机模拟齿轮转动mov al, 255mov dx, i8254_0add dx, 1out dx, alcall read_statecmp sound_flag, 01000000bjne next_test_music;输出音乐;获得频率和时间的首地址lea si, mus_freq lea di, mus_timeplay:mov dx, [si]cmp dx, -1 ;频率为-1时结束播放je end_play call sound ;sound函数用于演奏一个字符add si, 2 ;指向下一个数据add di, 2 call read_state ;允许在歌曲中间打断歌曲,下次歌曲依旧从头播放cmp sound_flag, 01000000bjne sound_exitjmp playend_play:mov ax, 2 mov dx, i8254_0add dx, 2out dx, al ;先送低8位到计数器,dx是8253芯片通道2的端口地址mov al, ahout dx, al ;后送高8位计数器next_test_music: sti ;开中断;---------------------等待中断----------------------LLL: call machine ;重复刷新直流电机call read_state ;读取状态;判断清零标志,clear_flag不为0则初始化count_km和pricecmp clear_flag, 00010000bjne next2call clearnext2: cli ;关中断执行dispcall disp ;重复刷新LED显示sti ;执行disp结束,开中断jmp LLL main endp;---------------------中断时钟设置-----------------
;子函数功能:将1MHz信号进行10000分频,得到100Hz的方波
;芯片:8254,计数器0,方式3(方波方式),读写先低后高,二进制计数
;输出:out0口得到100Hz的信号,用于统计路程clock proc;计数器 0 的 CW 和 N mov dx, i8254_0add dx, 3 ;指向控制口mov al, 00110110b ;计数器0,方式3(方波方式),读写先低后高,二进制计数out dx, almov dx, i8254_0 ;指向计数器0mov ax, 1875 ;赋初值Nout dx, almov al, ah out dx, al ;计数器 1 的 CW 和 N mov dx, i8254_0 ;向8254写控制字add dx, 3mov al, 01010100b ;计数器1,方式2(分频器),只写低 out dx, al mov dx, i8254_0 add dx, 1 ;指向计数器1mov al, 2 ;在N属于[0,12]下,使N初始化为2 out dx, al;计数器 2 的 CWmov al, 10110110b ;8254初始化TC2,读写16位,方式3方波模式mov dx,i8254_0 add dx, 3out dx,al retclock endp;-----------------AD转换并计算速度函数--------------- AD_transfer procmov dx, AD_IO ;ADC启动转换地址out dx, al ;启动ADCmov dx, AD_IO ;获取ADC EOC状态地址add dx, 2L1:in al, dxtest al, 01h ;测试EOC是否为1jz L1mov dx, AD_IO ;读数据地址inc dxin al, dxmov ah, 0mov cl, 21div cl ;获得2-12档,2档最快,12档停止mov N, alretAD_transfer endp;---------------------进度显示子函数-------------------progress procpush axmov al, progress_0 ;读取progress_0到aldec al ;得到要显示的进度mov dx,i8255_cout dx, al ;将al输出到下C口rol progress_0, 1 ;progress_0循环左移,为下一次做准备cmp progress_0, 00010000b ;1从第四位左移到高四位,则将progress_0还原为初始值jb next_progressmov progress_0, 00000001b next_progress:pop axretprogress endp;----------------中断服务子程序IS5---------------int_proc1 proc farpush axpush dxcall AD_transfer ;读取电位器对应的Ncall disp88 ;调用点阵显示函数add km_flag, 1cmp km_flag, 4jne no_update ;km_flag为8时,表示已经运行1KM,需更新count_km和price;更新km和pricecall calculate_kmcall calculate_pricemov km_flag, 0 ;更新完毕,对km_flag清0no_update: ;-------------------------显示进度版本修改代码-------------------------call progress ;更新km进度;-------------------------显示进度版本修改代码------------------------- continue_int_proc1:;对计数器1重新赋初值mov dx, i8254_0 add dx, 1 ;指向计数器1cmp N, 2jae next_int_proc1mov N, 2 ;设置最快速度,高低电平至少各0.5秒next_int_proc1:mov al, N ;赋值新的N值out dx, al;发送中断结束命令 EOImov al,20h out 20h,al ;(向386EX主8259)pop dxpop axsti ;开中断iretint_proc1 endp;sound函数:演奏一个音符
;入口参数:si - 要演奏的音符的频率的地址
; di - 要演奏的音符的音长的地址sound procpush axpush dxpush cx;{dx, ax}作为被除数,我认为{dx, ax}是TC2的输入频率;应该是基于一个公式:输入频率250kHz = 分频数ax(TC2的N)* 声音频率(分频后的频率);call read_state ;允许在歌曲中间打断歌曲,下次歌曲依旧从头播放;cmp sound_flag, 01000000b;jne sound_exit mov dx,0003h ;TC2输入频率为250kHzmov ax,0d090h;[si]作为除数div word ptr [si] ;计算分频值,赋给ax。[si]中存放声音的频率值。;将ax作为TC2的N,输出到TC2端口mov dx, i8254_0add dx, 2out dx, al ;先送低8位到计数器,dx是8253芯片通道2的端口地址mov al, ahout dx, al ;后送高8位计数器mov dx, [di] ;保持[di]时长wait11:mov cx, 14000delay_sound:noploop delay_sounddec dx jnz wait11pop cxpop dxpop axsound_exit:retsound endp;-------------------显示函数------------------disp procpush bxpush dx;km显示;清除鬼影mov al, 0 mov dx, led_ioout dx, almov al, 000000binc dxout dx, alcall delay lea bx, ledcode_1mov al, count_kmmov ah, 0mov cl, 10 ;截取十位div clmov ah, 0 div clmov al, ahmov ah, 0 add bx, axmov al, [bx] ;取得要显示的数据mov dx, led_io ;获取显示的地址out dx, al ;输出数据mov al, 100000b ;指明要点亮的位为第一位inc dx ;地址加1out dx, alcall delay ;清除鬼影mov al, 0 mov dx, led_ioout dx, almov al, 000000binc dxout dx, alcall delay lea bx, ledcode_1mov al, count_kmmov ah, 0mov cl, 10 ;截取个位div clmov al, ahmov ah, 0add bx, axmov al, [bx]mov dx, led_ioout dx, almov al, 010000binc dxout dx, alcall delay;清除鬼影mov al, 0 mov dx, led_ioout dx, almov al, 000000binc dxout dx, alcall delay ;显示"-"字符 mov al, ledcode_3 mov dx, led_ioout dx, almov al, 001000binc dxout dx, alcall delay;清除鬼影mov al, 0 mov dx, led_ioout dx, almov al, 000000binc dxout dx, alcall delay ;显示价格 lea bx, ledcode_1mov ax, pricemov cl, 10 ;截取百位div clmov ah, 0div clmov ah, 0div clmov al, ahmov ah, 0 add bx, axmov al, [bx]mov dx, led_ioout dx, almov al, 000100binc dxout dx, alcall delay;清除鬼影mov al, 0 mov dx, led_ioout dx, almov al, 000000binc dxout dx, alcall delay lea bx, ledcode_2 ;带小数点mov ax, pricemov cl, 10 ;截取十位div clmov ah, 0 div clmov al, ahmov ah, 0 add bx, axmov al, [bx]mov dx, led_ioout dx, almov al, 000010binc dxout dx, alcall delay ;清除鬼影mov al, 0 mov dx, led_ioout dx, almov al, 000000binc dxout dx, alcall delay lea bx, ledcode_1mov ax, pricemov cl, 10 ;截取个位div clmov al, ahmov ah, 0add bx, axmov al, [bx]mov dx, led_ioout dx, almov al, 000001binc dxout dx, alcall delay;清除鬼影mov al, 0 mov dx, led_ioout dx, almov al, 000000binc dxout dx, alcall delay pop dxpop bxretdisp endp;-----------------里程计算函数------------------
;子函数功能:该程序在IR5被响应时调用,表示740个clk计数完毕,对应公里数加1calculate_km procpush axmov al, 1add count_km, alcmp count_km, 99jb no_clearmov count_km, 0mov price, 100no_clear:pop axretcalculate_km endp;-----------------价格计算函数------------------calculate_price procmov al, count_kmcmp al, 2 ;2km为起始距离ja biggermov price, 100 ;起始价为10jmp exit1bigger:sub al, 2mov dl, 12mul dladd ax, 100mov price, ax ;存储结果,用于显示exit1:retcalculate_price endp;----------------状态读取并显示函数---------------read_state proc;---------------------测试代码2:在测试代码一上,查看是否能正常读入数据----------------------mov dx, i8255_cin al, dxmov clear_flag, al ;读取clear_flag状态,为D4位and clear_flag, 00010000bmov dx, i8255_cin al, dxmov updown_flag, al ;读取updown_flag状态,为D5位and updown_flag, 00100000bmov dx, i8255_cin al, dxmov sound_flag, al ;读取sound_flag状态,为D4位and sound_flag, 01000000b;---------------------测试代码2:在测试代码一上,查看是否能正常读入数据-------------------retread_state endp;-----------------里程清零函数------------------
;子函数功能:当clear_flag为1时被调用,清零count_kmclear procmov count_km, 0mov price, 100retclear endp;-------------------直流电机函数------------------
;原理,通过方式2的分频,导致占空比不同,N越大,占空比越小(需经过非门)
;test1修改版本,经dosbox测试正确,开发板待检验machine procmov al, Nmov ah, 0mov dx, i8254_0 add dx, 1 ;指向TC1 out dx, al ;N为2~12,2最快,12停止retmachine endp;---------------8*8点阵显示---------------
disp88 proc push cxmov di, offset led3 ;设di为字形码缓冲区指针(指向首地址), LED3为上升箭头call read_state cmp updown_flag, 00100000bje next_disp88 mov di, offset led4 ;设di为字形码缓冲区指针(指向首地址), LED3为下降箭头
next_disp88:mov cx, 0005h ;点阵扫描次数call disp0 ;调用扫描子程序pop cxret
disp88 endp;--------------点阵子函数--------------
disp0 proc push bxpush axpush dx
loop5:mov count, 0000h ;计数器初始=0mov bh, 01h ;产生最高位扫描码mov al, 0 ;扫描码消失(熄灭);mov dx, 202h ;关闭扫描信号 -->8255地址,待改mov dx, i8255_b ;关闭扫描信号 -->PA为扫描信号out dx, al ;LED灯熄灭
lll0:mov byte ptr bz,bhpush diadd di,countmov bl,byte ptr[di]pop dimov al,bl;mov dx,201h ;8255b控制行mov dx,i8255_a ;8255b控制行out dx,almov al,byte ptr bzmov dx,i8255_b ;8255c控制列 显示bz列out dx,alinc countpush cxmov cx,20h ;延迟一段时间
delay0:loop delay0pop cxmov al,0;mov dx,202h ;关闭扫描信号mov dx, i8255_b ;关闭扫描信号out dx,almov bh,byte ptr bzshl bh,1 ;bh指向下一位jnz lll0 ;8列都扫描完结束loop loop5pop dxpop axpop bxret
disp0 endp;------------------延时函数------------------delay procpush cxmov cx, 30X1:loop X1pop cxretdelay endpcode endsend main
[汇编语言计算机原理] 带开机音乐,速度、进度和行驶方向显示的出租出计费系统设计相关推荐
- 计算机怎样设置开机音乐,电脑开机声音听腻了怎么办?一招教你搞定
Hello,大家好,我是余生.如果今天带来的内容足够精彩,希望各位动手来给小编评论点赞喔!您的每一次评论点赞都会带来好运气喔! 如何修改电脑开机声音?一招教你搞定 对于经常使用电脑的朋友,每次电脑开机 ...
- 计算机自带的音乐剪辑怎么打开,音乐剪切器怎么使用,音乐剪切器使用教程
音乐剪切器怎么使用的详细教程 一.首先打开计算机上的音乐剪切器",然后添加要转换的音频文件.我们在软件中找到我们的添加文件的按钮, 二.打开导航窗口,找到要转换的歌曲,然后单击打开. 三.然 ...
- Android TextView 带背景的文字垂直方向显示(ems属性)
工具:Android Studio 在项目中有个这个需求:要求文字带背景,且文字是垂直方向显示的,竖着排,如图1. 图1 但是当我满怀欣喜地写入了这段代码之后: <TextView andro ...
- C# Winform 计算机原理模型机的设计——带超前进位加法器
前言 此刻距离我上一篇博客已有一年多,这一年来学业繁忙,少有顾及,但这个博客我会一直写下去的.尽管现在的我还是菜鸡 今天要写的是关于我大二时候学习计算机原理的时候,用C#和C# Winform做的一个 ...
- 课程设计用计算机演奏音乐,微机原理课程设计--音乐演奏.doc
微机原理课程设计--音乐演奏 学 院: 计算机科学技术 专 业: 计算机科学与技术(工) 班 级: 计10-1班 姓 名: 学 号: 指导教师: 2013年3月10日 微机原理与汇编语言课程设计任务书 ...
- 用计算机怎么开启音乐模式,XP开机音乐怎么设置?如何设置电脑开机音乐?
XP开机音乐怎么设置?XP系统自带的开机音乐听了一辈子,自然是腻歪了,为了调节一下气氛,修改一下XP开机音乐就当是个性伸展,不过设置之前需要用户下载一个自己喜欢的音乐并转化为wav格式文件,具体过程请 ...
- 怎么打开计算机的音乐模式,xp开机音乐怎么设置 如何设置开机音乐
每天当你开机的时候,电脑总会发出windos系统自带的开机音乐,听久了也没趣,不如换个自己喜欢的开机音乐.xp开机音乐怎么设置呢?其实不难,看看电脑开机音乐设置.>>如何下载狸窝VIP资源 ...
- 怎样用计算机调出歌曲,怎样设置电脑开机音乐
每天当你开机的时候,电脑总会发出windos系统自带的开机音乐,听久了也没趣,不如换个自己喜欢的开机音乐.xp开机音乐怎么设置呢?其实不难,看看电脑开机音乐设置.>>如何下载狸窝VIP资源 ...
- 计算机原理与编程设计,计算机原理与汇编语言程序设计(高职)
计算机原理与汇编语言程序设计(高职) 语音 编辑 锁定 讨论 上传视频 为了适应高职高专的课程改革,本书将原来计算机专业的两大主要课程"计算机组成原理"和"汇编语言程序设 ...
最新文章
- mupdf不支持x64_ARM版Win10用户狂喜 微软全新补丁让应用不再不兼容
- 前端知识点之CSS(一)
- R包stringr处理字符串
- 学院选人的时候会考虑博士和硕士的比例
- 领域驱动设计战术模式--值对象
- linux如何删除符号链接文件夹,在Linux中怎样移除(删除)符号链接
- LeetCode 800. 相似 RGB 颜色
- JZOJ5918【NOIP2018模拟10.20】Car
- 上海消保委评饿了么“多等5分钟”功能:逻辑上有问题
- Qt学习笔记常用容器
- Apache Log4j任意代码执行漏洞安全风险通告第三次更新
- Servlet工作原理解析
- springboot-高校医院体检系统
- FCC算法和数据结构 项目实战:罗马数字转换器
- 北京市211学校计算机专业,北京较容易考的2所211大学,王牌专业实力强悍,学生不愁就业...
- 分机计算机怎么设置共享打印机,win7打印机共享设置分机怎么设置
- Python常见笔/面试题
- Linux环境go项目启动提示/usr/bin/ld: cannot find -lxxx
- 做了两年P7面试官,谈谈我认为的阿里人才画像,你配吗?
- 求求你,商用项目不要再使用jsdelivr的CDN服务了