matlab adc0809,计算机原理小学期实验报告

计算机原理小学期实验报告

DA及AD转换实验报告自03 张驰昱 20100120281、D/A转换用DAC0832实现D/A转换,使产生的模拟电压波形分别为锯齿波,三角波和正弦波要求: 程序运行后等待键入(1)若键入1,则产生锯齿波(2)若键入2,则产生三角波(3)若键入3,则产生正弦波(4)若键入4,则返回DOS程序运行过程中没有新键入别的数字,则维持原状不变,用示波器能观测到连续的电压波形。解决思路:先写三个用于波形发生的过程,分别发出锯齿波、三角波和正弦波。再写一个每次从DAC0832输出数据前都会调用的产生延迟的过程,在这个过程中进行有无按键的判断和分辨按键的判断。主程序先调用这个延迟的过程,这样程序一旦运行起来就相当于不断的在检测按键了。正弦波的值我是通过matlab生成和写入文件,并保存在数据段里的。以下是生成一个周期256个采样sin值的matlab代码:clear;clc;fid=fopen(sine.txt,w);s=round(sin(2*pi/256*1:256)*127.5+127.5);s=reshape(s,16,16);for i=1:16fprintf(fid,DB );fprintf(fid,%03XH,s(:,i);fprintf(fid,n);end源代码:DATAS SEGMENT DNUM DB 01HCSADD DW 0280HHINT1 DB TEETH WAVE,0DH,0AH,$HINT2 DB TRIANGLE WAVE,0DH,0AH,$HINT3 DB SINE WAVE,0DH,0AH,$SINE DB 083H,086H,089H,08CH,08FH,092H,095H,098H,09BH,09EH,0A2H,0A5H,0A7H,0AAH,0ADH,0B0HDB 0B3H,0B6H,0B9H,0BCH,0BEH,0C1H,0C4H,0C6H,0C9H,0CBH,0CEH,0D0H,0D3H,0D5H,0D7H,0DAHDB 0DCH,0DEH,0E0H,0E2H,0E4H,0E6H,0E8H,0EAH,0EBH,0EDH,0EEH,0F0H,0F1H,0F3H,0F4H,0F5HDB 0F6H,0F8H,0F9H,0FAH,0FAH,0FBH,0FCH,0FDH,0FDH,0FEH,0FEH,0FEH,0FFH,0FFH,0FFH,0FFHDB 0FFH,0FFH,0FFH,0FEH,0FEH,0FEH,0FDH,0FDH,0FCH,0FBH,0FAH,0FAH,0F9H,0F8H,0F6H,0F5HDB 0F4H,0F3H,0F1H,0F0H,0EEH,0EDH,0EBH,0EAH,0E8H,0E6H,0E4H,0E2H,0E0H,0DEH,0DCH,0DAHDB 0D7H,0D5H,0D3H,0D0H,0CEH,0CBH,0C9H,0C6H,0C4H,0C1H,0BEH,0BCH,0B9H,0B6H,0B3H,0B0HDB 0ADH,0AAH,0A7H,0A5H,0A2H,09EH,09BH,098H,095H,092H,08FH,08CH,089H,086H,083H,080HDB 07CH,079H,076H,073H,070H,06DH,06AH,067H,064H,061H,05DH,05AH,058H,055H,052H,04FHDB 04CH,049H,046H,043H,041H,03EH,03BH,039H,036H,034H,031H,02FH,02CH,02AH,028H,025HDB 023H,021H,01FH,01DH,01BH,019H,017H,015H,014H,012H,011H,00FH,00EH,00CH,00BH,00AHDB 009H,007H,006H,005H,005H,004H,003H,002H,002H,001H,001H,001H,000H,000H,000H,000HDB 000H,000H,000H,001H,001H,001H,002H,002H,003H,004H,005H,005H,006H,007H,009H,00AHDB 00BH,00CH,00EH,00FH,011H,012H,014H,015H,017H,019H,01BH,01DH,01FH,021H,023H,025HDB 028H,02AH,02CH,02FH,031H,034H,036H,039H,03BH,03EH,041H,043H,046H,049H,04CH,04FHDB 052H,055H,058H,05AH,05DH,061H,064H,067H,06AH,06DH,070H,073H,076H,079H,07CH,07FHDATAS ENDSSTACKS SEGMENT STACK DW 100 DUP(?)STACKS ENDSCODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKSDELAY PROC ;延时子程序PUSH DXPUSH AXMOV AH,0BH ;检测键盘有无按键,不等待INT 21HCMP AL,0FFH ;如果没有按键,继续JNZ CONTINUEMOV AH,01H ;如果有按键,读取键盘缓冲区的值并回显INT 21HCMP AL,1JNZ DUECALL TEETH ;如果是1,调用锯齿波DUE: CMP AL,2JNZ TRECALL TRI;如果是2,调用三角波TRE: CMP AL,3JNZ QUACALL SIN;如果是3,调用正弦波QUA: CMP DL,4;如果是4,退出JZ EXITEXIT: MOV AX,4C00H INT 21HCONTINUE: MOV DL,DNUM ;如果无按键,那么哪里调用的就返回到哪里去L: DEC DLJNZ LPOP AXPOP DXRETDELAY ENDPTRI PROC ;三角波子程序PUSH AXPUSH DXLEA DX,HINT1MOV AH,09HINT 21HMOV AH,0FFHDOWN: CALL DELAY ;三角波下降过程MOV AL,AHMOV DX,0280HOUT DX,ALCMP AH,1JE UPSUB AH,2JMP DOWNUP: CALL DELAY;三角波上升过程MOV AL,AHMOV DX,0280HOUT DX,ALCMP AH,0FFHJE DOWNADD AH,2JMP UPPOP DXPOP AXRETTRI ENDPTEETH PROC ;锯齿波子程序PUSH AXPUSH DXLEA DX,HINT2MOV AH,09HINT 21HPEAK: MOV AH,0FFH ;我写的是一个下降的锯齿波Z : CALL DELAYMOV AL,AHMOV DX,0280HOUT DX,ALCMP AH,0JE PEAKDEC AHJMP ZPOP DXPOP AXRETTEETH ENDPSIN PROC ;正弦波子程序PUSH DIPUSH SIPUSH AXPUSH DXLEA DX,HINT3MOV AH,09HINT 21H LEA DI,SINEADD DI,0FFH ;相当于用一个指针取顺序的扫描数据段里的数据HEAD: LEA SI,SINE ;扫描到结尾了再返回到开头TAIL: CALL DELAYMOV AL,SIMOV DX,0280HOUT DX,ALCMP SI,DIJE HEADINC SIJMP TAILPOP DXPOP AXPOP SIPOP DIRETSIN ENDPSTART: MOV AX,DATAS MOV DS,AXCALL DELAY;主程序一开始就不断调用DELAY检查有无按键JMP STARTCODES ENDSEND START2、A/D转换 用ADC0809实现A/D转换,用汇编语言程序自动对一个模拟信号重复采集20组不同的数据,在CRT上将每组数据对应显示成如下形式:D/A A/Dxx xx 然后等待键盘输入,若键入字母C则接着往下再做20组数据;若键入字母E则退回DOS。输入字母大小写应能兼容。源代码:DATAS SEGMENT DNUM DW 0FFFFHT DB 0DH,0AH,D/A A/D,0DH,0AH,$ ;标题D/A A/DBLANK DB ,$ ;三个空格,为了与上面标题对对齐ENT DB 0DH,0AH,$;回车加换行DATAS ENDSSTACKS SEGMENT STACK DW 20 DUP(?)STACKS ENDSCODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKSDELAY MACRO ;延时子程序LOCAL NPUSH DXMOV DX,DNUMN : DEC DXJNZ NPOP DXENDMPLAY MACRO SEG ;显示AL寄存器十六进制值的子程序,这个子程序我在实验三中写过LOCAL A2LOCAL A1PUSH CXPUSH DXPUSH AXMOV DL,SEGAND DL,0F0H ;取前四位MOV CL,4SHR DL,CL CMP DL,09HJBE A1ADD DL,07HA1:ADD DL,30H PUSH AXMOV AH,02H;输出前四位INT 21HPOP AXMOV DL,SEGAND DL,0FH ;取后四位CMP DL,09HJBE A2ADD DL,07HA2:ADD DL,30HMOV AH,02H ;输出后四位INT 21HPOP AXPOP DX POP CXENDMSTART: MOV AX,DATASMOV DS,AXMOV CH,0AGAIN:MOV CL,20LEA DX,TMOV AH,09HINT 21HNEXT: PLAY CH ;显示转换前的数字值MOV AL,CH ;数模转换MOV DX,280HOUT DX,ALLEA DX,BLANK;输出空格 MOV AH,09HINT 21HDELAYMOV AL,0 ;模数转换MOV DX,0289HOUT DX,ALDELAYJMP GO ;这里三行只是一个中途的跳板,因为程序过长,JMP超出限度JUMP:JMP NEXTAGA: JMP AGAINGO: MOV DX,0289H ;读入AD结果IN AL,DXPLAY AL ;输出AD结果LEA DX,ENT ;输出回车MOV AH,09HINT 21HADD CH,0FH ;每两个值相隔0FHDEC CL JNZ JUMPREAD: MOV AH,01H ;检查键盘INT 21HCMP AL,E ;E退出JE EXITCMP AL,eJE EXITCMP AL,C ;C继续读JNE READCMP AL,cJNE READJMP AGAEXIT: MOV AX,4C00H INT 21HCODES ENDSEND START计算机原理应用综合实验报告自03 张驰昱 20100120281、方式0 I/O将TPC实验台上的8255电路A口设置成方式0输入,检测8只开关的状态;将C口设置成方式0输出,控制8只LED灯。程序运行后不断地读入8只开关的状态,送往对应的LED灯显示,直至在计算机键盘上敲入空格键退回DOS。源代码:code segmentassume cs:codeSTART:MOV AL,10010000B ;写控制字MOV DX,0283HOUT DX,ALAGAIN:MOV DX,0280H ;从A口输入IN AL,DXMOV DX,0282H ;C口输出OUT DX,ALMOV AH,0BH ;检查键盘有无按键,不等待INT 21HCMP AL,0FFH ;如果有按键,去检查是不是空格JE EXITJMP AGAIN ;如果无按键,继续EXIT:MOV AH,01HINT 21HCMP AL, JNE AGAIN mov ax,4c00hint 21hcode endsend start2、选作内容A口仍保持方式0输入开关状态,C口仍以方式0输出LED灯显示,满足如下条件:(1)若仅K7=1,8只LED的状态循环左移(2)若仅K6=1,8只LED的状态循环右移(3)若仅K6=K7,8只LED一起闪烁。源代码:code segmentassume cs:codeDELAY MACRO ;延时子程序LOCAL NPUSH DXMOV DX,0FFFFHN : DEC DXJNZ NPOP DXENDMHOLD MACRO ;发现一次0FFFFH的计数不够长,四次够长了,五次的话JMP就超限了DELAYDELAYDELAYDELAYENDMLEFT MACRO ;向左亮灯子程序LOCAL LPUSH CXMOV CL,8MOV AL,00000001BL:HOLDMOV DX,0282HOUT DX,ALSHL AL,1 ;向左亮灯的本质就是寄存器的移位DEC CLJNE LPOP CXENDMRIGHT MACRO ;向左亮灯子程序,与向左几乎一样,指示寄存器向右移位LOCAL RPUSH CXMOV CL,8MOV AL,10000000BR:HOLDMOV DX,0282HOUT DX,ALSHR AL,1DEC CLJNE R POP CXENDMBLINK MACRO ;闪烁子程序,本质就是全亮停片刻,全灭停片刻MOV AL,0FFHMOV DX,0282HOUT DX,ALHOLDMOV AL,0MOV DX,0282HOUT DX,ALHOLDENDMSTART:MOV AL,10010000B ;主程序,写控制字MOV DX,0283H OUT DX,ALAGAIN:MOV DX,0280H ;读入A口状态IN AL,DXCMP AL,10000000B ;如果仅K7开,则调用向左亮灯子程序JNE A1LEFTJMP AGAIN ;向左一遍马上回去继续检测A口状态A1:CMP AL,01000000B ;如果仅K6开,则调用向右亮灯子程序JNE A2RIGHTJMP AGAINA2:CMP AL,11000000B ;如果仅K7、K6开,则调用向闪灯子程序JNE AGAIN BLINKJMP AGAINEXIT:mov ax,4c00hint 21hcode endsend start3、方式1 I/O实验中每按一次单脉冲按键,通过8255电路发一次中断请求。CRT上显示一个A口的ASCII码字符,直到A口数据为FFH退出。4、选作内容修改主程序实现密码检测功能,连续两次从A口拨入数据,与计算机内部事先存放的两字节数比较,相符则在CRT上显示“OK”,否则重新输入。以下代码已把3、4两个程序合并在一起。源代码:DATAS SEGMENTPASSWORD DB 38H,38H ;密码写在数据段中,定位88HINT DB 0DH,0AH,OK,0DH,0AH,$ ;提示语句”OK”DATAS ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASCHECKPASS MACRO BLA ;检验密码子程序,入口参数为8位寄存器“BLA”LOCAL BADLOCAL GOODLOCAL NEXTCMP BLA,SI ;如果对了第一位密码,SI向后走一个字节,一旦有错,SI回到PASSWORD头JNE BADCMP SI,DI ;DI指向PASSWORD尾,如果正确,则可以显示“OK”了JNE GOODLEA DX,HINTMOV AH,09HINT 21HGOOD:INC SIJMP NEXTBAD :LEA SI,PASSWORD NEXT:ENDMSERV PROC ;中断服务程序MOV DX,0280H ;读入A口数据IN AL,DXCMP AL,0FFH ;如果是FF那么退出JNE GOMOV AX,4C00HINT 21HGO: PUSH AX ; 这里保护AXMOV DL,AL ;显示A口ASCII码值MOV AH,02HINT 21HPOP AXCHECKPASS AL ;顺便检验一下是不是密码MOV AL,20H ;EOI命令退出中断OUT 20H,ALIRETSERV ENDPSTART:MOV AX,DATASMOV DS,AXLEA SI,PASSWORD ;SI指向PASSWORD头MOV DI,SIINC DI ;DI指向PASSWORD尾PUSH DS ;置中断矢量MOV DX,OFFSET SERVMOV AX,SEG SERVMOV DS,AXMOV AH,25HMOV AL,0BH INT 21HPOP DSIN AL,21H ;消除中断屏蔽AND AL,11110111BOUT 21H,ALMOV AL,10111011B ;写8255方式控制字MOV DX,0283HOUT DX,ALMOV AL,00001001B ;消除8255的中断屏蔽,这里好像没有明确讲MOV DX,0283HOUT DX,ALSTI ;允许中断过程W:JMP W mov ax,4c00hint 21hcode endsend start这个实验主要的问题就是一开始没有消除8255的中断屏蔽,我在书上也没有找到有关内容,希望如果教科书再版的话,加入详细的8255方式1输入输出的中断说明。5、选作内容将8255电路A口改成方式1输出(仅将PA7接一只LED示范即可),修改前面的程序实现每次中断后,通过A口输出数据控制LED状态在0,1之间翻转。源代码:STACKS SEGMENTDB 20 DUP(?)STACKS ENDSCODE SEGMENTASSUME CS:CODE,SS:STACKSSERV PROCMOV AL,CL ;CL相当于一个全局的控制灯翻转的变量MOV DX,0280H ;输出给A口OUT DX,ALNOT CL ;每次输出完,把CL反向一下,下一次输出的就是反向值了MOV AL,20H ;EOI命令OUT 20H,ALIRETSERV ENDPSTART:MOV DX,OFFSET SERV ;置中断矢量MOV AX,SEG SERVMOV DS,AXMOV AH,25HMOV AL,0BH INT 21HIN AL,21H ;消除中断屏蔽AND AL,11110111BOUT 21H,ALMOV AL,10100000B ;写8255方式控制字MOV DX,0283HOUT DX,ALMOV AL,00001001B ;清除8255中断屏蔽MOV DX,0283HOUT DX,ALMOV CL,0FFHSTIW:JMP W mov ax,4c00hint 21hcode endsend start6、扫描显示接口电路8255电路A口以方式0输出,C口也初始化成方式0输出且仅用其最低两位:PC1接数码管位码输入端S1,PC0接位码输入端S0。程序实现当A口输出字形“0”的段码时,C口输出01H,第一个数码管显示“0”,当A口输出字形“1”的段码时,C口输出02H,于是第二个数码管显示“1”。每一位显示之后调用一段延时程序,选择恰当的延时程序,使“01”几乎同时显示在两位数码管上。源代码:code segmentassume cs:codeDELAY MACROLOCAL GOPUSH DXMOV DX,01HGO:DEC DXJNE GOPOP DXENDMHOLD MACRO ;与之前一样,四次Delay才够长DELAYDELAYDELAYDELAYENDMSTART:MOV AL,10000000B ;写8255方式控制字MOV DX,0283HOUT DX,ALAGAIN: MOV AL,0 ;这里尤其关键,先要输出全暗,在输出所需值,这是为了消除重影MOV DX,0280HOUT DX,ALMOV AL,01H ;选通S0MOV DX,0282HOUT DX,ALMOV AL,3FH ;输出0MOV DX,0280HOUT DX,ALHOLDMOV AL,0 ;如果不清零的话,之前“0”的值3F还保留在A口里,MOV DX,0280H ;这样一选通S1首先输出的是0而非1,即有重影OUT DX,ALMOV AL,02H;选通S1MOV DX,0282H OUT DX,ALMOV AL,06H;输出1MOV DX,0280HOUT DX,ALHOLDMOV AH,0BH ;检测有无按键,不等待,之前已反复用到,不再赘述INT 21HCMP AL,0FFHJNZ AGAINMOV AH,01HINT 21HCMP AL, JNZ AGAINMOV AX,4C00HINT 21Hcode endsend start7、选作内容当程序运行后,从计算机键盘上输入两位十进制数,分别在两个数码管上显示。若继续输入数字则更新显示。若发现输入了非数字键则退回DOS。解决思路:把每次键盘输入的数字按键都放在一个缓存TEMP中,如果发现已经有两个数字键输入了,那么把这片缓存复制给名为PLAY的缓存,七段管每次只输出PLAY缓存的值,这样就可以实现每按两个键才改变七段管的值了。源代码:DATAS SEGMENTLED DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,07FH,06FH ;七段管0到9的ag的取值PLAY DB 3FH,3FH ;数码管当前显示值缓存器,默认值设为“00”TEMP DB 3FH,3FH ;键盘两位十进制数缓存器DATAS ENDSSTACKS SEGMENTDB 100 DUP(?)STACKS ENDSCODE SEGMENTASSUME CS:CODE,SS:STACKS,DS:DATASTRANS MACRO BLA ;键盘的ASCII码到七段管值的译码宏,入口参数为ASCII的八位寄存器BLALOCAL OKLOCAL EXITLOCAL NPUSH DXMOV DL,BLASUB DL,30HCMP DL,09H ;首先要判断键盘输入的是不是一个数字JA EXIT ;如果不是就退出LEA SI,LEDN: CMP DL,0 ;如果是,就去找到这个数字对应的七段管的值JZ OKINC SIDEC DLJMP NEXIT:MOV AX,4C00HINT 21HOK: MOV BLA,SI ;出口参数还是BLA,此时译码已完成,它表示的是七段管的值POP DXENDMDELAY MACRO ;延时子程序LOCAL GOPUSH DXMOV DX,0FFFFHGO:DEC DXJNE GOPOP DXENDMSTART:MOV AX,DATASMOV DS,AXMOV AL,10000000B ;写8255方式控制字MOV DX,0283HOUT DX,ALMOV CL,0 ;CL用来对键盘按键计数LEA BX,TEMP AGAIN:CMP CL,2 JNE N MOV CL,0;如果之前已经有两个键输入了,那么一切从头开始N:CMP CL,1JE ONEMOV AH,0BH ;不等待的检测按键,这个功能之前已反复用到INT 21HCMP AL,0FFHJNZ ONEMOV AH,01HINT 21HTRANS AL ;先译码为七段管值,再写入缓存TEMPMOV BX,ALINC CLONE: MOV AH,0BHINT 21HCMP AL,0FFHJNZ SHOWMOV AH,01HINT 21HTRANS ALMOV BX+1,AL ;之前已经有过一次按键了,所以写入BX+1位置INC CLSHOW:CMP CL,2 ;检验是不是已有两次按键JNE FORWARDLEA SI,PLAY ;如果已有两次,就把TEMP缓存复制到PLAY缓存,即更新待显示的值 MOV AX,BXMOV SI,AXINC SIMOV AX,BX+1MOV SI,AXFORWARD:MOV AL,0 ;先清除A口的输出值MOV DX,0280HOUT DX,ALMOV AL,02H ;选通S1 MOV DX,0282HOUT DX,ALLEA DI,PLAY ;输出缓存PLAY的第一个值MOV AL,DIMOV DX,0280HOUT DX,ALDELAYMOV AL,0 ;清除A口的输出值MOV DX,0280HOUT DX,ALMOV AL,01H;选通S0MOV DX,0282HOUT DX,ALINC DI ;输出缓存PLAY的第二个值MOV AL,DI MOV DX,0280HOUT DX,ALDELAYJMP AGAINcode endsend start8、选作内容使用TPC实验台上的8253定时计数电路来代替前面的软件延时。8253定时器自动重复工作,每工作一个周期发出一次中断请求信号,在中断服务程序里同步更换段码和位码,实现扫描显示。源代码:CODES SEGMENT ASSUME CS:CODESPLAY MACRO ;七段管显示子程序LOCAL ONELOCAL NEXTPUSH AXPUSH DXCMP CX,0 ;这里CX相当于全局的控制选通哪个七段管的变量JE ONE ;CX如果是零,那么去选通S1,否则选通S0MOV AL,0MOV DX,0280HOUT DX,ALMOV AL,01HMOV DX,0282HOUT DX,ALMOV AL,3FHMOV DX,0280HOUT DX,ALJMP NEXT ONE:MOV AL,0MOV DX,0280HOUT DX,ALMOV AL,02HMOV DX,0282HOUT DX,ALMOV AL,06HMOV DX,0280HOUT DX,ALNEXT: POP DXPOP AXENDMINTR PROC ;中断过程NOT CX ;每次来中断都反向CX,这样实现交替控制两个七段管PLAYMOV AL,20H ;EOI命令OUT 20H,ALIRETINTR ENDPSTART: PUSH DS ;装入新中断矢量MOV DX,OFFSET INTRMOV AX,SEG INTRMOV DS,AXMOV AH,25HMOV AL,0BHINT 21HPOP DSIN AL,21H ;消除对该位的屏蔽AND AL,11110111BOUT 21H,ALMOV DX,293H ;280289我给了并行通信, 290299我给了计数器MOV AL,00110111B OUT DX,AL ;写入CNT0控制字MOV DX,290HMOV AL,0OUT DX,AL ;先写低字节MOV AL,10HOUT DX,AL ;再写高字节MOV AL,10100000B ;写8255方式控制字MOV DX,0283HOUT DX,ALMOV CX,0 ;值CX初始值0STINEXT: JMP NEXTMOV AX,4C00H ;退出程序INT 21HCODES ENDSEND START实验总结本次实验加上写代码和调试我一共花了两天两夜的时间,我觉得收获颇丰。首先,是熟悉了AD和DA的转换思想和各种方式并行通信的方法,其次是对计算机硬件的特性,比如中断、扫描显示等有了更深的认识:扫描显示如果频率过高数码管可能不显示,用中断前需考虑有没有消除中断屏蔽。在此,也感谢消除8255中断屏蔽遇到问题时助教对我的帮助这次实验中我还发觉利用数据段建立缓存来记录数据是一个很好的办法,如果总用各种寄存器来记录数据,数据一旦多起来将很难维护。各种要用到的常量直接写入数据段也更方便。2012-9-9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值