写在前面的话:

  • 这是计算机原理实验的大作业。
  • 详细报告在资源“(汇编语言程序设计)带开机音乐,速度、进度和行驶方向显示的出租出计费系统设计”中,可自己下载。
  • 资源中的源代码,我把音乐模块打包成子函数了,但没有经过测试。本博客中的代码是验证无误的,但音乐模块并没有从主函数独立出来。
  • 本博客只提供思路,以及样例代码。运行环境在下面写的很清楚了,如果运行报错请自行调试,问为什么报错的一概不回复
  • 重申:尽管代码已经验证无误,但代码只提供思路,拿来不能用的情况很常见,自己改改就好了。代码的注释和资源的报告讲的很明白了。

题目

带开机音乐,速度、进度和行驶方向显示的出租出计费系统设计

运行环境

  • 软件环境:HQFC集成开发环境
  • 硬件环境:386EX计算机原理实验箱
  • 设计语言:汇编语言

功能概述

模拟出租车系统的功能,除了基本起价、里程计算、费用显示等功能外,增加了开机音乐(可选)、里程及费用锁存、速度可调、直流电机转速可调、行驶方向显示、8*8 LED点阵闪烁频率可调、1km内里程显示等功能。

具体要求如下:

  1. 8253/8254对250kHz信号分频。
  • TC0工作于方式3方波发生器模式,用于将250kHz信号分频到较低频率。

  • TC1工作于方式2分频器模式,输出占空比可调的PWM信号。一方面用作中断触发输入,调用中断服务程序的执行;另一方面,经过非门作为直流电机的输入信号,通过占空比的调整改变直流电机的转速。

  • TC2工作于方式3方波发生器模式,用于改变计数初值N产生特定频率的信号,实现音乐播放的功能。

  1. 电位器控制出租车速度。

    通过ADC0809读取速度,对出租车里程、费用进行控制。

  2. 六位共阴极LED数码管显示里程和费用。

    六位数码管的高2位显示里程数(XX千米),低3位显示费用(显示XX.X元),两者之间的数码管显示“-”作为分隔。

  3. 出租车的速度大小同时由直流电机的转速和8*8 LED点阵的闪烁频率表示。

  4. 系统初始状态的设定。

    里程数00(km),低3位显示起步价(设置为10元)。2km内价格不变,超过2km,按每公里1.2元计价。

  5. 通过5个开关实现系统控制:

  • K0开关用于在乘客下车时锁存里程和费用显示。高电平时正常计数,低电平时锁存里程和费用信息。该开关连接TC1的GATE1。
  • K3开关用于在乘客下车后将里程和费用重置为初始值。高电平重置,低电平正常计数。该开关连接8255的PC4。
  • K4开关控制出租车行驶方向。高电平为向前行驶,低电平为向后行驶(即倒车)。该开关连接8255的PC5。
  • K5开关控制音乐播放。当K6为高电平时(留有开机时间),K5为高电平则播放音乐,K5为低电平则静默。该开关连接8255的PC6。
  • K6开关控制开机时间。当K6为高电平时留有开机时间,为低电平时直接开机。该开关连接TC2的GATE2。
  1. 通过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

