TEMP EQU 50H ;临时变量
SGM_H EQU 51H ;求和的高8位,以及平均值
SGM_L EQU 52H ;求和的低8位,以及平均值的余数
ORG 0000H
LJMP MAIN
ORG 0030H
MAIN:
LCALL MM ;排序子程序
LCALL AVG ;平均值子程序
SJMP $
MM:
MOV R0,#40H
LP_1:
MOV A,R0
MOV R1,A
MOV TEMP,@R0
LP_2:
INC R1
MOV A,@R1
CJNE A,TEMP,NEXT1
NEXT1:
JNC NEXT2
MOV @R0,A
MOV @R1,TEMP
MOV TEMP,@R0
NEXT2:
CJNE R1,#4FH,LP_2
INC R0
CJNE R0,#4FH,LP_1
RET
AVG:
MOV R0,#41H
MOV A,@R0
MOV SGM_H,#00H
LP_3:
CLR C
INC R0
ADD A,@R0
JNC NEXT3
INC SGM_H
NEXT3:
CJNE R0,#4EH,LP_3
MOV SGM_L,A
;以上部分是求和
SWAP A
ANL A,#0FH
MOV R1,A
MOV A,SGM_H
SWAP A
ADD A,R1
MOV B,#14D
DIV AB
SWAP A
MOV SGM_H,A
MOV A,B
SWAP A
MOV R1,A
MOV A,SGM_L
ANL A,#0FH
ADD A,R1
MOV B,#14D
DIV AB
ADD A,SGM_H
MOV SGM_H,A
MOV SGM_L,B
;以上部分是16位除以8位的除法
RET
解题思路是先排序,得到最大值与最小值,然后求平均值。
以上供参考。
2. 请大家帮忙写下单片机mcs51程序 (所有的分全给)
你的题目太模糊了,好像两个程序的电路图还不一样吧。没有电路图是作不了程序的,至少也要给出外围器件与单片机是怎么连接的。
3. 51单片机中12位双字节数(低12位)求平均数
;
MOV R0, #40H ;四个数据的起始地址
MOV R2, #4
MOV R3, #0 ;四个数据的和
MOV R4, #0
A_LOOP:
MOV A, R3
ADD A, @R0 ;加数据低字节
MOV R3, A
INC R0
MOV A, R4
ADDC A, @R0 ;加数据高字节
MOV R4, A
INC R0
DJNZ R2, A_LOOP ;
;-------------------------下面除以4,右移两位即可
CLR C
MOV A, R4
RRC A ;先移高八位
MOV R4, A
MOV A, R3
RRC A ;后移低八位
MOV R3, A
CLR C ;再移动一次
MOV A, R4
RRC A
MOV R4, A
MOV A, R3
RRC A
MOV R3, A
;结果在 R4R3。
END
找出最大、最小,要比较双字节的数据。
全部循环一遍,所花费的时间,就太多了。
特别是多字节的数据,特费时间。
不如,利用这些时间,多采样几个数据,累加后,取平均值。
用向右移位,代替除法,特别方便。
那么,采样数据的个数,宜取:4、8、16。
个数再多,好像也没有必要了。
4. 用MCS-51单片机汇编语言实现下列的程序:
;1--片内RAM30H字节单元的存储内容传送到片内RAM20H字节单元
MOV 20H,30H
;2--片内RAM30H字节单元的存储内容传送到片外RAM2000H字节单元
MOV A,30H
MOV DPH,#20H
MOV DPL,#00H
MOVX @DPTR,A
;3--片外ROM30H字节单元的存储内容传送到片内RAM30H字节单元
MOV DPH,#00H
MOV DPL,#30H
CLR A
MOVC A,@A+DPTR
MOV 30H,A
;4--片外ROM3000H字节单元的存储内容传送到片外RAM2000H字节单元
MOV DPH,#30H
MOV DPL,#00H
CLR A
MOVC A,@A+DPTR
MOV DPH,#20H
MOV DPL,#00H
MOVX @DPTR,A
;5--片外ROM3000H字节单元的存储内容传送到片外ROM2000H字节单元
;这道题目是错误的,ROM不可修改,所以无法将任何数据传送到ROM里
;所以,“内容传送到片外ROM2000H字节单元”是无法实现的。
5. MCS-51单片机程序设计
周期2ms,占空比1:2,,也就是说高电平667us,低电平1333us,你的定时器参数分别为:
TGH=(65536-667)/256;
TGL=(65536-667)%256;
TDH=(65536-1333)/256;
TDL=(65536-1333)%256;
在中断服务程序里交替用这两个参数给TH0和TL0赋值,对P1.0取反就可以了。
#include<reg51.h>
#define uchar unsigned char
uchar tgh,tgl,tdh,tdl;
bit flag;
sbit p10=P1^0;
void t0isr() interrupt 1
{
if(flag)
{
TH0=tgh;
TL0=tgl;
p10=0;
flag=~flag;
}
if(!flag)
{
TH0=tdh;
TL0=tdl;
p10=1;
flag=~flag;
}
}
main()
{
TMOD=0x01;
tgh=(65536-667)/256;
tgl=(65536-667)%256;
tdh=(65536-1333)/256;
tdl=(65536-1333)%256;
TH0=tdh;
TL0=tdl;
TR0=1;
ET0=1;
EA=1;
while(1);
}
6. 用汇编语言编写80c51单片机程序,求内部RAM中50H~59H十个单元内容的平均值,并存放在5AH单元。
结合1,2,3楼,考虑了溢出问题。花了好多时间才想出来了。
希望对你有帮助。
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN:
MOV R0,#50H
MOV R7,#10
MOV R2,#00H
MOV A,#00H
LOOP:CLR C
ADD A,@R0
JNC BBB
INC R2
CLR C
BBB: INC R0
DJNZ R7,LOOP
MOV 5CH,A ;把和放5CH,不用管溢出的,和为s1
MOV 5BH,R2 ;把溢出的次数放地址5BH
MOV B,5BH ;溢出的次数给B
MOV A,#19H ;溢出一次相当于 100H=(FAH+10H)=19*BH+ 6*BH /A
MUL AB ;A=溢出部分的平均值,肯定小于0FF
MOV 5AH,A ;第一部分的平均值p1给5AH
MOV A,#6H
MOV B,5BH
MUL AB ;值给5BH,最大值是3CH,所以不用考虑溢出。
ADD A,5CH ;
MOV B,#10
DIV AB ;6B+s1的平均值p2
ADD A,5AH
MOV 5AH,A ;p1+p2
MOV 5BH,B
SJMP $
END
7. MCS—51单片机定时/计数器实验 编程 求程序
按照图示,应该用P1.7向T1送入计数脉冲
送去4000个,即达到了1s
下列程序,在PROTEUS中仿真通过
;---------------------------------
ORG
0000H
JMP
START
ORG
000BH
JMP
T0_INT
ORG
001BH
JMP
T1_INT
ORG
0030H
START:MOV
SP,#60H
MOV
TMOD,#52H
;T1计数方式1;
T0定时方式2
MOV
TH0,
#(256-250)
;T0定时250us@12MHz
MOV
TL0,
#(256-250)
;
SETB
TR0;
MOV
TH1,
#(65536-4000)
/
256
;T1计数4000
MOV
TL1,
#(65536-4000)
MOD
256
;即1s
SETB
TR1;
SETB
ET0;
SETB
ET1;
SETB
EA;
MOV
R2,
#3
WAIT:
SJMP
WAIT
;等待中断
;----------------------------------
T0_INT:
;T0方式2,不用重新送初始值.
CLR
P1.7
;向T1送计数脉冲.
NOP
SETB
P1.7
RETI
;----------------------------------
T1_INT:
;每当收到4000个脉冲,即1s中断一次.
MOV
TL1,
#(65536-4000)
MOD
256
;重新送入初始值.
MOV
TH1,
#(65536-4000)/256
;T1计数4000
CLR
P1.0
DJNZ
R2,
T1_END
SETB
P1.0
MOV
R2,
#3
T1_END:
RETI
;----------------------------------
END
8. MCS-51单片机求平均值的源程序
加法除法不会吗?
假设有8个数
uchar tempdata[8];
uint sum=0;
uchar av;
for(i=0;i<8;i++)
{
sum+=tempdata[i];
}
av=(uint)sum/8;
9. 求 单片机 十分复用 使用例子,C 汇编都行,那种单片都行,51最好,多谢谢!
MCS-51 的寻址方式:
1 、立即寻址 如: MOV A , #40H
2 、直接寻址 如: MOV A , 3AH
3 、寄存器寻址 如: MOV A , Rn
4 、寄存器间接寻址 如: MOV A , @Rn
5 、基址加变址寻址 如: MOVC A , @A+DPTR
6 、相对寻址 如: SJMP 08H
7 、位寻址 MOV 20H , C
以下是详细介绍:
一、立即寻址:操作数就写在指令中,和操作码一起放在程序存贮器中。把“#”号放在立即数前面,以表示该寻址方式为立即寻址,如#20H。
二、寄存器寻址:操作数放在寄存器中,在指令中直接以寄存器的名字来表示操作数的地址。例如MOV A,R0就属于寄存器寻址,即将R0寄存器的内容送到累加器A中。
三、直接寻址:操作数放在单片机的内部RAM某单元中,在指令中直接写出该单元的地址。如前例的ADD A,70H中的70H。
四、寄存器间接寻址:操作数放在RAM某个单元中,该单元的地址又放在寄存器R0或R1中。
如果RAM的地址大于256,则该地址存放在16位寄存器DPTR(数据指针)中,此时在寄存器名前加@符号来表示这种间接寻址。如MOV A,@R0。其它还有变址寻址、相对寻址、位寻址等,待以后再详细介绍。可能有人会问,在指令中直接给出实际操作数,不是简单、明了吗?为什么还要用其它几种寻址方式呢?这是因为在编制程序时很难一下子就给出操作数。如用单片机控制温度时,时时需要将给定的控制温度(如20℃)减去环境温度,而环境温度时时有变化,显然无法在程序指令中给出,只有通过一定方式,将其送入某个输入/输出口,再存放在某个寄存器中,这就必须用到寄存器寻址。又如要进行算术运算,要计算每班学员各科成绩的平均值,如果把每个学员的各科都编一个程序,在程序中直接给出该学员各科成绩,再求平均值,显然太麻烦。这里可以编一个求平均成绩的通用程序,把每位学员的成绩送入存贮器的各个单元中,这时可采取直接寻址,一个程序可供每个学员用,不是更方便吗?所以,寻址方式越多,编制程序就越方便、灵活,适用范围就越广。寻址有如找人,如被找的人有手机、BP机、座机电话等多种联系方式则就容易找到他,单片机也是如此,寻址方式越多,找操作数越方便,单片机的功能就越强。前面介绍51系列单片机的寻址方式时,常遇到单片机内部的一些寄存器、累加器A、通用寄存器R0~R7、数据指针DPTR和存贮器等。在以后介绍指令时,数据就要在这些寄存器、存贮器之间传送,或者进行运算。因此,编制程序就需熟悉单片机的内部结构。
8051单片机的内部总体结构其基本特性如下:
8位CPU、片内振荡器
4k字节ROM、128字节RAM
21个特殊功能寄存器
32根I/O线
可寻址的64k字节外部数据、程序存贮空间
2个16位定时器、计数器
中断结构:具有二个优先级、五个中断源
一个全双口串行口
位寻址(即可寻找某位的内容)功能,适于按位进行逻辑运算的位处理器。除128字节RAM、4k字节ROM和中断、串行口及定时器模块外,还有4组I/O口P0~P3,余下的就是CPU的全部组成。把4kROM换为EPROM就是8751的结构,如去掉ROM/EPROM部分即为8031的框图,如果将ROM置换为Flash存贮器或EEPROM,或再省去某些I/O,即可得到51系列的派生品种,如89C51、AT89C2051等单片机的框图。
10. 由键盘输入10个数,求出其中的最大值、最小值及平均值的C程序
c程序如下:
#include <stdio.h>
int main()
{
double max=0,min=0,a,s=0;
int i;
for(i=1;i<=10;i++)
{
printf("请输入第%d个数:",i);
scanf("%f",&a);
if (max<a) then max=a;
if (min>a) then min=a;
s+=a;
}
printf("最大值:%f,最小值:%f,平均值:%f”,max,min,s/10);
return 0;
}
C++程序:
#include<iostream>
using namespace std;
int max(int *p);
int min(int *p);
double avg(int *p);
void main()
{
int a[10];
for(int i=0;i<10;++i)
cin>>a[i];
cout<<"最大数"<<max(a);
cout<<"最小数"<<min(a);
cout<<"平均数"<<avg(a);
}
int max(int*p)
{
int max;
max=p[0];
for(int i=1;i<10;++i)
if(max<p[i])
{
max=p[i];
}
return max;
}
int min(int*p)
{
int min;
min=p[0];
for(int i=1;i<10;++i)
if(min>p[i])
{
min=p[i];
}
return min;
}
double avg(int *p)
{
double sum=0;
for(int i=0;i<10;++i)
{
sum+=p[i];
}
return sum/10;
}