51单片机编程实例大全(下部)
学习单片机
// 实例 1:用单片机控制第一个灯亮
#include<reg51.h> //包含 51单片机寄存器定义的头文件void main(void)
{ P1=0xfe; //P1=1111 1110B,即 P1.0输出低电平
}
// 实例 2:用单片机控制一个灯闪烁:认识单片机的工作频率
#include<reg51.h> //包含单片机寄存器的头文件/ 函数功能:延时一段时间
/ void delay(void) //两个 void 意思分别为无需返回值,没有参数传递{
unsigned int i; // 定义无符号整数,最大取值范围 65535 for(i=0;i<20000;i++) // 做 20000次空循环
; //什么也不做,等待一个机器周期} / 函数功能:主函数 (C语言规定必须有也只能有 1个主函数)
/ void main(void) {
while(1) //无限循环{
P1=0xfe; //P1=1111 1110B, P1.0输出低电平delay(); //延时一段时间P1=0xff; //P1=1111 1111B, P1.0输出高电平delay(); //延时一段时间
} }
// 实例 3:将 P1 口状态分别送入 P0、P2、P3 口:认识 I/O 口
的引脚功能
#include<reg51.h> //包含单片机寄存器的头文件
/ 函数功能:主函数 (C语言规定必须有也只能有 1个主函数)
/
void main(void) {
while(1) //无限循环{
P1=0xff; // P1=1111 1111B,熄灭 LED P0=P1; // 将 P1口状态送入 P0口P2=P1; // 将 P1口状态送入 P2口
P3=P1; // 将 P1口状态送入 P3口}
}
// 实例 4:使用 P3 口流水点亮 8 位 LED
#include<reg51.h> //包含单片机寄存器的头文件/ 函数功能:延时一段时间
/
void delay(void) {
unsigned char i,j; for(i=0;i<250;i++)
for(j=0;j<250;j++) ;
} / 函数功能:主函数
/ void main(void) {
while(1) {
P3=0xfe; //第一个灯亮delay(); //调用延时函数P3=0xfd; //第二个灯亮delay(); //调用延时函数P3=0xfb; //第三个灯亮delay(); //调用延时函数
P3=0xf7; //第四个灯亮delay(); //调用延时函数P3=0xef; //第五个灯亮
delay(); //调用延时函数P3=0xdf; //第六个灯亮delay(); //调用延时函数P3=0xbf; //第七个灯亮
delay(); //调用延时函数P3=0x7f; //第八个灯亮
delay(); //调用延时函数}
}
//实例 7:通过对 P3口地址的操作流水点亮 8位 LED #include<reg51.h> //包含单片机寄存器的头文件sfr x=0xb0; //P3 口在存储器中的地址是 b0H, 通过 sfr 可定义 8051内核单片机
//的所有内部 8位特殊功能寄存器 ,对地址 x的操作也就是对 P1口的操作/ 函数功能:延时一段时间
/ void delay(void)
{ unsigned char i,j; for(i=0;i<250;i++)
for(j=0;j<250;j++) ; //利用循环等待若干机器周期,从而延时一段时间
} / 函数功能:主函数
/ void main(void) {
while(1) {
x=0xfe; //第一个灯亮delay(); // 调用延时函数x=0xfd; //第二个灯亮
delay(); // 调用延时函数x=0xfb; //第三个灯亮
delay(); // 调用延时函数x=0xf7; //第四个灯亮
delay(); // 调用延时函数x=0xef; //第五个灯亮
delay(); //调用延时函数x=0xdf; //第六个灯亮delay(); //调用延时函数x=0xbf; //第七个灯亮
delay(); //调用延时函数x=0x7f; //第八个灯亮
delay(); //调用延时函数}
}
//实例 8:用不同数据类型控制灯闪烁时间#include<reg51.h> //包含单片机寄存器的头文件/ 函数功能:用整形数据延时一段时间
/ void int_delay(void) //延时一段较长的时间{
unsigned int m; // 定义无符号整形变量,双字节数据,值域为 0~65535 for(m=0;m<36000;m++)
; //空操作} / 函数功能:用字符型数据延时一段时间
/ void char_delay(void) //延时一段较短的时间{
unsigned char i,j; //定义无符号字符型变量,单字节数据,值域 0~255 for(i=0;i<200;i++)
for(j=0;j<180;j++) ; //空操作
} / 函数功能:主函数
/ void main(void) {
unsigned char i; while(1)
{ for(i=0;i<3;i++)
{
P1=0xfe; //P1.0 口的灯点亮int_delay(); //延时一段较长的时间P1=0xff; //熄灭int_delay(); //延时一段较长的时间
} for(i=0;i<3;i++)
{ P1=0xef; //P1.4 口的灯点亮char_delay(); //延时一段较长的时间P1=0xff; //熄灭char_delay(); //延时一段较长的时间
}
}
}
// 实例 9:用 P0 口、 P1 口分别显示加法和减法运算结果
#include<reg51.h> void main(void) {
unsigned char m,n; m=43; //即十进制数 2x16+11=43 n=60; //即十进制数 3x16+12=60 P1=m+n; //P1=103=0110 0111B,结果 P1.3、P1.4、P1.7 口的灯被点亮P0=n-m; //P0=17=0001 0001B,结果 P0.0、P0.4的灯被熄灭
}
// 实例 10:用 P0、P1 口显示乘法运算结果
#include<reg51.h> //包含单片机寄存器的头文件void main(void) {
unsigned char m,n; unsigned int s; m=64;
n=71; s=m n; //s=64 71=4544,需要 16位二进制数表示,高 8位送 P1口,低 8
位送 P0口//由于 4544=17 256+192=H3 16 16 16+H2 16 16+H1 16+H0
//两边同除以 256,可得 17+192/256=H3 16+H2+(H1 16+H0)/256
//因此,高 8位 16进制数 H3 16+H2必然等于 17,即 4544除以 256的商
//低 8位 16进制数 H1 16+H0必然等于 192,即 4544除以 256的余数
P1=s/256; //高 8位送 P1口 ,P1=17=11H=0001 0001B, P1.0和 P1.4口灭,其余亮
P0=s%256; //低 8位送 P0口 , P3=192=c0H=1100 0000B,P3.1,P3.6,P3.7口灭,其余亮}
// 实例 11:用 P1、P0 口显示除法运算结果
#include<reg51.h> //包含单片机寄存器的头文件void main(void) {
P1=36/5; //求整数P0=((36%5) 10)/5; //求小数while(1)
; //无限循环防止程序"跑飞"}
// 实例 12:用自增运算控制 P0 口 8 位 LED 流水花样
#include<reg51.h> //包含单片机寄存器的头文件/ 函数功能:延时一段时间
/ void delay(void) {
unsigned int i; for(i=0;i<20000;i++)
; } / 函数功能
/ void main(void) {
unsigned char i; for(i=0;i<255;i++) //注意 i 的值不能超过 255 {
P0=i; //将 i的值送 P0口delay(); //调用延时函数
} }
// 实例 13:用 P0 口显示逻辑 "与"运算结果
#include<reg51.h> //包含单片机寄存器的头文件void main(void) {
P0=(4>0)&&(9>0xab);//将逻辑运算结果送 P0口while(1)
; //设置无限循环,防止程序"跑飞"}
// 实例 14:用 P0 口显示条件运算结果
#include<reg51.h> //包含单片机寄存器的头文件void main(void) {
P0=(8>4)?8:4;//将条件运算结果送 P0口,P0=8=0000 1000B while(1)
; //设置无限循环,防止程序"跑飞"}
// 实例 15:用 P0 口显示按位 "异或 "运算结果
#include<reg51.h> //包含单片机寄存器的头文件void main(void) {
P0=0xa2^0x3c;// 将条件运算结果送 P0口,P0=8=0000 1000B while(1)
; //设置无限循环,防止程序"跑飞"}
// 实例 16:用 P0 显示左移运算结果
#include<reg51.h> //包含单片机寄存器的头文件void main(void) {
P0=0x3b<<2;//将左移运算结果送 P0口,P0=1110 1100B=0xec while(1)
; //无限循环,防止程序"跑飞"}
// 实例 17:"万能逻辑电路 "实验
#include<reg51.h> //包含单片机寄存器的头文件sbit F=P1^4; //将 F位定义为 P1.4 sbit X=P1^5; //将 X位定义为 P1.5 sbit Y=P1^6; //将 Y位定义为 P1.6 sbit Z=P1^7; //将 Z位定义为 P1.7 void main(void) {
while(1) {
F=((~X)&Y)|Z; //将逻辑运算结果赋给 F ;
} }
// 实例 18:用右移运算流水点亮 P1 口 8 位 LED
#include<reg51.h> //包含单片机寄存器的头文件/
函数功能:延时一段时间/
void delay(void) { unsigned int n; for(n=0;n<30000;n++)
; } / 函数功能:主函数
/ void main(void) {
unsigned char i; while(1)
{ P1=0xff; delay(); for(i=0;i<8;i++)//设置循环次数为 8 {
P1=P1>>1; //每次循环 P1的各二进位右移 1位,高位补 0 delay(); //调用延时函数
} }
}
// 实例 19:用 if 语句控制 P0 口 8 位 LED 的流水方向
#include<reg51.h> //包含单片机寄存器的头文件sbit S1=P1^4; //将 S1位定义为 P1.4 sbit S2=P1^5; //将 S2位定义为 P1.5 / 函数功能:主函数
/ void main(void) {
while(1) { if(S1==0) //如果按键 S1按下
P0=0x0f; //P0 口高四位 LED点亮if(S2==0) //如果按键 S2按下
P0=0xf0; //P0 口低四位 LED点亮}
}
// 实例 20:用 swtich 语句的控制 P0 口 8 位 LED 的点亮状态
#include<reg51.h> //包含单片机寄存器的头文件sbit S1=P1^4; //将 S1位定义为 P1.4 / 函数功能:延时一段时间
/ void delay(void) { unsigned int n; for(n=0;n<10000;n++)
; } / 函数功能:主函数
/ void main(void) {
unsigned char i; i=0; //将 i初始化为 0 while(1) {
if(S1==0) //如果 S1键按下{
delay(); //延时一段时间if(S1==0) //如果再次检测到 S1键按下
i++; //i 自增 1 if(i==9) //如果 i=9,重新将其置为 1
i=1;
} switch(i) //使用多分支选择语句
{ case 1: P0=0xfe; //第一个 LED亮
break; case 2: P0=0xfd; // 第二个 LED亮
break;
case 3:P0=0xfb; //第三个 LED亮break;
case 4:P0=0xf7; //第四个 LED亮break;
case 5:P0=0xef; //第五个 LED亮break;
case 6:P0=0xdf; //第六个 LED亮break;
case 7:P0=0xbf; //第七个 LED亮break;
case 8:P0=0x7f; //第八个 LED亮break;
default: //缺省值,关闭所有 LED P0=0xff;
} }
}
// 实例 21:用 for 语句控制蜂鸣器鸣笛次数
#include<reg51.h> //包含单片机寄存器的头文件sbit sound=P3^7; // 将 sound位定义为 P3.7 / 函数功能:延时形成 1600Hz音频
/ void delay1600(void) { unsigned char n;
for(n=0;n<100;n++) ;
} / 函数功能:延时形成 800Hz音频
/ void delay800(void) { unsigned char n;
for(n=0;n<200;n++) ;
}
/
函数功能:主函数/
void main(void) {
unsigned int i; while(1) {
for(i=0;i<830;i++) {
sound=0; //P3.7 输出低电平delay1600(); sound=1; //P3.7 输出高电平delay1600();
} for(i=0;i<200;i++) {
sound=0; //P3.7 输出低电平delay800(); sound=1; //P3.7 输出高电平delay800();
}
}
}
// 实例 22:用 while 语句控制 LED
#include<reg51.h> //包含单片机寄存器的头文件/ 函数功能:延时约 60ms (3 100 200=60000μs)
/ void delay60ms(void) { unsigned char m,n; for(m=0;m<100;m++)
for(n=0;n<200;n++) ;
} / 函数功能:主函数
/ void main(void) {
unsigned char i; while(1) //无限循环{
i=0; //将 i初始化为 0 while(i<0xff) //当 i小于 0xff(255)时执行循环体{
P0=i; //将 i 送 P0口显示delay60ms(); //延时i++; //i 自增 1
} }
}
// 实例 23:用 do-while 语句控制 P0 口 8 位 LED 流水点亮
#include<reg51.h> //包含单片机寄存器的头文件/ 函数功能:延时约 60ms (3 100 200=60000μs)
/ void delay60ms(void) { unsigned char m,n; for(m=0;m<100;m++)
for(n=0;n<200;n++) ;
} / 函数功能:主函数
/ void main(void) {
do {
P0=0xfe; // 第一个 LED亮delay60ms(); P0=0xfd; // 第二个 LED亮delay60ms(); P0=0xfb; //第三个 LED亮delay60ms();
P0=0xf7; //第四个 LED亮delay60ms(); P0=0xef; //第五个 LED亮delay60ms(); P0=0xdf; //第六个 LED亮delay60ms(); delay60ms(); P0=0xbf; //第七个 LED亮delay60ms(); P0=0x7f; //第八个 LED亮delay60ms();
}while(1); //无限循环,使 8位 LED循环流水点亮}
// 实例 24:用字符型数组控制 P0 口 8 位 LED 流水点亮
#include<reg51.h> //包含单片机寄存器的头文件/ 函数功能:延时约 60ms (3 100 200=60000μs)
/ void delay60ms(void) { unsigned char m,n; for(m=0;m<100;m++)
for(n=0;n<200;n++) ;
} / 函数功能:主函数
/ void main(void) {
unsigned char i; unsigned char code Tab[ ]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定义无符
号字符型数组while(1) {
for(i=0;i<8;i++) {
P0=Tab[i];//依次引用数组元素,并将其送 P0口显示delay60ms();//调用延时函数
}
} }
// 实例 25: 用 P0 口显示字符串常量
#include<reg51.h> //包含单片机寄存器的头文件/ 函数功能:延时约 150ms (3 200 250=150 000μs=150ms
/ void delay150ms(void) {
unsigned char m,n; for(m=0;m<200;m++)
for(n=0;n<250;n++) ;
} / 函数功能:主函数
/ void main(void) {
unsigned char str[]={"Now,Temperature is :"}; // 将字符串赋给字符型全部元素赋值
unsigned char i; while(1) {
i=0; //将 i初始化为 0,从第一个元素开始显示while(str[i]!='\0') // 只要没有显示到结束标志 '\0' {
P0=str[i]; //将第 i个字符送到 P0口显示delay150ms(); //调用 150ms延时函数i++; // 指向下一个待显字符
} }
}
// 实例 26:用 P0 口显示指针运算结果??
#include<reg51.h> void main(void)
{ unsigned char p1, p2; //定义无符号字符型指针变量 p1,p2 unsigned char i,j; //定义无符号字符型数据i=25; //给 i 赋初值 25 j=15; p1=&i; //使指针变量指向 i ,对指针初始化p2=&j; //使指针变量指向 j ,对指针初始化P0= p1+ p2; // p1+ p2 相当于 i+j,所以 P0=25+15=40=0x28
//则 P0=0010 1000B,结果 P0.3、P0.5引脚 LED熄灭,其余点亮while(1)
; //无限循环,防止程序"跑飞"
}
// 实例 27:用指针数组控制 P0 口 8 位 LED 流水点亮
#include<reg51.h> / 函数功能:延时约 150ms (3 200 250=150 000μs=150ms
/ void delay150ms(void) {
unsigned char m,n; for(m=0;m<200;m++)
for(n=0;n<250;n++) ;
} / 函数功能:主函数
/ void main(void) {
unsigned char code Tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char p[ ]={&Tab[0],&Tab[1],&Tab[2],&Tab[3],&Tab[4],&Tab[5],
&Tab[6],&Tab[7]};
unsigned char i; //定义无符号字符型数据while(1)
{ for(i=0;i<8;i++)
{ P0= p[i];
delay150ms(); }
} }
// 实例 28:用数组的指针控制 P0 口 8 位 LED 流水点亮
#include<reg51.h> / 函数功能:延时约 150ms (3 200 250=150 000μs=150ms
/ void delay150ms(void) {
unsigned char m,n; for(m=0;m<200;m++)
for(n=0;n<250;n++) ;
} / 函数功能:主函数
/ void main(void) {
unsigned char i; unsigned char Tab[ ]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,
0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE, 0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,0x00, 0xE7,0xDB,0xBD,0x7E,0x3C,0x18,0x00,0x81, 0xC3,0xE7,0x7E,0xBD,0xDB,0xE7,0xBD,0xDB}; //流水灯控制码
unsigned char p; //定义无符号字符型指针p=Tab; // 将数组首地址存入指针 p while(1)
{ for(i=0;i<32;i++) //共 32个流水灯控制码
{ P0= (p+i); // (p+i)的值等于 a[i] delay150ms(); //调用 150ms延时函数
} }
}
// 实例 29:用 P0 、P1 口显示整型函数返回值
#include<reg51.h> / 函数功能:计算两个无符号整数的和
/ unsigned int sum(int a,int b) {
unsigned int s; s=a+b; return (s);
} / 函数功能:主函数
/ void main(void) {
unsigned z; z=sum(2008,2009); P1=z/256; //取得 z的高 8位P0=z%256; //取得 z的低 8位while(1)
; }
// 实例 30:用有参函数控制 P0 口 8 位 LED 流水速度
#include<reg51.h> / 函数功能:延时一段时间
/ void delay(unsigned char x) {
unsigned char m,n; for(m=0;m<x;m++)
for(n=0;n<200;n++) ;
} /
函数功能:主函数/
void main(void) {
unsigned char i; unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
//流水灯控制码while(1)
{ //快速流水点亮 LED for(i=0;i<8;i++) //共 8个流水灯控制码
{ P0=Tab[i]; delay(100); //延时约 60ms, (3 100 200=60 000μs)
} //慢速流水点亮 LED for(i=0;i<8;i++) //共 8个流水灯控制码{
P0=Tab[i]; delay(250); //延时约 150ms, (3 250 200=150 000μs)
} }
}
// 实例 31:用数组作函数参数控制流水花样
#include<reg51.h> / 函数功能:延时约 150ms
/ void delay(void) {
unsigned char m,n; for(m=0;m<200;m++)
for(n=0;n<250;n++) ;
} / 函数功能:流水点亮 P0口 8位 LED
/ void led_flow(unsigned char a[8]) {
unsigned char i; for(i=0;i<8;i++)
{ P0=a[i]; delay();
} }
/ 函数功能:主函数
/ void main(void) {
unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水灯控制码
led_flow(Tab);
}
// 实例 32:用指针作函数参数控制 P0 口 8 位 LED 流水点亮
#include<reg51.h> / 函数功能:延时约 150ms
/ void delay(void) {
unsigned char m,n; for(m=0;m<200;m++)
for(n=0;n<250;n++) ;
} / 函数功能:流水点亮 P0口 8位 LED
/ void led_flow(unsigned char p) //形参为无符号字符型指针{
unsigned char i; while(1) {
i=0; //将 i置为 0,指向数组第一个元素while( (p+i)!='\0') // 只要没有指向数组的结束标志{
P0= (p+i);// 取的指针所指变量(数组元素)的值,送 P0口delay(); //调用延时函数i++; // 指向下一个数组元素
} }
}
/ 函数功能:主函数
/ void main(void) {
unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F, 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,
0xFF,0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,
0x00,0xE7,0xDB,0xBD,0x7E,0xFF,0xFF,0x3C, 0x18,0x0,0x81,0xC3,0xE7,0xFF,
0xFF,0x7E}; //流水灯控制码
unsigned char pointer; pointer=Tab; led_flow(pointer);
}
// 实例 33:用函数型指针控制 P1 口灯花样
#include<reg51.h> //包含 51单片机寄存器定义的头文件unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水灯控制码,该数组被定义为全局变量/ 函数功能:延时约 150ms
/ void delay(void)
{
unsigned char m,n; for(m=0;m<200;m++) for(n=0;n<250;n++)
; }
/ 函数功能:流水灯左移
/ void led_flow(void) {
unsigned char i; for(i=0;i<8;i++) //8 位控制码
{ P0=Tab[i]; delay();
}
} / 函数功能:主函数
/ void main(void) {
void ( p)(void); //定义函数型指针,所指函数无参数,无返回值p=led_flow; //将函数的入口地址赋给函数型指针 p while(1) ( p)(); //通过函数的指针 p调用函数 led_flow()
}
// 实例 34:用指针数组作为函数的参数显示多个字符串
#include<reg51.h> //包含 51单片机寄存器定义的头文件unsigned char code str1[ ]="Temperature is tested by DS18B20";//C语言中,字符串是作为字符数组来处理的unsigned char code str2[ ]="Now temperature is:"; //所以,字符串的名字就是字符串的首地址
unsigned char code str3[ ]="The Systerm is designed by Zhang San"; unsigned char code str4[ ]="The date is 2008-9-30"; unsigned char p[ ]={str1,str2,str3,str4}; // 定义 p[4]为指向 4个字符串的字符型指针数组/
函数功能:延时约 150ms /
void delay(void) {
unsigned char m,n; for(m=0;m<200;m++) for(n=0;n<250;n++)
; }
/ 函数功能:流水点亮 P0口 8位 LED
/ void led_display(unsigned char x[ ]) //形参必须为指针数组{
unsigned char i,j; for(i=0;i<4;i++) //有 4个字符串要显示{
j=0; //指向待显字符串的第 0号元素while( (x[i]+j)!='\0') // 只要第 i个字符串的第 j 号元素不是结束标志
{ P0= (x[i]+j); //取得该元素值送到 P0口显示delay(); //调用延时函数
j++; //指向下一个元素}
} } / 函数功能:主函数
/ void main(void) {
unsigned char i; while(1)
{ for(i=0;i<4;i++)
led_display(p); //将指针数组名作实际参数传递}
}
// 实例 35:字符函数 ctype.h 应用举例
#include<reg51.h> //包含 51单片机寄存器定义的头文件
#include<ctype.h> void main(void) {
while(1) {
P3=isalpha('_')?0xf0:0x0f;//条件运算,若 '_'是英文字母, P3=0xf0 }
}
// 实例 36:内部函数 intrins.h 应用举例
#include<reg51.h> //包含 51单片机寄存器定义的头文件#include<intrins.h> // 包含函数 isalpha()声明的头文件/ 函数功能:延时约 150ms
/ void delay(void) {
unsigned char m,n; for(m=0;m<200;m++)
for(n=0;n<250;n++) ;
} / 函数功能:主函数
/ void main(void) {
P3=0xfe; //P3=1111 1110B while(1)
{ P3=_crol_(P3,1);// 将 P3的二进制位循环左移 1位后再赋给 P3 delay(); //调用延时函数
} }
// 实例 37:标准函数 stdlib.h 应用举例
#include<reg51.h> //包含 51单片机寄存器定义的头文件#include<stdlib.h> //包含函数 isalpha()声明的头文件/ 函数功能:延时约 150ms
/ void delay(void) {
unsigned char m,n; for(m=0;m<200;m++)
for(n=0;n<250;n++) ;
} / 函数功能:主函数
/ void main(void) { unsigned char i; while(1) {
for(i=0;i<10;i++) //产生 10个随机数{
P3=rand()/160; //将产生的随机数缩小 160倍后送 P3显示delay();
} }
}
// 实例 38:字符串函数 string.h 应用举例
#include<reg51.h> //包含 51单片机寄存器定义的头文件#include<string.h> //包含函数 isalpha()声明的头文件void main(void) { unsigned char str1[ ]="Now, The temperature is :"; unsigned char str2[ ]="Now, The temperature is 36 Centgrade:"; unsigned char i; i=strcmp(str1,str2); //比较两个字符串,并将结果存入 i if(i==0) //str1=str2
P3=0x00; else
if(i<0) //str1<str2 P3=0xf0;
else //str1>str2 P3=0x0f;
while(1) ; //防止程序"跑飞"
}
// 实例 39:宏定义应用举例 2
#include<reg51.h> //包含 51单片机寄存器定义的头文件# define F(a,b) (a)+(a) (b)/256+(b) //带参数的宏定义, a和 b为形参void main(void) {
unsigned char i,j,k; i=40; j=30; k=20; P3=F(i,j+k); //i 和 j+k分别为实参,宏展开时,实参将替代宏定义中的形
参while(1)
; }
// 实例 40:宏定义应用举例 2
#include<AT89X51.h> #include<ctype.h> void main(void) {
P3_0=0; //将 P3.0引脚置低电平, LED点亮P3_1=0; //将 P3.0引脚置低电平, LED点亮P3_2=0; //将 P3.0引脚置低电平, LED点亮P3_3=0; //将 P3.0引脚置低电平, LED点亮P3_4=1; //将 P3.4引脚置高电平, LED熄灭P3_5=1; //将 P3.5引脚置高电平, LED熄灭P3_6=1; //将 P3.7引脚置高电平, LED熄灭
P3_7=1; //将 P3.7引脚置高电平, LED熄灭while(1)
; }
// 实例 41:宏定义应用举例 3
#include<reg51.h> //包含 51单片机寄存器定义的头文件#define MAX 100 //将 MAX宏定义为字符串 100 void main(void) {
#if MAX>80 //如果字符串 100大于 80 P3=0xf0; //P3 口低四位 LED点亮
#else P3=0x0f; //否则,P3口高四位 LED点亮
#endif //结束本次编译
}
/
中断、定时器 中断、定时器
中断、定时器 中断、定时器
/
// 实例 42:用定时器 T0 查询方式 P2 口 8 位控制 LED 闪烁
#include<reg51.h> // 包含 51单片机寄存器定义的头文件/ 函数功能:主函数
/ void main(void)
{ // EA=1; // 开总中断
// ET0=1; // 定时器 T0中断允许TMOD=0x01; //使用定时器 T0的模式 1 TH0=(65536-46083)/256; //定时器 T0的高 8位赋初值TL0=(65536-46083)%256; //定时器 T0的高 8位赋初值TR0=1; // 启动定时器 T0 TF0=0; P2=0xff; while(1)// 无限循环等待查询{
while(TF0==0) ;
TF0=0; P2=~P2;
TH0=(65536-46083)/256; //定时器 T0的高 8位赋初值TL0=(65536-46083)%256; //定时器 T0的高 8位赋初值
} }
// 实例 43:用定时器 T1 查询方式控制单片机发出 1KHz 音频
#include<reg51.h> // 包含 51单片机寄存器定义的头文件sbit sound=P3^7; //将 sound位定义为 P3.7引脚/ 函数功能:主函数
/ void main(void) {
// EA=1; // 开总中断// ET0=1; //定时器 T0中断允许
TMOD=0x10; //使用定时器 T1的模式 1 TH1=(65536-921)/256; //定时器 T1的高 8位赋初值TL1=(65536-921)%256; //定时器 T1的高 8位赋初值TR1=1; // 启动定时器 T1 TF1=0; while(1)// 无限循环等待查询{
while(TF1==0) ;
TF1=0;
sound=~sound; //将 P3.7引脚输出电平取反TH1=(65536-921)/256; //定时器 T0的高 8位赋初值TL1=(65536-921)%256; //定时器 T0的高 8位赋初值
} }
// 实例 44:将计数器 T0 计数的结果送 P1 口 8 位 LED 显示
#include<reg51.h> // 包含 51单片机寄存器定义的头文件sbit S=P3^4; //将 S位定义为 P3.4引脚/ 函数功能:主函数
/ void main(void) {
// EA=1; // 开总中断// ET0=1; // 定时器 T0中断允许
TMOD=0x02; //使用定时器 T0的模式 2 TH0=256-156; //定时器 T0的高 8位赋初值TL0=256-156; //定时器 T0的高 8位赋初值TR0=1; // 启动定时器 T0 while(1)// 无限循环等待查询{
while(TF0==0) //如果未计满就等待{
if(S==0) //按键 S按下接地,电平为 0 P1=TL0; //计数器 TL0加 1后送 P1口显示
} TF0=0; //计数器溢出后,将 TF0清 0
} }
// 实例 45:用定时器 T0 的中断控制 1 位 LED 闪烁
#include<reg51.h> // 包含 51单片机寄存器定义的头文件sbit D1=P2^0; //将 D1位定义为 P2.0引脚/
函数功能:主函数/
void main(void) {
EA=1; // 开总中断ET0=1; // 定时器 T0中断允许TMOD=0x01; //使用定时器 T0的模式 2 TH0=(65536-46083)/256; //定时器 T0的高 8位赋初值TL0=(65536-46083)%256; //定时器 T0的高 8位赋初值TR0=1; // 启动定时器 T0 while(1)// 无限循环等待中断
; }
/ 函数功能:定时器 T0的中断服务程序
/ void Time0(void) interrupt 1 using 0 //"interrupt"声明函数为中断服务函数
//其后的 1为定时器 T0的中断编号; 0表示使用第 0组工作寄存器
{ D1=~D1; //按位取反操作,将 P2.0引脚输出电平取反TH0=(65536-46083)/256; //定时器 T0的高 8位重新赋初值TL0=(65536-46083)%256; //定时器 T0的高 8位重新赋初值
}
// 实例 46:用定时器 T0 的中断实现长时间定时
#include<reg51.h> // 包含 51单片机寄存器定义的头文件sbit D1=P2^0; //将 D1位定义为 P2.0引脚unsigned char Countor; //设置全局变量,储存定时器 T0中断次数/ 函数功能:主函数
/ void main(void) {
EA=1; // 开总中断ET0=1; // 定时器 T0中断允许TMOD=0x01; //使用定时器 T0的模式 2 TH0=(65536-46083)/256; //定时器 T0的高 8位赋初值TL0=(65536-46083)%256; //定时器 T0的高 8位赋初值TR0=1; // 启动定时器 T0
Countor=0; // 从 0开始累计中断次数while(1)// 无限循环等待中断
; }
/ 函数功能:定时器 T0的中断服务程序
/ void Time0(void) interrupt 1 using 0 //"interrupt"声明函数为中断服务函数
//其后的 1为定时器 T0的中断编号; 0表示使用第 0组工作寄存器{
Countor++; //中断次数自加 1 if(Countor==20) //若累计满 20次,即计时满 1s {
D1=~D1; //按位取反操作,将 P2.0引脚输出电平取反Countor=0; //将 Countor清 0,重新从 0开始计数
} TH0=(65536-46083)/256; //定时器 T0的高 8位重新赋初值TL0=(65536-46083)%256; //定时器 T0的高 8位重新赋初值
}
// 实例 47:用定时器 T1 中断控制两个 LED 以不同周期闪烁
#include<reg51.h> // 包含 51单片机寄存器定义的头文件sbit D1=P2^0; //将 D1位定义为 P2.0引脚sbit D2=P2^1; //将 D2位定义为 P2.1引脚unsigned char Countor1; //设置全局变量,储存定时器 T1中断次数unsigned char Countor2; //设置全局变量,储存定时器 T1中断次数/ 函数功能:主函数
/ void main(void) {
EA=1; // 开总中断ET1=1; // 定时器 T1中断允许TMOD=0x10; //使用定时器 T1的模式 1 TH1=(65536-46083)/256; //定时器 T1的高 8位赋初值TL1=(65536-46083)%256; //定时器 T1的高 8位赋初值TR1=1; // 启动定时器 T1 Countor1=0; //从 0开始累计中断次数Countor2=0; //从 0开始累计中断次数
while(1)// 无限循环等待中断;
} / 函数功能:定时器 T1的中断服务程序
/ void Time1(void) interrupt 3 using 0 //"interrupt"声明函数为中断服务函数
//其后的 3为定时器 T1的中断编号; 0表示使用第 0组工作寄存器{
Countor1++; //Countor1 自加 1 Countor2++; //Countor2 自加 1 if(Countor1==2) //若累计满 2次,即计时满 100ms
{ D1=~D1; //按位取反操作,将 P2.0引脚输出电平取反Countor1=0; //将 Countor1清 0,重新从 0开始计数
} if(Countor2==8) //若累计满 8次,即计时满 400ms
{ D2=~D2; //按位取反操作,将 P2.1引脚输出电平取反Countor2=0; //将 Countor1清 0,重新从 0开始计数
} TH1=(65536-46083)/256; //定时器 T1的高 8位重新赋初值TL1=(65536-46083)%256; //定时器 T1的高 8位重新赋初值
}
// 实例 48:用计数器 T1 的中断控制蜂鸣器发出 1KHz 音频
#include<reg51.h> // 包含 51单片机寄存器定义的头文件sbit sound=P3^7; // 将 sound位定义为 P3.7引脚/ 函数功能:主函数
/ void main(void) {
EA=1; // 开总中断ET1=1; // 定时器 T1中断允许TMOD=0x10; //TMOD=0001 000B,使用定时器 T1的模式 1 TH1=(65536-921)/256; //定时器 T1的高 8位赋初值TL1=(65536-921)%256; // 定时器 T1的高 8位赋初值TR1=1; // 启动定时器 T1
while(1)// 无限循环等待中断;
} / 函数功能:定时器 T1的中断服务程序
/ void Time1(void) interrupt 3 using 0 //"interrupt"声明函数为中断服务函数{
sound=~sound; TH1=(65536-921)/256; //定时器 T1的高 8位重新赋初值TL1=(65536-921)%256; // 定时器 T1的高 8位重新赋初值
}
// 实例 49:用定时器 T0 的中断实现 "渴望 "主题曲的播放
#include<reg51.h> //包含 51单片机寄存器定义的头文件sbit sound=P3^7; //将 sound位定义为 P3.7 unsigned int C; //储存定时器的定时常数//以下是 C调低音的音频宏定义#define l_dao 262 //将" l_dao"宏定义为低音" 1"的频率 262Hz #define l_re 286 //将" l_re"宏定义为低音" 2"的频率 286Hz #define l_mi 311 //将" l_mi"宏定义为低音" 3"的频率 311Hz #define l_fa 349 //将" l_fa"宏定义为低音" 4"的频率 349Hz #define l_sao 392 //将" l_sao"宏定义为低音" 5"的频率 392Hz #define l_la 440 //将" l_a"宏定义为低音" 6"的频率 440Hz #define l_xi 494 // 将" l_xi"宏定义为低音" 7"的频率 494Hz //以下是 C调中音的音频宏定义#define dao 523 //将"dao"宏定义为中音" 1"的频率 523Hz #define re 587 //将" re"宏定义为中音" 2"的频率 587Hz #define mi 659 //将"mi"宏定义为中音" 3"的频率 659Hz #define fa 698 // 将" fa"宏定义为中音" 4"的频率 698Hz #define sao 784 //将" sao"宏定义为中音" 5"的频率 784Hz #define la 880 //将" la"宏定义为中音" 6"的频率 880Hz #define xi 987 //将"xi"宏定义为中音" 7"的频率 523H //以下是 C调高音的音频宏定义#define h_dao 1046 // 将"h_dao"宏定义为高音" 1"的频率 1046Hz #define h_re 1174 //将"h_re"宏定义为高音" 2"的频率 1174Hz #define h_mi 1318 // 将"h_mi"宏定义为高音" 3"的频率 1318Hz #define h_fa 1396 //将"h_fa"宏定义为高音" 4"的频率 1396Hz #define h_sao 1567 //将"h_sao"宏定义为高音" 5"的频率 1567Hz #define h_la 1760 //将"h_la"宏定义为高音" 6"的频率 1760Hz
#define h_xi 1975 //将"h_xi"宏定义为高音" 7"的频率 1975Hz / 函数功能: 1个延时单位,延时 200ms
/ void delay()
{ unsigned char i,j; for(i=0;i<250;i++)
for(j=0;j<250;j++) ;
} / 函数功能:主函数
/ void main(void)
{ unsigned char i,j;
//以下是《渴望》片头曲的一段简谱unsigned int code f[]={re,mi,re,dao,l_la,dao,l_la, // 每行对应一小节音符
l_sao,l_mi,l_sao,l_la,dao, l_la,dao,sao,la,mi,sao, re, mi,re,mi,sao,mi, l_sao,l_mi,l_sao,l_la,dao,
l_la,l_la,dao,l_la,l_sao,l_re,l_mi, l_sao, re,re,sao,la,sao, fa,mi,sao,mi, la,sao,mi,re,mi,l_la,dao, re, mi,re,mi,sao,mi, l_sao,l_mi,l_sao,l_la,dao, l_la,dao,re,l_la,dao,re,mi, re, l_la,dao,re,l_la,dao,re,mi, re, 0xff}; // 以 0xff 作为音符的结束标志
//以下是简谱中每个音符的节拍//"4" 对应 4个延时单位, "2"对应 2个延时单位, "1"对应 1个延时单位unsigned char code JP[ ]={4,1,1,4,1,1,2,
2,2,2,2,8, 4,2,3,1,2,2, 10,
4,2,2,4,4, 2,2,2,2,4,
2,2,2,2,2,2,2, 10, 4,4,4,2,2, 4,2,4,4, 4,2,2,2,2,2,2, 10, 4,2,2,4,4, 2,2,2,2,6, 4,2,2,4,1,1,4, 10, 4,2,2,4,1,1,4, 10 };
EA=1; //开总中断ET0=1; //定时器 T0中断允许TMOD=0x00; // 使用定时器 T0的模式 1(13位计数器)while(1) // 无限循环
{ i=0; //从第 1个音符 f[0]开始播放
while(f[i]!=0xff) //只要没有读到结束标志就继续播放{ C=460830/f[i]; TH0=(8192-C)/32; //可证明这是 13位计数器 TH0高 8位的赋
初值方法
TL0=(8192-C)%32; //可证明这是 13位计数器 TL0低 5位的赋初值方法
TR0=1; //启动定时器 T0 for(j=0;j<JP[i];j++) //控制节拍数
delay(); // 延时 1个节拍单位TR0=0; //关闭定时器 T0
i++; //播放下一个音符}
} } / 函数功能:定时器 T0的中断服务子程序,使 P3.7引脚输出音频的方波
/ void Time0(void ) interrupt 1 using 1 {
sound=!sound; //将 P3.7引脚输出电平取反,形成方波TH0=(8192-C)/32; //可证明这是 13位计数器 TH0高 8位的赋初值方法TL0=(8192-C)%32; //可证明这是 13位计数器 TL0低 5位的赋初值方法
}
// 实例 50-1:输出 50 个矩形脉冲
#include<reg51.h> //包含 51单片机寄存器定义的头文件sbit u=P1^4; //将 u位定义为 P1.4 / 函数功能:延时约 30ms (3 100 100=30 000μs =30m
/ void delay30ms(void) {
unsigned char m,n; for(m=0;m<100;m++)
for(n=0;n<100;n++) ;
} / 函数功能:主函数
/ void main(void)
{ unsigned char i; u=1; //初始化输出高电平for(i=0;i<50;i++) //输出 50个矩形脉冲
{ u=1; delay30ms(); u=0; delay30ms();
} while(1)
; //无限循环,防止程序"跑飞"}
// 实例 50-2 :计数器 T0 统计外部脉冲数
#include<reg51.h> //包含 51单片机寄存器定义的头文件
/ 函数功能:主函数
/ void main(void)
{ TMOD=0x06; // TMOD=0000 0110B,使用计数器 T0的模式 2 EA=1; //开总中断ET0=0; //不使用定时器 T0的中断TR0=1; //启动 T0 TH0=0; //计数器 T0高 8位赋初值TL0=0; // 计数器 T0低 8位赋初值while(1) //无限循环,不停地将 TL0计数结果送 P1口P1=TL0;
}
// 实例 51-2 :定时器 T0 的模式 2 测量正脉冲宽度
#include<reg51.h> //包含 51单片机寄存器定义的头文件sbit ui=P3^2; // 将 ui位定义为 P3.0( INT0)引脚,表示输入电压/ 函数功能:主函数
/ void main(void)
{ TMOD=0x0a; // TMOD=0000 1010B,使用定时器 T0的模式 2,GATE置 1 EA=1; //开总中断ET0=0; //不使用定时器 T0的中断TR0=1; //启动 T0 TH0=0; //计数器 T0高 8位赋初值TL0=0; // 计数器 T0低 8位赋初值while(1) // 无限循环,不停地将 TL0计数结果送 P1口{
while(ui==0) //INT0 为低电平, T0不能启动;
TL0=0; //INT0 为高电平,启动 T0计时,所以将 TL0清 0 while(ui==1) //在 INT0高电平期间,等待,计时
; P1=TL0; //将计时结果送 P1口显示
} }
// 实例 52:用定时器 T0 控制输出高低宽度不同的矩形波
#include<reg51.h> //包含 51单片机寄存器定义的头文件sbit u=P3^0; //将 u 位定义为 P3.0,从该引脚输出矩形脉冲unsigned char Countor; //设置全局变量,储存负跳变累计数/ 函数功能:延时约 30ms (3 100 100=30 000μs =30ms)
/ void delay30ms(void) {
unsigned char m,n; for(m=0;m<100;m++)
for(n=0;n<100;n++) ;
}
/ 函数功能:主函数
/ void main(void)
{ unsigned char i; EA=1; //开放总中断EX0=1; //允许使用外中断IT0=1; //选择负跳变来触发外中断Countor=0; for(i=0;i<100;i++) //输出 100个负跳变{
u=1; delay30ms(); u=0; delay30ms();
} while(1)
; //无限循环, 防止程序跑飞}
/ 函数功能:外中断 T0的中断服务程序
/ void int0(void) interrupt 0 using 0 // 外中断 0的中断编号为 0 {
Countor++; P1=Countor;
}
// 实例 53:用外中断 0 的中断方式进行数据采集
#include<reg51.h> //包含 51单片机寄存器定义的头文件sbit S=P3^2; //将 S位定义为 P3.2,/ 函数功能:主函数
/ void main(void)
{ EA=1; //开放总中断EX0=1; //允许使用外中断IT0=1; //选择负跳变来触发外中断P1=0xff; while(1) ; //无限循环, 防止程序跑飞
} / 函数功能:外中断 T0的中断服务程序
/ void int0(void) interrupt 0 using 0 // 外中断 0的中断编号为 0 {
P1=~P1; //每产生一次中断请求, P1取反一次。
}
单片机试题及答案
第一章
1-1选择
1.计算机中最常用的字符信息编码是( A )
A ASCII B BCD码 C 余3码 D 循环码
2.要MCS-51系统中,若晶振频率屡8MHz,一个机器周期等于(A ) μs
A 1.5 B 3 C 1 D 0.5
3.MCS-51的时钟最高频率是 ( A ).
A 12MHz B 6 MHz C 8 MHz D 10 MHz
4. 以下不是构成的控制器部件(D ):
A 程序计数器、 B指令寄存器、 C指令译码器、 D存储器
5. 以下不是构成单片机的部件( D )
A 微处理器(CPU)、B存储器 C接口适配器(I\O接口电路) D 打印机
6. 下列不是单片机总线是( D )
A 地址总线 B 控制总线 C 数据总线 D 输出总线
7.-49D的二进制补码为.( B )
A 11101111 B 11101101 C 0001000 D 11101100
8.十进制29的二进制表示为原码( C )
A 11100010 B 10101111 C 00011101 D 00001111
9. 十进制0.625转换成二进制数是( A )
A 0.101 B 0.111 C 0.110 D 0.100
10 选出不是计算机中常作的码制是( D )
A 原码 B 反码 C补码 D ASCII
1-2填空
1.计算机中常作的码制有原码、反码和补码
2.十进制29的二进制表示为00011101
3.十进制数-29的8位补码表示为.11100011
4.单片微型机CPU、存储器和I\O接口三部分组成.
5.若不使用MCS-51片内存器引脚EA必须接地.
6.输入输出设备是计算机与外部世界交换信息的载体.
7.十进制数-47用8位二进制补码表示为.11010001
8.-49D的二进制补码为.11101101
9.计算机中最常用的字符信息编码是ASCII
10.计算机中的数称为机器数,它的实际值叫真值。
1-3判断
1.我们所说的计算机实质上是计算机的硬件系统与软件系统的总称。 ( √ )
2.MCS-51上电复位时,SBUF=00H。 ( × )。 SBUF不定。
3.使用可编程接口必须处始化。 ( √ )。
4.8155的复位引脚可与89C51的复位引脚直接相连。( √ )
5.MCS-51是微处理器。( × )不是。
6.MCS-51系统可以没有复位电路。( × )不可以。复位是单片机的初始化操作。
7.要MCS-51系统中,一个机器周期等于1.5μs。( × )若晶振频率屡8MHz,才可能为1.5μs
8.计算机中常作的码制有原码、反码和补码( √ )
9.若不使用MCS-51片内存器引脚EA必须接地. ( √ )
10.十进制数-29的8位补码表示为.11100010( × )
1-4简答
1.何谓单片机?单片机与一般微型计算机相比,具有哪些特点?
答:单片机是在一块集成电路上把CPU、存储器、定时器/计数器及多种形式的I/O接口集成在一起而构成的微型计算机。它与通用微型计算机相比,具有如下特点:
(1) 单片机的程序存储器和数据存储器是分工的,前者为ROM,后者为RAM;
(2) 采用面向控制的指令系统,控制功能强;
(3) 多样化的I/O接口,多功能的I/O引脚;
(4) 产品系列齐全,功能扩展性强;
(5) 功能是通用的,像一般微处理机那样可广泛地应用在各个方面。
2 单片机主要应用在哪些领域?
答:单片机的应用范围很广泛,诸如智能化家用电器、仪器仪表、工业控制、计算机外部设备、智能机器人、电信及导航等方面。
3 在各种系列的单片机中,片内ROM的配置有几种形式?用户应根据什么原则来选用?
答:各种类型的单片机片内程序存储器的配置形式主要有以下几种形式:
(1) (Msak)ROM型单片机:内部具有工厂 编程的ROM,ROM中的程序只能由单片机制造厂家用 工艺固化,用户不能修改ROM中的程序。例如:MCS—51系列的8051。
ROM单片机适合于大批量生产的产品。用户可委托芯片生产厂家采用 方法将程序制作在芯片的ROM。
(2) EPROM型单片机:内部具有紫外线可擦除电可编程的只读存储器,用户可以自行将程序写入到芯片内部的EPROM中,也可以将EPROM中的信息全部擦除。擦去信息的芯片还可以再次写入新的程序,允许反复改写。例如:MCS—51系列的8751。
EPROM型单片机使用比较方便,但价格较高,适合于研制产品或结构要求简单的小批量产品。
(3) 无ROM型单片机:内部没有程序存储器,它必须连接程序存储器才能组成完整的应用系统。例如:MCS—51系列的8031。
无ROM型单片机价格低廉,用户可根据程序的大小来选择外接程序存储器的容量。这种单片机扩展灵活,但系统结构较复杂。
(4) E2ROM型单片机:内部具有电可擦除叫可编程的程序存储器,使用更为方便。例如:MCS—51的派生型89C51单片机。
(5) OTP(One Time Programmable)ROM单片机:内部具有一次可编程的程序存储器,用户可以在编程器上将程序写入片内程序存储器中,程序写入后不能再改写。例如:NEC公司的μPD75P308GF—3B9。这种芯片的价格也较低。
4.控制器的组成和作用
答:控制器:由程序计数器、指令寄存器、指令译码器、时序发生器和操作控制器等组成。用来协调指挥计算机系统的操作。
5. 微型计算机组成
答:微型计算机组成由微处理器(CPU)、存储器、接口适配器(I\O接口电路)及输入/输出设备组成。通过系统总线将它们连接起来,以完成某些特定的运算与控制。
6.什么叫寻址方式
答:寻址方式:寻址方式就是寻找指令中操作数或操作数所在地址的方式。也就是如何找到存放操作数的地址,把操作数提取出来的方法。
7. 什么叫堆栈:
答:堆栈是在片内RAM中专门开辟出来的一个区域,数据的存取是以"后进先出"的结构方式处理的。实质上,堆栈就是一个按照"后进先出"原则组织的一段内存区域。
8.什么是汇编语言?什么叫指令周期?
答:汇编:汇编语言源程序在交付计算机执行之前,需要先翻译成目标程序,这个翻译过程叫汇编。
指令周期:指执行一条指令所占用的全部时间。通常一个指令周期含1~4个机器周期。
9.什么是进位和溢出
答:两数运算的结果若没有超出字长的表示范围,则由此产生的进位是自然进位;若两数的运算结果超出了字长的表示范围(即结果不合理),则称为溢出。例如将正数3FH和负数D0H相加,其结果不会超出8位字长的表示范围,所以其结果10FH中的进位是正常进位(也就是模)。但是,若正数3FH与正数70H相加,其结果为AFH,最高位为"1",成了负数的含义,这就不合理了,这种情况称为溢出。
第二章
2-1填空
1..微处器由寄存器、控制器、运算器三部分组成..
2.当MCS-51引脚ALE信号有效时,表示从Po口稳定地送出了低8位地址.
3.MCS-51的堆栈是软件填写堆栈指针临时在_片内数据存储器内开辟的区域.
4.MCS-51中凡字节地址能被_8整除的特殊功能寄存器均能寻址.
5.MCS-51有4组工作寄存器,它们的地址范围是00H~1FH.
6.MCS-51片内20H~2FH范围内的数据存储器,既可以字节寻址又可以位寻址.
7.计算机的系统总线有地址总线、控制总线和数据总线。
8.80C51含4KB ROM。
9.80C51在物理有4个独立的存储空间。
10.一个机器周期等于6个状态周期,振荡脉冲2分频后产生的时钏信号的周期定义为状态 周期。
2-2判断
1.我们所说的计算机实质上是计算机的硬件系统与软件系统的总称。 ( √ )
2.MCS-51的相对转移指令最大负跳距是127B。 ( × )
3.MCS-51的程序存储器只是用来存放程序的。 ( × ) 存放程序和表格常数。
4.MCS-51的时钟最高频率是18MHz. ( × ). 12MHz。
5.使用可编程接口必须处始化。 ( √ )。
6.当MCS-51上电复位时,堆栈指针SP=00H。 ( × )。 SP=07H
7.MCS-51外扩I/O口与外RAM是统一编址的。 ( √ )。
8.使用8751且 =1时,仍可外扩64KB的程序存储器。( × )60KB。
9.8155的复位引脚可与89C51的复位引脚直接相连。( √ )
10.MCS-51是微处理器。( × )不是。
11.MCS-51的串行接口是全双工的。( √ )
12.PC存放的是当前执行的指令。( × )是将要执行的下一条指令的地址。
13.MCS-51的特殊功能寄存器分布在60H~80H地址范围内。(×)80H~FFH。
14.MCS-51系统可以没有复位电路。( × )不可以。复位是单片机的初始化操作。
15.要MCS-51系统中,一个机器周期等于1.5μs。( ×)若晶振频率屡8MHz,才可能为1.5μs
2-3选择
1.要想测理INT0引脚上的一个正脉冲宽度,那么特殊功能寄存器TMOD的内容应为( B ).
(A)09H (B)87 H (C)00H (D)80H
2.PSW=18H时,则当前工作寄存器是( D )
(A)0组 (B)1组 (C)2组 (D)3组
3.控制串行口工作方式的寄存器是( C )
(A)TCON (B)PCON (C)SCON (D)TMOD
4.P1口的每一位能驱动( B )
(A)2个TTL低电平负载有 (B)4个TTL低电平负载
(C)8个TTL低电平负载有 (D)10个TTL低电平负载
5.MCS-51的中断允许触发器内容为83H,CPU将响应的中断请求是( B )
(A) T1, (B)T0,T1 (C)T1,串行接口 (D) ,T0
2-4问答题
1 8051单片机内部包含哪些主要逻辑功能部件?
答:8051单片机是个完整的单片微型计算机。芯片内部包括下列硬件资源:
(1) 8位CPU;
(2) 4KB的片内程序存储器ROM。可寻址64KB程序存储器和64KB外部数据存储器;
(3) 128B内部 RAM;
(4) 21个 SFR;
(5) 4个8位并行I/O口(共32位I/O线);
(6) 一个全双工的异步串行口;
(7) 两个16位定时器/计数器;
(8) 5个中断源,两个中断优先级;
(9) 内部时钟发生器。
2 EA/VPP引脚有何功用?8031的引脚应如何处理?为什么?
答:EA/VPP是双功能引脚,功能如下:
(1)
EA接高电平时,在低4KB程序地址空间(0000H~0FFFH),CPU执行片内程序存储器的指令,当程序地址超出低4KB空间(1000H~FFFFH)时,CPU将自动执行片外程序存储器的指令。
(2)
EA接低电平时,CPU只能执行外部程序存储器的指令。
8031单片机内部无ROM,必须外接程序存储器。因此,8031的EA引脚必须接低电平。
在对8751单片机内部的 EPROM编程时,此引脚VPP外接+12V电压,用于固化EPROM程序。
3 8051单片机存储器的组织结构是怎样的?
答:8051存储器包括程序存储器和数据存储器,从逻辑结构上看,可以分为三个不同的空间:
(1) 64KB的程序存储器地址空间:0000H~FFFFH,其中0000H~0FFFH为片内4KB的ROM地址空间,1000H~FFFFH为外部ROM地址空间;
(2) 256B的内部数据存储器地址空间,00H~FFH,分为两大部分,其中00H~7FH(共128B单元)为内部静态RAM的地址空间,80H~FFH为特殊功能寄存器的地址空间,21个特殊功能寄存器离散地分布在这个区域;
(3) 64KB的外部数据存储器地址空间:0000H~FFFFH,包括扩展I/O地址空间。
4.片内数据存储器分为哪几个性质和用途不同的区域?
答:8051内部128B的数据RAM区,包括有工作寄存器组区、可直接位寻址区和数据缓冲区。各区域的特性如下:
(1) 00H~1FH为工作寄存器组区,共分4组,每组占用8个RAM字节单元,每个单元作为一个工作寄存器,每组的8个单元分别定义为8个工作寄存器R0~R7。当前工作寄存器组的选择是由程序状态字PSW的RS1、RS0两位来确定。如果实际应用中并不需要使用工作寄存器或不需要使用4组工作寄存器,不使用的工作寄存器组的区域仍然可作为一般数据缓冲区使用,用直接寻址或用Ri的寄存器间接寻址来访问。
(2) 20H~2FH为可位寻址区域,这16个字节的每一位都有一个地址,编址为00H~7FH。
当然,位寻址区也可以用作字节寻址的一般数据缓冲区使用。
(3)30H~7FH为堆栈、数据缓冲区。
5 单片机有哪几个特殊功能寄存器?各在单片机的哪些功能部件中?
答:8051单片机内部有21个特殊功能寄存器,在物理上是分散在片内各功能部件中,在数学上把它们组织在内部数据存储器地址空间80H~FFH中,以便能使用统一的直接寻址方式来访问。这些特殊功能寄存器颁在以下各个功能部件中:
(1) CPU:ACC、B、PSW、SP、DPTR(由DPL和DPH两个8位寄存器组成);
(2) 中断系统:IP、IE;
(3) 定时器/计数器:TMOD、TCOM、TL0、TH0、TL1、TH1;
(4) 并行I/O口:P0、P1、P2、P3;
(5) 串行口:SCON、SBUF、PCON。
6 PC是什么寄存器?是否属于特殊功能寄存器?它有什么作用?
答:PC是16位程序计数器(Program Counter),它不属于特殊功能寄存器范畴,程序员不以像访问特殊功能寄存器那样来访问PC。PC是专门用于在CPU取指令期间寻址程序存储器。PC总是保存着下一条要执行的指令的16位地址。通常程序是顺序执行的,在一般情况下,当取出一个指令(更确切地说为一个指令字节)字节后,PC自动加1。如果在执行转移指令、子程序调用/返回指令或中断时,要把转向的地址赋给PC。
7 DPTR是什么寄存器?它由哪些特殊功能寄存器组成?它的主要作用是什么?
答:DPTR是16位数据指针寄存器,它由两个8位特殊功能寄存器DPL(数据指针低8位)和DPH(数据指针高8位)组成,DPTR用于保存16位地址,作间址寄存器用,可寻址外部数据存储器,也可寻址程序存储器。
第三章
3-1选择题
1、MOVX A,@DPTR指令中源操作数的寻址方式是(B)
(A) 寄存器寻址 (B)寄存器间接寻址 (C)直接寻址 (D)立即寻址
1. ORG 0003H
LJMP 2000H
ORG 000BH
LJMP 3000H 当CPU响应外部中断0后,PC的值是(B)
(A) 0003H (B)2000H (C)000BH (D)3000H
2. 执行PUSH ACC指令,MCS-51完成的操作是(A)
(A)
SP+1 SP (ACC) (SP) (B)(ACC) (SP)SP-1 SP
(B)
(C)SP-1 SP (ACC) (SP) (D)(ACC) (SP)SP+1 SP
4、 LCALL指令操作码地址是2000H,执行完相子程序返回指令后,PC=(D)
(C) 2000H (B)2001H (C)2002H (D)2003H
5、51执行完MOV A,#08H后,PSW的一位被置位(D)
(A)(A)C (B)F0 (C)OV (D)P
6、下面条指令将MCS-51的工作寄存器置成3区(B)
(A)MOV PSW,#13H (B)MOV PSW,#18H
(B) SETB PSW.4 CLR PSW.3 (d) SETB PSW.3 CLR PSW.4
7、执行MOVX A,@DPTR指令时,MCS-51产生的控制信号是(C)
(D) /PSEN (B)ALE (C)/RD (D)/WR
8、MOV C,#00H的寻址方式是(A)
(A) 位寻址 (B)直接寻址 (C)立即寻址 (D)寄存器寻址
9、ORG 0000H
AJMP 0040H
ORG 0040H
MOV SP,#00H当执行完左边的程序后,PC的值是(C)
(A) 0040H (B)0041H (C)0042H (D)0043H
10、对程序存储器的读操作,只能使用(D)
(A) MOV指令 (B)PUSH指令 (C)MOVX指令(D)MOVC指令
3-2判断题 。
3. MCS-51的相对转移指令最大负跳距是127B。(错)128B
4. 当MCS-51上电复位时,堆栈指针SP=00H。(SP=07H)( 错 )
5. 调用子程序指令(如:CALL)及返回指令(如:RET)与堆栈有关但与PC无关。(错)子序的转返与PC也有关(PC入栈与出栈)
6. MOV @R1,#80H (对)
5、INC DPTR (对)
6、CLR R0 (错)指令系统中没有。
7、MOV @R1,#80H (对)
8、ANL R1,#0FH (错)
9、ADDC A,C (错)
10、XOR P1,#31H (对)
3-3简答题
1 简述MCS-51汇编语言指令格式。
答:MCS-51汇编语言格式如下:
[标号:]操作码助记符[操作数1] [操作数2] [操作数3][注释]标号是用户定义的符号,其值代表这条指令的地址。操作码助记符是指令系统规定的代表特定指令功能的英文缩写符。每条指令都有操作码记符。指令的操作数最多有3个,也有无操作数的指令。注释字段是用户对程序的说明,便于对程序的阅读和理解。
简答
2 MCS-51指令系统主要有哪几种寻址方式?试举例说明。
答:MCS-51指令操作数主要有以下7种寻址方式:
寻址方式 举例
立即寻址 MOV A,#16
直接寻址 MOV 20H,P1
寄存器寻址 MOV A,R0
寄存器间接寻址 MOVX A, @DPTR
变址寻址 MOVC A, @A+DPRT
相对寻址 SJMP LOOP
位寻址 ANL C,70H
3对访问内部RAM和外部RAM,各应采用哪些寻址方式?
答:对内部RAM的寻址方式有直接寻址、寄存器间接寻址和可对位寻址的位寻址。对外部RAM的寻址方式只能用寄存器R0/R1(8位地址)或DPTR(16位地址)间接寻址。
4设内部RAM(30H)=5AH,(5AH)=40H,(40H)=00H,端口P1=7FH,问执行下列指令后,各有关存储单元(即R0,R1,A,B,P1,30H,40H及5AH单元)的内容如何?
MOV R0,#30H ;R0=30H
MOV A,@R0 ;A=5AH
MOV R1,A ;R1=5AH
MOV B,R1 ;B=5AH
MOV @R1,P1 ;(5AH)=7FH
MOV A,P1 ;A=7FH
MOV 40H,#20H ;(40H)=20H
MOV 30H,40H ;(30H)=20H
解:每一条指令执行后的结果如注释字段所标。最后结果为:R0=30H,R1=5AH,A=7FH,B=5AH,P1=7FH,(30H)=20H,(40H)=20H,(5AH)=7FH。
5 SJMP(短转移)指令和AJMP(绝对转移)指令的主要区别。
前者提供了以SJMP的下一条指令的起始地址为中心的256字节范围的转移(-128~+127),后者的转移目标地址必须在与AJMP的下一条指令的第一字节相同的2KB区的程序储存器中。短转移方便了可重定位编码。SJMP方便了PC可重定位编码,但转移范围小。而ASJMP转移范围大,但存在跳区的限制,AJMP指令只能位于2KB区的最后2个字节处时,才可跳到下一个区去。因此用AJMP指令来代替SJMP指令是有条件的,也就是目标地址必须与它下面的指令存放地址在同一个2KB区域内。
3-4编程题
1 编程将片内RAM30H单元开始的15B的数据传送到片外RAM3000H开始的单元中去。
解:STRAT:MOV R0,#30H
MOV R7,#0FH
MOV DPTR,#3000H
LOOP: MOV A,@R0
MOVX @DPTR,A
INC R0
INC DPTR
DJNZ R7,LOOP
RET
2 片内RAM30H开始的单元中有10B的二进制数,请编程求它们之和(和<256 ).
解 ADDIO:MOV R0,30H
MOV R7,#9
MOV A,@R0
LOOP: INC R0
ADD A,@R0
DJNZ R7,LOOP
MOV 30H,A
RET
3 编一个程序,将累加器中的一个字符从串行接口发送出去.
解 SOUT:MOV SCON,#40H ;设置串行接口为工作方式
MOV TMOD,#20H ;定时器T1工作于模式2
MOV TL1,#0E8H; ;设置波特率为1200b/s
MOV TH1,#0E8H
SETB TR1
MOV SBUF,A
JNB T1,$
CLB T1
RET
4 用查表法编一子程序,将R3中的BCD码转换成ASCII码.
解 MAIN: MOV A,R3 ;待转换的数送A
MOV DPTR,#TAR ;表首地址送DPTR
MOVC A,@A+DPTR ;查ASCII码表
MOV R3,A ;查表结果送R3
RET
TAR DB 30H,31H,32H,33H,34H
DB 35H,36H,37H,38H,39H
5 片内RAM40H开始的单元内有10B二进制数,编程找出其中最大值并存于50H单元中.
解 START: MOV R0,#40H ;数据块首地址送R0
MOV R7,#09H ;比较次数送R7
MOV A,@R0 ;取数送A
LOOP: INC R0
MOV 30H,@R0 ;取数送30H
CJNE A,30H,NEHT ;(A)与(30H)相比
NEXT: JNC BIE1 (A)≥(30H)转BIR1
MOV A,30H ;(A)<(30H),大数送A
BIE1: DJNZ R7,LOOP ;比较次数减1,不为0,继续比较
MOV 50H,A ;比较结束,大数送50H
RET
6 编一子程序,从串行接口接受一个字符.
解: START: MOV TMOD,#20H ;定时器T1工作于模式2
MOV TH1,#0E8H ;设置波特率为1 200b/s
MOV TL1,#0E8H
SETB TR1 ;启动T1
MOV SCON,#50H ;串行接口工作于方式1,充许接收
L1: JNB RI,L1 ;等待接收数据,末接收到数据,继续等待
CLR RI ;接收到数据,清RI
MOV A,SBUF ;接收到数据送A
RET
7 利用调子程序的方法,进行两个无符号数相加。请编主程序及子程序。
解 用R0和R1作数据指针,R0指向第一个加数,并兼作“和”的指针,R1指向另一个加数,字节存放到R2中作计数初值。
主程序:
JAFA: MOV R0,#20H ;指向加数最低字节
MOV R1,#29H ;指向另一加数最低字节
MOV R2,#04H ;字节数作计数值
ACALL JASUB ;调用加法子程序
AJMP $
RTE
多字节加法子程序:
JASUB: CLR C
JASUB1: MOV A,@R0 ;取出加数的一个字节(4B无符号数加数)
ADDC A,@R1 ;加上另一数的一个字节
MOV @R0,A ;保存和数
INC R0 ;指向加数的高位
INC R1 ;指向另一加数的高位
DJNZ R2,JASUB1 ;全部加完了吗?
RET
8 若图数据块是有符号数,求正数个数,编程并注释。
解 ORG 0030H
START: MOV 20H,#00H ;计正数个数计数器
MOV DPTR,#0000H ;
MOVX A,@DPTR ;数据块长度→10H
MOV 10H,A
INC DPTR ;DPTR指向第一个数的地址
TWO: MOVX A,@DPTR ;取数→A
JB ACC.7,ONE ;是负数转ONE,准备取下一个数
INC 20H ;是正数,正数计数器加1
ONE: INC DPTR ;地址指针加1
DJNZ 10H,TW ;数据块长度减1不等于0,继续寻找
RET
9 编制一个循环闪烁灯的程序。有8个发光二极管,每次其中某个灯闪烁点亮10次后,转到下一个闪烁10次,循环不止。画出电路图。
解
P1.0
8013
P1.7
D0 Q0
74LS240
D7 Q7
本程序的硬件连接如图所示。当P1.0输出高电平时,LED灯亮,否则不亮。
其程序如下:
MOV A,#01H ;灯亮初值
SHIFT: LCAIL FLASH ;调闪亮10次子程序
RR A ;右移一位
SJMP SHIFT ;循环
FLASH: MOV R2,#0AH 闪烁10次计数
FLASH1; MOV P1,A ;点亮
LCALL DELAY ;延时
MOV P1,#00H ;熄灭
LCALL DELAY ;延时
DJNZ R2,FLASH1 ;循环
RET
第四章
4-1填空
1.MCS-51的Po口作为输出端口时,每位能驱动 8 个SL型TTL负载.
2.MCS-51有 4个并行I\O口,其中P0~P3是准双向口,所以由输出转输入时必须先写入"1"
3.设计8031系统时,_P0、P2 口不能用作一般I\O口.
4.MCS-51串行接口有4种工作方式,这可在初始化程序中用软件填写特殊功能寄存器__SCON _加以选择.
5.当使用慢速外设时,最佳的传输方式是 中 断 .
6.当定时器To工作在方式3 时,要占定时器T1的TR1和TF1_两个控制位.
7.MCS-51有 5 个中断源,有2 个中断优先级,优先级由软件填写特殊功能寄存器 IP 加以选择..
8.用串口扩并口时,串行接口工作方式应选为方式 0 .
9.在串行通信中,有数据传送方向单工、半双工、全双工三种方式.
10.外部中断 入口地址为_ 0013H
4-2判断
1.MCS-51的5个中断源优先级相同。 ( × )
2.要进行多机通信,MCS-51串行接口的工作方式应为方式1。 ( × )
3.MCS-51上电复位时,SBUF=00H。 ( × )。
4.MCS-51有3个中断源,优先级由软件填写特殊功能寄存器IP加以选择.. ( × )
5.用串口扩并口时,串行接口工作方式应选为方式1. ( × )
6.外部中断INTO 入口地址为_0013H( × )
7.MCS-51外部中断0的入口地址是0003H。 (√ ).
8.TMOD中的GATE=1时,表示由两个信号控制定时器的启停。 ( √ )。
9.使用8751且 =1时,仍可外扩64KB的程序存储器。( × )
10.PC存放的是当前执行的指令。( × )
11.MCS-51的特殊功能寄存器分布在60H~80H地址范围内。(× )
12.MCS-51有4个并行I\O口,其中P0~P3是准双向口,所以由输出转输入时必须先写入"0"( × )
4-3选择
1.在中断服务程序中,至少应有一条( D )
(A)传送指令(B)转移指令(C)加法指法(D)中断返回指令
2.要使MCS-51能够响应定时器T1中断、串行接口中断,它的中断允许寄存器IE的内容应是( A )
(A)98H (B)84H (C)42 (D)22H
3.D MCS-51在响应中断时,下列哪种操作不会发生( D ).
(A)保护现场 (B)保护PC (C)找到中断入口 (D)保护PC转入中断入口
4.用MCS-51串行接口扩展并行I\O口时,串行接口工作方式应选择( C )
(A)方式0 (B)方式1 (C)方式2 (D)方式3
5.MCS-51有中断源( A )
(A)5个 (B)2个 (C)3个 (D)6个
6.MCS-51响应中断时,下面哪一个条件不是必须的( )
(A)当前指令执行完毕 (B)中断是开放的确
(C)没有同级或高级中断服务须 (D)必须有RET1指令
7.使用定时器T1时,有几种工作模式( C )
(A)1种 (B)2种 (C)3种 (D)4种
8.计算机在使用中断方式与外界交换信息时,保护现场的工作方式应该是 ( B )
(A)由CPU自动完成 (B)在中断响应中完成
(C)应由中断服务程序完成 (D)在主程序中完成
9.下面哪一种传送方式适用于处理外部事件( C )
(A)DMA (B)无条件传递进 (C)中断 (D)条件传递
1、2、4章的编程
1. 8225A控制字地址为300FH,请按:A口方式0输入,B口方式1输出,C口高位输出,C口低位输入,确定8225A控制字并编初始化程序.
解:控制字为 10010101=95H
初始化程序:MOV DPTR ,#300FH
MOV A, #95H
MOVX @DPTR, A
2. 编定一个软件延时1S和1min的子程序.设fosc=6Hz,则一个机器周期1μs。
解:(1)1S=2US*5*100000
5*100000=250*200*10
(2) ORG 1000H
TIME: MOV R7, #10
T3: MOV R6, #200
T2: MOV R6, #250
T1: DJNZ R5, T1
DJNZ R6, T2
DJNZ R7, T3
RET
(2)1min=60,调用上面1s子程序60次
ORG 0030H
MOV R0, #60
LOOP: LCALL TIME
DJNZ R0, LOOP
RET
3. 请编制串行通信的数据发送程序,发送片内RAM50H~5FH的16B数据,串行接口设定为方式2,采用偶校验方式。设晶振频率为6MHz。
解:查询方式发送程序如下
MOV SCON, #8OH
M OV PCON, #80H
MOV R0, #50H
MOV R7, #16H
LOOP: MOV A,@R0
MOV C, P
MOV TB8, C
MOV SBUF, A
JNB T1, $
CLR T1
INC R0
DJNZ R7, LOOP
RET
4.应用单片机内部定时器T0工作在方式1下,从P1.0输出周期为2ms的方波脉冲信号,已知单片机的晶振频率为6MHZ。
请(1)计算时间常数X,应用公式X=216-t(f/12)
(2)写出程序清单
解:X=216-t(F/12)
=216-1*10-3*6*106/12
=OFEOCH
ORG 3000H
START: MOV TMOD, #01H
MOV TL0, #OCH
MOV THO, #OFEH
SETB TR0
LOOP: JBC TFO, DONE
SJMP LOOP
DONE: MOV TL0, #OCH
MOV THO, #OFEH
CPL P1.0
SJMP LOOP
5.应用单片机内部定时器T0工作在方式1下,从P1.0输出周期为1ms的方波脉冲信号,已知单片机的晶振频率为6MHZ。
请(1)计算时间常数X,应用公式X=216-t(f/12)
(2)写出程序清单
解:解:X=216-t(F/12)
=216-0.5*10-3*6*106/12
=FF06H
ORG 3000H
START: MOV TMOD, #01H
MOV TL0, #06H
MOV THO, #FFH
SETB TR0
LOOP: JBC TFO, DONE
SJMP LOOP
DONE: MOV TL0, #06H
MOV THO, #FFH
CPL P1.0
SJMP LOOP
6、 用89C51的P1口,监测某一按键开关,使每按键一次,输出一个正脉冲(脉宽随意)。编出汇编语言程序。
解: ORG 0100H
ABC: SETB P1.0
SETB P1.7
JB PI.7, $
JNB P1.7, $
CLR P1.0
MOV R2, #0
DAY: NOP
NOP
DJNZ R2, DAY
SJMP ABC
7、设计一个4位数码显示电路,并用汇编语言编程使"8"从右到左显示一遍。
解: ORG 0100H
MOV A, #08H
MOV R2, #01H
MOV DPTR, #TAB
MOVC A,@A+DPTR
MOV P1, A
NEXT: MOV A, R2
MOV P3, A
ACALL DAY
JB ACC.4, LPD
RL A
MOV R2, A
AJMP NEXT
LPD: RET
TAB: DB
END
8. 编制一个循环闪烁的程序。有8个发光二极管,每次其中某个灯闪烁点亮10次后,转到下一个闪烁10次,循环不止。画出电路图。
解: MOV A,#01H
SHIFT: LCALL FLASH
RR
SJMP SHIFT
FLAH: MOV R2, #0AH
FLAH1: MOV P1, A
LCALL DELAY
MOV P, #00H
LCALL DELAY
DJNZ R2, FLASH1
RET
9.在8051单片机的INTO引脚外接脉冲信号,要求每送来一个脉冲,把30H单元值加1,若30H单元记满则进位31H单元。试利用中断结构,编制一个脉冲计数程序。
解: ORG 0000H
AJMP MAIN
ORG 0003H
AJMP SUBG
MAIN: MOV A, #OOH
MOV 30H, A
MOV 31H, A
MOV SP, #70H
SETB INT0
SETB EA
SETB EX0
AJMP $
ORG 0200H
SUBG: PUSH ACC
INC 30H
MOV A, 30H
JNZ BACK
INC 31H
BACK: POP
RET1
10.利用89C51的P1口控制8个发光俄二极管LED。相邻的4个LED为一组,使2组每隔0。5S 交替发亮一次,周尔复始。试编写程序。
解: ORG 0100H
MOV A, #0FH
ABC: MOV P1, A
ACALL D05
SWAP A
SJMP ABC
D05: MOV R6, 250
DY: MOV R7, 250
DAY: NOP
NOP
DJNZ R6, DAY
DJNZ R7, DAY
RET
END
11.设计89C51和ADC0809的接口,采集2通道10个数据,存入内部RAM的50H~59H单元,画出电路图,编出:
(1)延时方式;
(2)查询方式;
(3)中断方式中的一种程序。
解:IN2的地址为7FFAH,P1.0查询转换结束信号,查询程序如下:
ORG 0100H
MOV R7, #0AH
MOV R0, #50H
MOV DPTR, #7FFAH
NEXT: MOVX @DPTR, A
JB P1.0, $
MOVX A,@DPTR
MOV @R0, A
INC R0
DJNZ NEXT
SJMP $
第五章
5-1选择题
1、6264芯片是(B)
(A) EEPROM (B)RAM(C)FLASH ROM (D)EPROM
2、用MCS-51用串行扩展并行I/O口时,串行接口工作方式选择(A)
(A) 方式0 (B)方式1 (C)方式2 (D)方式3
3、使用8255可以扩展出的I/O口线是(B)
(A) 16根 (B)24根 (C)22根 (D)32根
4、当8031外出扩程序存储器8KB时,需使用EPROM 2716(C)
(A) 2片 (B)3片 (C)4片 (D)5片
5、某种存储器芯片是8KB*4/片,那么它的地址线根线是(C)
(A) 11根 (B)12根 (C)13根 (D)14根
6、MCS-51外扩ROM,RAM和I/O口时,它的数据总线是(A)
(A) P0 (B)P1 (C)P2 (D)P3
7、当使用快速外部设备时,最好使用的输入/输出方式是(C)
(A)中断 (B)条件传送 (C)DMA (D)无条件传送
8、MCS-51的中断源全部编程为同级时,优先级最高的是(D)
(A) INT1 (B)TI (C)串行接口 (D)INT0
9、MCS-51的并行I/O口信息有两种读取方法:一种是读引脚,还有一种是(A)
(A)读锁存器具 (B)读数据库 (C)读A累加器具 (D)读CPU
10、MCS-51的并行I/O口读-改-写操作,是针对该口的(D)
(A)引脚 (B)片选信号 (C)地址线 (D)内部锁存器
5-2判断题 1、MCS-51外扩I/O口与外RAM是统一编址的。(对)
2、使用8751且EA=1时,仍可外扩64KB的程序存储器。(错)60KB
3、8155的复位引脚可与89C51的复位引脚直接相连。(对)
4、片内RAM与外部设备统一编址时,需要专门的输入/输出指令。(错)统一编址的
特点正是无需专门的输入输出指令。
5、8031片内有程序存储器和数据存储器。(错)无程序存储器
6、EPROM的地址线为11条时,能访问的存储空间有4K。(错)2K.
7、8255A内部有3个8位并行口,即A口,B口,C口。(对)
8、8155芯片内具有256B的静态RAM,2个8位和1个6位的可编程并行I/O口,1个14位定时期等常用部件及地址锁存器。(对)
9、在单片机应用系统中,外部设备与外部数据存储器传送数据时,使用MOV指令。(错)用MOVX指令。
10、为了消除按键的抖动,常用的方法有硬件和软件两种方法。(对)
5-3简答题
1 8031的扩展储存器系统中,为什么P0口要接一个8位锁存器,而P2口却不接?
答:这是因为P0口是扩展储存器系统的多路低8位地址和数据总线,在访问外部存储器时,P0口分时用作输出外部储存器低8位地址和传送数据,为了在整个访问外部存储器期间,对外部存储器存在着有效的低8位地址信号,所以P0口需要外接一个地址锁存器。ALE信号就是用来把P0口输出的地址字节锁存在这个外接的锁存器中,再从锁存器输出外部存储器的低8位地址。而P2口只用作扩展存储器系统的高8位地址线,并在整个访问外部存储器期间不变,所以不必外接地址锁存器。
2 在8031扩展系统中,外部程序存储器和数据存储器共用16位地址线和8位数据线,为什么两个存储空间不会发生冲突?
答:这是因为外部程序存储器和外部数据存储器所使用的控制信号不同。对外部程序存储器的选读通是用PSEN控制线,而对外部数据存储器的读/写控制是用RD和WR读、写控制线,所以不会发生地址冲突。
3 8031单片机需要外接程序存储器,实际上它还有多少条I/O线可以用?当使用外部存储器时,还剩下多少条I/O线可用?
答:8031系统必须外接程序促成器,原则上说,P0和P2口要用作数据和地址总线,所以只有P1和P3口可用作I/O口,共16条I/O线。在使用外部存储器时,除了占用P0和P2口外,还需要用P3口RD(P3.7)和WR(P3.6)两条控制线,所以这种情况下就只剩下14条I/O线可用了。
4 试将8031单片机外接一片2716 EPROM和一片6116 RAM组成一个应用系统,请画出硬件连线图,并指出扩展存储器的地址范围。
答:2716是2K×8位的EPROM,6116是2K×8位的静态RAM,两者都仅需要11根地址线。由于没有规定地址范围,故可按最简单的方式来连接,即省去地址译码器,程序存储器的地址必须从0开始,基本地址为0000H—07FFH。数据存储器的地址为0000H—07FFH。控制线的连接为/PSEN控制EPROM的读出,/RD和/WR控制RAM的读写,两个芯片的片选端都固定接地,连线图如图所示。
P2.2
P2.1
P2.0
P0
8031
ALE
/PSEN
/EA
/RD
/WE
5 简述可编程并行接口8255 A的内部结构?
答:8255 A的内部结构由三部分组成:总线接口部分,内部逻辑部分,外部接口部分。
(1) 总线接口部分 其中有数据总线驱动器,读/写控制逻辑
(2) 内部逻辑部分 由A组和B组控制电路。
(3) 外部接口部分 该部分有3个8位并行I/O端口,即A口、B口和C口。
5-4编程题
1 试编程对8155进行初始化,设A口为选通输出,B口为选通输入,C口作为控制联络口,并启动定时器/记数器按方式1工作,工作时间为10ms,定时器计数脉冲频率为单片机的时钟频率24分频,fosc=12MHz。
解:算得初值=5000 =1388H
MOV DPTR,#7F04 ;定时器低八位寄存器地址 DPTR
MOV A,#88H ;低8位初值 A
MOVX @DPTR,A ; 低8位初值 低8位寄存器
INC DPTR ;DPTR指向定时器高8位
MOV A,#13H ;高8位初值 A
MOVX @DPTR,A ;高8位初值 高8位寄存器
MOV DPTR,#7F00H ;8155命令寄存器地址 DPTR
MOV A,0C5H ;命令字 A
MOVX @DPTR,A ;命令字 命令寄存器
2 设单片机采用8051,未扩展片外ROM,片外RAM采用一片6116,编程将其片内ROM从0100H单元开始的10B得内容依次外接到片外RAM从100H单元开始得10B中去。
解: MOV R2,#00H ;源数据缓冲器地址偏移量00H A
MOV R3,#0AH ;字节长度 R3
MOV DPTR,#0100H ;源数据缓冲区首地址 DPTR
MOV A,R2 ;源地址偏移量 A
MOVC A,@A+DPTR ;传送一个数据
MOVX @DPTR,A
INC DPTR ;源地址(目的地址)加1
DJNZ R3,L1 ;数据全部传送完?没传送完,转L1继续传送
SJMP $ ;结束
3 8031扩展8255A,将PA口设置成输入方式,PB口设置成输出方式,PC口设置成输出方式,给出初始化程序。
解: 根据题目要求,A口输入,B口输出,二者均采用工作方式0,则控制字为98H。编程如下:
MOV A,#98H ;方式控制字 A
MOV DPTR,#7FFFH ;选通控制寄存器
MOVX @TPTR,A ;方式控制字送入8255A
MOV DPTR,#7FFCH
MOVX A,@DPTR ;读PA口数据
MOV DPTR,#7FFDH ;
MOVX @DPTR,A ;送PB口数据
4 设计一个2×2行列式键盘电路并编写键盘扫描子程序。
解: (1)2×2行列式键盘电路如图所示。
(2)键盘扫描子程序:
KEY1: ACALL KS1 ;调用判断有无键按下子程序
JNZ LK1 ;有键按下,转LK1
AJMP KEY1 ;无键按下,返回
LK1: ACALL T12MS ;调延时12ms子程序
ACALL KS1 ;查有无键按下
JNZ LK2 ;若有,则为键确实按下,转逐列扫描
AJMP KEY1 ;无键按下,返回
LK2: MOV R4,#00H ;首列号 R4
MOV R2,#FEH ;首列扫描字 R2
LK4: MOV A,R2 ;列扫描字 P1口
MOV P1,A ;使第一列线为0
MOV A,P1 ;读入行状态
JB ACC.0,LONE;第0行无键按下,转查第一行
MOV A,#00H ;第0行有键按下,该行首键号#00H A
AJMP LKP ;转求键号
LONE: JB ACC.1,NEXT ;第一行无键按下,转查下一列
MOV A,#02 ;第一行有键按下,该行首键号#02 A
LKP: ADD A,R4 ;键号=首行号+列号
PUSH ACC ;键号进栈保护
LK3: ACALL KS1 ;等待键释放
JNZ LK3 ;未释放,等待
POP AC ;键释放,键号 A
RET ;键扫描结束
NEXT: INC R4 ;列号加1,指向下一列
MOV A,R2 ;列扫描字 A
JNB ACC.1,KND ;判断2列全扫描完?扫描完,转KND
RL A ;没扫描完,扫描字左移一位,形成下一列扫描字
MOV R2,A ;扫描字 R2
AJMP LK4 ;扫描下一列
AJMP KEY1 ;全扫描完,返回
MOV A,#FCH ;全扫描字11111100B A
MOV P1,A ;全扫描字 所有行
MOV A,P1 ;读取列值
CPL A ;取正逻辑,高电平表示有键按下
ANL A,#0C0H ;屏蔽低6位,取高2位
RET ;出口状态(A)!=0,有键按下
5 要求将存放在8031单片机内部RAM中30H—33H单元的4字节数据,按十六进制(8位)从做到右显示,试编制程序。
ORG 1000H ;指向显示缓冲区
MOV R0,#30H ;显示字节数
MOV R2,#04 ;初始显示位置(最高位)
MOV P1,#08H ;取1B
SDLAY: MOV A,@R0 ;备份
MOV B,A ;截取字节高位
ANL A,#0F0H ;装入P1.4—P1.7
ORL P1,A ;准备显示右一位
INC P1 ;取备份
MOV A,B ;截取字节低位
SWAP A ;
ANL A,#0F0H
ORL P1,A ;装入并显示
INC P1 ;准备显示下一字节
INC R0
DJNZ R2,SDLAY ;4B未显示完循环
RET ;显示完成
END
START:MOV DPTR,#7FFFH
MOV A,#00
LOOP :MOVX @DPTR,A
INC A
MOV R0,#data ;data为延时常数
DJNZ R0,$ ;延时,改变data可改变锯齿波周期T值
SJMP LOOP
例2:产生矩形波
START: MOV DPTR, #7FFFH
STEP: MOV A , #dataH ;置矩形波上限
MOVX @DPTR , A ;D/A转换
ACALL DELH ;调输出“1”时延时
MOV A , #00H ;置矩形波下限
MOVX @DPTR, A
ACALL DELL ;调输出“0”时延时
SJMP STEP ;重复执行
例3: 产生三角波
START: MOV DPTR, #7FFFH
STEP1: MOV A, #00H
STEP2: MOVX @DPTR, A
INC A
CJNE A , #data , STEP2
STEP3: DEC A
MOVX @DPTR , A
CJNE A , #01H , STEP3
AJMP STEP1
相关问答
【 51单片机 的 程序 问题将累加器 A 中低四位的状态,通过P1口的高...[最佳回答]A中有八位数,记为:7654_3210P1中有八位数,记为:8888_9999ANLA,#0FH;屏蔽A.7~A.4---A=0000_3210SWAPA;高、低半字节交换-A=321...
单片机 填空求助1.MCS- 51 系列单片机为()位单片机.2.8051单片...[最佳回答]1.MCS-51系列单片机为(8)位单片机.2.8051单片机有两种复位方式,既上电复位和手动复位.复位后SP=(07H),PC=(0000H),PSW=(00H),P0=(F...
51单片机 的 程序 是怎么制的?51单片机程序是通过编写汇编语言或C语言代码来实现的。首先,需要了解51单片机的指令集和寄存器,以及外设的操作方式。然后,根据设计需求,编写相应的程序代码...
51单片机程序 清单怎么写?51单片机程序清单主要包括以下几个部分:头文件:包含单片机的一些寄存器定义和函数声明。宏定义:定义一些常量或者宏函数,方便程序的编写。全局变量:定义程序...
mcs 51 指令执行过程分为?MCS-51单片机的指令如果按功能划分可以分为五类:1,数据传送类指令:完成数据在单片机内部之间的传送。分为8位数和16位两种。除了奇偶位外,指令的执行对PSW...
51单片机程序 中如何接收信号的?在51单片机程序中,可以通过串口通信来接收外部信号。以下是一些常用的方法:1.使用串口接收函数:在程序中使用串口接收函数(例如USART_Receive())来读取串...
51单片机 没有系统 怎么运行?没有系统就没有办法运行。KeilC51是一款51单片机的开发工具,要运行该工具需要先安装该软件,并连接好相应的单片机开发板。连接好硬件之后,在KeilC51中新建...
51单片机 编程方法?1.定义的变量不要太多。低128位为用户定义变量的存放区域(默认时),也可以把变量放在高128位,但容易出错,尽量少放,最好不放。通过*.M51可以查看内存变量的存...
用C语言写 51单片机 闹钟 程序 - 156****1626 的回答 - 懂得//*********************************************************//实现2113功能:本程序实现在P1口模拟一个流水5261灯程序//******...
C语言写 51单片机程序 ,中断程序应当放哪里?-ZOL问答#include