单片机实验

实验二 基础实验

一、实验题目:

  1. (汇编)若0-5号键的键值分别是:EEH、DEH、BEH、7EH、EDH、DDH。设键值存放在内部RAM 20H单元中,编程实现根据2OH中的键值分别使程序转移到PR0-PR4程序段。要求当以上程序段的功能完成后,都采用RET指令,指定返回到程序的初始入口START标号处。

  2. (C语言)新建工程用C语言完成1题
    要求:PR0 :教材75页习题7
    PR1 :同上 习题9题
    PR2:同上 习题10
    其余入口,只需完成空操作就返回。
    PR3-4:ABCchar定义三个变量

二、实验目的
1、掌握散转的编程方法。
2、掌握指定返回的编程方法。

三、实验要求:
1、独立完成实验内容。
2、掌握在Keil中调试程序的方法。
3、掌握在Keil中建立存储器窗口的方法(C、D、X)
4、 提供实验报告(电子档)

四、实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请另加附页)

汇编代码:

BUF2 EQU 0A0H
BUF EQU 11H       
BUF1 EQU 0CCH
DATA1 EQU 04H 
      
ORG 0000H
LJMP STRAT
ORG 0100H

STRAT:
       MOV  DPTR ,#STRAT
       push dph
       push dpl    
       MOV DPTR,#TAB              ;键值表的     起始位置
       MOV R0,#0FFH        ;循环计数,初始为-1

NEXT:
       INC R0             ;自加
       MOV A,R0
       MOVC A,@A+DPTR
       CJNE A,B,NEXT      ;A与B的内容比较  现在查的键值存在B中,不等,循环键值表下一个单元
       MOV A,R0           ;键值表第几个位置送给A
       MOV DPTR,#JPT     
       RL A                 ;计算偏移 :A=A*2,AJMP为两字节指令,R0对应PR0,R1对应PR1。。。。。

                             ;若R0=2,变址A*2后为4,跳过4个字节到PR2处
       JMP @A+DPTR                        ;间接跳转到对应函数     基址JPT加变址RL A   JMP间接转移       

PR0:
       MOV R7,#10H    ;16个数据  十进制数10=16进制数10H
       MOV A,#0
       MOV R4,A
       MOV R5,A
       MOV R6,A
       MOV R0,#40H
       MOV R1,#50H
       mov R3,sp
       MOV SP,#3FH             ;指针指向3FH地址,从内部存储器30H单元开始,SP指向末地址

NEXT1:
       POP ACC         ;弹出从内部存储器30H单元开始的元素的末地址的元素
       JZ ZER0         ;判断是否为0
       JB ACC.7 ,NE1    ;最高位为1,为负数
       INC R4           ;正数个数加一         
       MOV @R0,A        ;存入R0地址,即40H地址
       INC R0                 ;地址加一
       AJMP DJ

NE1:
       INC R5            ;负数个数加一     
       MOV @R1,A        ;存入R1地址,即50H地址
       INC R1                 ;地址加一
       AJMP DJ

ZER0:
       INC R6

DJ:
       DJNZ R7,NEXT1   ;R7减1与0比较,不相等跳转
       mov sp,R3
              RET


;/*将存放在DATA1单元开始的一个4字节数去补后送回原单元*/

PR1:
       MOV R7,#03H       ;4字节数,用于高字节循环判断
       MOV R0,#DATA1

IN:
       INC R0
       DJNZ R7,IN
       MOV A,@R0
       JB ACC.7,FUSHU     ;和1比较,判断负数
       RET

FUSHU:
       MOV R7,#03H
       MOV R0,#DATA1
       MOV A,@R0     ;将DATA中的值送入A
       CPL A                    ;低字节求补     ;取反
       ADD A,#01                  ;加一
       MOV @R0,A         ;送回原地址

AB1:
       INC R0                   ;下一个字节
       MOV A,@R0
       CPL A                         ;取反
       ADDC A,#0                 ;加上低字节的进位
       DJNZ R7,AB1                ;减1和0比较,高字节循环3次
              RET     
               
;以BUF1为起始地址的外存储器中,存放着16个单字节无符号二进制数,
;将平均值存入BUF2,余数存入BUF

