..《单片机原理及应用》实验报告册系别:电气学院班级:自动化142姓名:学号:实验一:熟悉keil c51 集成开发环境及常用指令一、实验目的:(1)了解80c51典型应用系统的开发过程,熟悉keil c51集成开发环境;(2)掌握单步执行程序,查看专用寄存器和单片机RAM的执行结果;(3)掌握80c51的寻址方式及常用指令的使用方法。
二、实验内容(1)基本指令练习;(2)数据转送(循环方式)。
三、思考题1、分别执行以下程序,在调试状态下观察有关单元的内容顺序执行的程序:ORG 00HSJMP MAINORG 30HMAIN:MOV SP,#60HMOV R0,#40HMOV R1,#30HMOV 30H,#50HMOV A,#40HMOV @R0,A ;R0与A内容相等为40HINC AMOV A,@R1 ;A的内容为30H,R1的内容给APUSH ACC ;61H给APOP 32H ;60H给30HMOV A,#5FHSWAP A ;高四位低四位交换,A为F5HMOV DPTR,#0030HMOVX @DPTR,A循环程序:XUNHUAN1:MOV R0,#30H ;要赋值的首地址MOV R2,#10H ;一共赋值16次CLR A ;从0开始赋值LOOP1:MOV @R0,A ;赋值16次后停止赋值INC A ;32H=2,37H=7,3BH=0B,3FH=0FINC R0DJNZ R2,LOOP1XUNHUAN2:MOV R0,#30HMOV R1,#40HMOV R2,#10HLOOP2:MOV A,@R0 ;从40H开始一直赋值MOV @R1,A ;赋的值从30H开始INC R0 ;就是40H=30H,41H=31HINC R1 ;一直到R2=0DJNZ R2,LOOP2 ;就是4FH=3FH汇编程序3:PANDUAN1:MOV 30H,#10HMOV 31H,#4BHMOV R0,#30HMOV R1,#31HPAN0:MOV A,@R0CLR C ;进位位清零SUBB A,@R1 ;带进位位的加法JNC PAN1 ;判断进位位C,不为零跳转MOV A,@R0 ;所以当C等于零时,将MOV 40H,@R1 ;30H和30H的内容互换MOV @R0,40HMOV @R1,APAN0:NOPEND2、编程完成:单片机内部RAM40H~4FH置初值A0H~4FH 的内容传送到外部RAM中的2000H~200FH单元,在把外部RAM中的2000H~200FH单元的内容传送到单片机内部RAM的50H~5FH单元。
汇编代码:ORG 00HAJMP MAINORG 30HMAIN:MOV R0,#40HMOV R1,#16MOV A,#01HMOV DPTR,#2000HLOOP1:MOV @R0,AMOVX @DPTR,AINC DPTRINC R0INC ADJNZ R1,LOOP1 MOV R0,#50H MOV R1,#16MOV DPTR,#2000H LOOP2:MOVX A,@DPTR MOV @R0,AINC DPTRINC R0DJNZ R1,LOOP2 END实验二:中断、定时器与I/O口控制一、实验目的(1)掌握定时器/计数器、中断初始化程序设计的方法;(2) 掌握定时/计数器方式2的编程方法;(3)掌握中断的编程方法;(4)掌握使用单片机P1口和P3口做I/O输出,各参数的配置。
二、实验任务完成在每隔50MS/1S下接在P1口的八个发光二极管循环亮灭程序设计和调试。
要求:1、选择定时器T0方式一定时,中断方式产生50MS,使P1口的八个发光二极管循环亮灭。
2、用定时器与计数器的方式,使T0工作定时产生50MS,使T1工作与计数器,计数10次,每次T0溢出后从P3.0给T1端P3.5一个脉冲。
三、(1)用定时器定时,计数器计数,当50ms到来时,取反P3.0让P3.0口能够输出一个周期为100ms的脉冲,通过外接导线到P3.5,则计数器就有了外部脉冲的信号,而计数器是在下降沿时计数,所以应该让P3.0一开始就输出低电平。
电路图如下:(2)定时器方式一和方式二最大定时间分别是:方式一:65.536ms(2^13微秒)方式二:0.256ms(2^8微秒)实验三:扩展并行接口8155一、实验目的:(1)掌握8051单片机与8155的接口方法(2)掌握keil c51集成开发环境在硬件仿真条件下各参数的设置;(3)掌握软件延时和定时器中断延时的编程方法。
二、实验内容画出实验电路图:汇编程序:..ORG 0000HLJMP MAINORG 000BHLJMP TIMEOMAIN:MOV SP ,#60HMOV TMOD ,#01HMOV TH0 ,#3CHMOV TL0 ,#0B0H ;定时50msMOV DPTR ,7FF8 ;DPTR指向命令寄存器8155 MOV A ,#03H ;设定A,B,C工作方式MOVX @DPTR ,A ;启动8155MOV DPTR,#7FF9H ;打开A口MOV A ,#0FEHMOVX @DPTR ,A ;将流水灯值给PA口SETB EASETB ET0SETB TR0 ;打开单片机定时器0SJMP $TIME0:MOV TH0 ,#3CHMOV TL0 ,0B0HRL AMOVX @DPTR ,A ;将左移的值给PA口RETIEND实验四:并行A/D转换一、实验目的:(1)掌握并行A/D芯片ADC0809与单片机的接口方法(2)了解ADC0809芯片的性能;(3)通过实验了解单片机实现数据采集的方法。
二、实验内容:画出电路图:按图中cs接P2.7则模拟输入通道的地址值INT0~INT7:7FF8~7FFF#include"stdio.h"typedef int ElemType;typedef int Status;struct List{ElemType *list1; //指向线性表的第一个节点int length; //线性表的实际长度int listSize; //线性表的最大长度324};//附加1:给线性表增加空间Status AgainMalloc(struct List *L1){ElemType *p = (ElemType *)realloc(L1->list1,(L1->listSize + 1)*sizeof(ElemTy pe));if(!p){printf("存储空间分配失败!");exit(1);}L1->list1 = p; /*使list1指向新线性表空间*/L1->listSize=L1->listSize + 1; /*把线性空间大小修改为新的长度*/’.//附加2:遍历线性表元素Status Traverse(struct List *L1){int i;for(i = 0;i < L1->length;i++){printf("%d ",L1->list1[i]);}}//1.创建线性表,给定长度Status InitList(struct List *L1,int ms){if(ms<0){printf("初始化线性表的长度不能小于0\n");exit(1);}L1->length = 0;L1->listSize = ms;//给list1分配空间,单元大小为定义的ElemType类型,长度为ms L1->list1 = (ElemType *)malloc(ms * sizeof(ElemType));if(!L1)’.printf("空间分配失败!");exit(1);}else{printf("空间分配成功!\n");printf("您分配的空间大小为%d\n",ms);}return 0;}//2.销毁线性表Status DestoryList(struct List *L1){if(L1 != NULL){L1->length = 0;L1->listSize = 0;free(L1);}printf("销毁成功!\n");return 0;}’.//3.清空线性表Status ClearList(struct List *L1){//清空只需要将线性表的长度记为0即可。
L1->length = 0;printf("清空成功!\n");return 0;}//4.判断线性表是否为空(如果为空返回0,如果不为空返回1)Status ListEmpty(struct List *L1){if(L1->length != 0){printf("线性表不为空!\n");return 1;}else{printf("线性表为空!\n");return 0;}}//5.返回线性表的当前长度’.int ListLength(struct List *L1){return L1->length;}//6.返回第i个元素的值ElemType GetElem(struct List *L1,int i){if((i < 1)||(i > L1->listSize)){printf("查找的位置超出线性表的范围!");//退出exit(1);}else{//返回第pos个元素的值return L1->list1[i-1];}}//7.判断某个元素是否是线性表元素,如果是,返回这个元素第一次在线性表中出现的位置,如果不是返回0int IsElem(struct List *L1,ElemType e){’.//必须要先定义,后使用!int i;for(i = 0;i<L1->length;i++){if(L1->list1[i]==e)//因为i是从0,开始,所有返回i+1return i + 1;} //如果没有找到相应的元素,返回-1;return 0;}//8.返回某个元素的前驱元素(如果这个元素是第一个,则提示“这是第一个元素”)//1、如果这个元素不是线性表元素,返回-1//2、如果这个元素是线性表第一个元素,返回0,提示第一个元素没有前驱元素ElemType PriorElem(struct List *L1,ElemType e){//判断这个元素是否是线性表元素,如果是返回它的第一个位置//调用IsElem函数,并将结果返回给temp变量int temp = IsElem(L1,e);if(temp == 0){printf("这个元素不是线性表的元素");return -1;}else if(temp == 1)’.{printf("这个元素是第一个元素,没有前驱元素");return 0;}else{//返回e元素的前驱元素return L1->list1[temp-2];}}//9.返回某个元素的后继元素(如果这个元素是最后一个,则提示“这是最后一个元素”)//1、如果这个元素不是线性表元素,返回-1//2、如果这个元素是线性表的最后一个元素,返回0,提示最后一个元素没有后继元素ElemType NextElem(struct List *L1,ElemType e){//判断这个元素是否是线性表元素,如果是返回它的第一个位置//调用IsElem函数,并将结果返回给temp变量int temp = IsElem(L1,e);if(temp == 0){printf("这个元素不是线性表的元素");return -1;}else if (temp == L1->length)’.{printf("这个元素是最后一个元素,没有后继元素");return 0;}else{//返回e元素的后继元素return L1->list1[temp];}}//10.在线性表的指定位置i之前插入元素eStatus ListInsert(struct List *L1,int i,ElemType e){int temp;if((i < 1)||(i > L1->length + 1)){printf("i越界,不能插入");exit(1);} //如果线性表的长度等于最大长度,增加空间if(L1->length == L1->listSize){//每次增加1个ElemType单位的个空间AgainMalloc(L1);} //将位置i之后的元素向后以一个位置for(temp = (L1->length+1);temp >= i;temp--)L1->list1[temp] = L1->list1[temp-1];//在i-1的位置插入新元素eL1->list1[i-1] = e;//长度加1L1->length = L1->length +1;return 0;}//11.删除线性表中指定位置i的元素e,并将e返回ElemType ListDelete(struct List *L1,int i){ElemType e;int temp;if((i < 1)||(i > L1->length)){printf("要删除的元素超出线性表的范围!");exit(1);} //将第i个位置的元素返回给ee = L1->list1[i-1];for(temp = i;i < L1->length;i++){//将第i+1个元素的值赋值给第i个位置L1->list1[i-1] = L1->list1[i];}//将长度减去1L1->length = L1->length - 1;return e;}int main(){int itemp = 0;int anytemp = 0;int i = 1;int listlength = 0;ElemType e;struct List L1;printf("线性表的基本操作!\n");printf("**************初始化操作*****************\n");printf("请输入初始化的长度:");scanf("%d",&itemp);//1.创建--InitList(struct List *L1,int ms)InitList(&L1,itemp);printf("请输入线性表的值,不能超过%d个,以911结束,911不算长度:\n",itemp); for(i = 1;i <= itemp;i++){scanf("%d",&e);//这里不能是exit,exit直接退出了所有程序,所以是breakif(e == 911)break;//10.在线性表指定位置i之前插入元素eListInsert(&L1,i,e);}//5.返回长度--ListLength(struct List *L1)listlength = ListLength(&L1);printf("目前,线性表的长度为:%d\n",listlength);//遍历线性表printf("目前,线性表的值为:\n");//遍历,在Traverse中输出Traverse(&L1);//6.返回第i个元素值--GetElem(struct List *L1,int i)printf("请输入,要返回第几个元素值:\n");//输入时,要在这里赋值地址“&”scanf("%d",&anytemp);printf("第%d个位置元素的对应的元素值为:%d\n",anytemp,GetElem(&L1,anytemp)); //8.返回某个元素的前驱--PriorElem(struct List *L1,ElemType e)printf("返回线性表元素的前驱,请输入线性表元素:\n");scanf("%d",&e);printf("元素%d的前驱元素是:%d\n",e,PriorElem(&L1,e));//9.返回某个元素的后继--NextElem(struct List *L1,ElemType e) printf("返回线性表元素的后继,请输入线性表元素:\n");scanf("%d",&e);printf("元素%d的后继元素是:%d\n",e,NextElem(&L1,e));//11.删除线性表指定位置i的元素,将结果e返回--ListDelete(struct List *L1,int i)listlength = ListLength(&L1);printf("目前,线性表的长度为:%d\n",listlength);printf("请输入要删除第几个位置的元素:\n");scanf("%d",&i);ListDelete(&L1,i);listlength = ListLength(&L1);printf("目前,线性表的长度为:%d\n",listlength);printf("目前,线性表的值为:\n");//遍历,在Traverse中输出Traverse(&L1);return 0;}。