[汇编语言计算机原理] 带开机音乐,速度、进度和行驶方向显示的出租出计费系统设计相关推荐

  1. 计算机怎样设置开机音乐,电脑开机声音听腻了怎么办?一招教你搞定

    Hello,大家好,我是余生.如果今天带来的内容足够精彩,希望各位动手来给小编评论点赞喔!您的每一次评论点赞都会带来好运气喔! 如何修改电脑开机声音?一招教你搞定 对于经常使用电脑的朋友,每次电脑开机 ...

  2. 计算机自带的音乐剪辑怎么打开,音乐剪切器怎么使用,音乐剪切器使用教程

    音乐剪切器怎么使用的详细教程 一.首先打开计算机上的音乐剪切器",然后添加要转换的音频文件.我们在软件中找到我们的添加文件的按钮, 二.打开导航窗口,找到要转换的歌曲,然后单击打开. 三.然 ...

  3. Android TextView 带背景的文字垂直方向显示(ems属性)

    工具:Android Studio 在项目中有个这个需求:要求文字带背景,且文字是垂直方向显示的,竖着排,如图1. 图1  但是当我满怀欣喜地写入了这段代码之后: <TextView andro ...

  4. C# Winform 计算机原理模型机的设计——带超前进位加法器

    前言 此刻距离我上一篇博客已有一年多,这一年来学业繁忙,少有顾及,但这个博客我会一直写下去的.尽管现在的我还是菜鸡 今天要写的是关于我大二时候学习计算机原理的时候,用C#和C# Winform做的一个 ...

  5. 课程设计用计算机演奏音乐,微机原理课程设计--音乐演奏.doc

    微机原理课程设计--音乐演奏 学 院: 计算机科学技术 专 业: 计算机科学与技术(工) 班 级: 计10-1班 姓 名: 学 号: 指导教师: 2013年3月10日 微机原理与汇编语言课程设计任务书 ...

  6. 用计算机怎么开启音乐模式,XP开机音乐怎么设置?如何设置电脑开机音乐?

    XP开机音乐怎么设置?XP系统自带的开机音乐听了一辈子,自然是腻歪了,为了调节一下气氛,修改一下XP开机音乐就当是个性伸展,不过设置之前需要用户下载一个自己喜欢的音乐并转化为wav格式文件,具体过程请 ...

  7. 怎么打开计算机的音乐模式,xp开机音乐怎么设置 如何设置开机音乐

    每天当你开机的时候,电脑总会发出windos系统自带的开机音乐,听久了也没趣,不如换个自己喜欢的开机音乐.xp开机音乐怎么设置呢?其实不难,看看电脑开机音乐设置.>>如何下载狸窝VIP资源 ...

  8. 怎样用计算机调出歌曲,怎样设置电脑开机音乐

    每天当你开机的时候,电脑总会发出windos系统自带的开机音乐,听久了也没趣,不如换个自己喜欢的开机音乐.xp开机音乐怎么设置呢?其实不难,看看电脑开机音乐设置.>>如何下载狸窝VIP资源 ...

  9. 计算机原理与编程设计,计算机原理与汇编语言程序设计(高职)

    计算机原理与汇编语言程序设计(高职) 语音 编辑 锁定 讨论 上传视频 为了适应高职高专的课程改革,本书将原来计算机专业的两大主要课程"计算机组成原理"和"汇编语言程序设 ...

最新文章

  1. mupdf不支持x64_ARM版Win10用户狂喜 微软全新补丁让应用不再不兼容
  2. 前端知识点之CSS(一)
  3. R包stringr处理字符串
  4. 学院选人的时候会考虑博士和硕士的比例
  5. 领域驱动设计战术模式--值对象
  6. linux如何删除符号链接文件夹,在Linux中怎样移除(删除)符号链接
  7. LeetCode 800. 相似 RGB 颜色
  8. JZOJ5918【NOIP2018模拟10.20】Car
  9. 上海消保委评饿了么“多等5分钟”功能:逻辑上有问题
  10. Qt学习笔记常用容器
  11. Apache Log4j任意代码执行漏洞安全风险通告第三次更新
  12. Servlet工作原理解析
  13. springboot-高校医院体检系统
  14. FCC算法和数据结构 项目实战:罗马数字转换器
  15. 北京市211学校计算机专业,北京较容易考的2所211大学,王牌专业实力强悍,学生不愁就业...
  16. 分机计算机怎么设置共享打印机,win7打印机共享设置分机怎么设置
  17. Python常见笔/面试题
  18. Linux环境go项目启动提示/usr/bin/ld: cannot find -lxxx
  19. 做了两年P7面试官,谈谈我认为的阿里人才画像,你配吗?
  20. 求求你,商用项目不要再使用jsdelivr的CDN服务了

热门文章

  1. python与java前景-java和Python的前景谁更好
  2. 如何系统的自学python-如何系统学习python
  3. 有哪些能识别英文的语音助手?
  4. 前端emojs_Emoji-Chat emoji表情包发送及显示兼容web端、移动端
  5. Node介绍及环境配置~超级详细哦
  6. java语法格式整理
  7. 【动态规划】完全背包:整数划分(方案数)
  8. 【动态规划】区间dp:P1005矩阵取数
  9. 最简单的基于FFmpeg的libswscale的示例附件:测试图片生成工具
  10. OpenCV 使用光流法检测物体运动