PR2:
       MOV R7,#0FH    ;16个数据   
       MOV R0,#BUF1
       MOV B,#0            ;存和的高位
       MOV A,@R0        ;取BUF1为起始地址的外存储器的首地址的值
       MOV R2,A           ;暂存R2

NEXT2:
       MOV A,R2
       INC R0                 ;BUF1下一个地址
       ADD A,@R0         ;数据求和,地位存于A
       MOV R2,A         ;暂存R2
       MOV A,B                    
       ADDC A,#0          
       MOV B,A         ;存数据高位,加上进位
       DJNZ R7,NEXT2   ;数据读完
       MOV R6,#04H     ;右移4次实现除以16
       MOV BUF2,A                     ;低位数据暂存于BUF2
       MOV BUF,#0 ;存余数

NEX:
       CLR C                 ;清空C
       MOV A,B                    ;B中高位数据送给A进行右移
       RRC A
       MOV B,A         ;右移后的高位数据暂存于B
       MOV A,BUF2      ;暂存于BUF2的低位数据送给A
       RRC A                 ;低位数据进行右移
       MOV BUF2,A      ;右移后的低位数据暂存于BUF2
       MOV A,BUF       
       RRC A
       MOV BUF,A
       DJNZ R6,NEX     ;求商,余数(右循环四次实现除以16)
       MOV A,BUF
       SWAP A
              RET              
PR3:
       NOP
              RET         
PR4:
       NOP
              RET                                          
JPT:
       AJMP PR0  
       AJMP PR1  
       AJMP PR2
       AJMP PR3
       AJMP PR4

       

TAB:DB
0EEH,0DEH,0BEH,07EH,0EDH,0DDH ;键值表

END
 
/*从内部存储器30H单元开始,有16个数据,将其中的正数,负数分别存入40H和50H开始的存储单元,并分别将正数,负数,零的个数存入R4,R5,R6中
*/     
C语言代码:

#include 
#include 
#include 
#define uint unsigned int 
#define uchar unsigned char 
#define BUF1 0x80
#define BUF2 0x90 
#define BUF  0x72
#define DATA 0x65
uchar key_value[6]={0xEE,0xDE,0xBE,0x7E,0xED,0xDD};  //0-5号的键值
/*
PR0:从30H开始,有16个数据,正数和负数分别存放在40H和50H中,将正数负数和零的个数存入R4,R5,R6   
/* 
(*p)++,是先取指针P的值,然后对其值进行++运算,*(p++),是先对指针P进行++运算,然后再取取值。
*的作用是使用P指针指向数据。
例如:假设int*P=1,那么*P++值为2.假设int
array[5]; int *p = a; p++之后 p=&array[1]; 
也就是所,p指针自加也就是说p指向p之后的数据单元,本来p指向array[0]的,自加就指向array[1].
*/
*/
void PR0(){
       uint i,R4,R5,R6 ;
       uchar table[]={1,2,3,-4,4,5,6,-6,-7,-8,0,-9,-10,-11,0,0}; //16个数据
       uchar *p=0x30;   //开始30H指针
       uchar *px=0x40;  //存正数
       uchar *py=0x50;  //存负数
       for(i=0;i<16;i++){
              if(table[i]>0){
                     R4++;                                                      //正数个数
                     (*px++)=table[i];   //
              }
              else if(table[i]<0){
                     R5++;                                                      //负数个数
                     (*py++)=table[i];
              }
              else
                     R6++;               //0的个数
       }
}
void PR1(){
        char data *p = DATA;
        char data *q = p+3;
      uchar i,cy=0;
      *(q)=0x0f4;
      if((*(q)&0x80)!=0)
      {
          for(i=0;i<4;i++,p++)
          {
              *p=~*p;  
          }
         p=DATA;
         if(0x0ff==*p) //DATA  11111111  --00000000
         {
             cy++;  
             *p=0;   
          }

         else (*p)++;  

         for(i=1,p++;i<3;i++,p++)

         {
            
if(*p==0x0ff&&cy==1)
             {
                 cy=1;
                 *p=0;
              }
              else if(cy==1)
              {

                  (*p)++;
                  cy=0;
    

你可能感兴趣的:(单片机实验)