参考书目:《单片机原理与接口技术》(朱晓辉 来婷)编著
- 单片机的应用:智能仪表;机电一体化;实时控制;分布式多机系统;人类生活中的应用。
- 单片机的主要发展趋势:CMOS化;低功耗化;低电压化;低噪声与高可靠性。
- 单片机的特点:8051单片机是把CPU、ROM、RAM、I/O口、定时器/计数器、中断功能全集成在一块芯片上。8051的CPU为8位;其片内有振荡器及时钟电路,有32根I/O线,对于外部存储器寻址范围,ROM、RAM各64KB,有2个16位的定时器/计数器,5个中断源,2个中断优先级;全双工串行口;布尔处理器。
- ①振荡周期:指振荡源的周期,若为内部产生方式,为石英晶体的振荡周期。
②时钟周期:为振满周期的2倍,时钟周期=振荡周P1+振荡周期P2。 ③机器周期:一个机器周期含6个时钟周期。 ④指令周期:完成一条指令周期占用的全部时间。 8051的指令周期含1~4个机器周期,其中多数为单周期指令,还有2周期指令和4周期指令。 - 单片机的存储器的特点:采用哈佛结构,程序存储器与数据存储器分开,两者各有一个相互独立的64KB的寻址空间。
- 中断是指CPU在正常运行程序时,由于内部/外部事件或由程序预先安排的事件,引起CPU中断正在运行的程序,而转到为内部/外部事件或为预先安排的事件服务的程序中去,服务完毕,再返回去执行波暂时中断的程序。
- 在单片中一共有5个可以引起中断:两个外部中断,两个计数器/定时器中断,一个串口中断。
- 中断嵌套是指当CPU正在处理某个中断源即正在执行中断服务程序时,会出现先
更高的中断源申请中断,为了使更急的中断源及时得到服务,需要暂时中断当前正在执行的级别较低的中断服务程序,去处理更高级别的中断源,待执行完毕后再返回来执行波中断3的中断服务程序。但中断级别低或更低的中断源不能中断级別高的中断服务。 - 中断源是指任何引起单片机中断的事件,一般一个单片机允许有多个中断源。外部中断0、外部中断1、片内定时器/计数器0、片内定时器/计数器1、片内串行口发送/接收中断。
- 中断服务函数的一般形式:返回值 函数名 interrupt n(using n)。bit不能指定位变量的绝对值,当需要指定位变量的绝对值时,需要用sbit来定义。
内部RAM地址 | | 功能 |
---|
00H | 0区 | 4组通用寄存器R0~R7,也可作RAM使用,R0、R1可位寻址 | 08H | 1区 | | 10H | 2区 | 1FH | 3区 | 20H | 位寻址区00H~7FH | 全部可位寻址,共16个字节,128位 | 2FH | 30H | 数据缓冲区、堆栈区、工作单元 | 只能字节寻址 | 7FH | 80H | 特殊功能寄存器 | 可字节寻址,也可位寻址 | FFH |
中断号 | 中断源 | 入口地址 |
---|
0 | 外部中断0(INT0) | 0003H | 1 | 定时器/计数器0(T0) | 000BH | 2 | 外部中断1(INT1) | 0013H | 3 | 定时器/计数器1(T1) | 001BH | 4 | 串行口中断 | 0023H |
1. 把一个十六进制数转换为压缩的BCD码
#include<reg51.h>
#include<absacc.h>
main()
{ unsigned char data a[5],b;
b=DBYTE[0x30];
a[0]=b/100;
a[1]=b%100/10;
a[2]=b%10;
a[3]=a[1] << 4;
a[4]=a[3] | a[2];
DBYTE[0x20]=a[0];
DBYTE[0x21]=a[4];
while(1);
}
2. 把一个压缩的BCD码转换为十六进制数
#include<reg51.h>
#include<absacc.h>
main()
{
unsigned char data a[3],b;
b=DBYTE[0x30];
a[0]=b>>4;
a[1]=b&0x0F;
a[2]=a[0]*10+a[1];
DBYTE[0x31]=a[2];
while(1);
}
3. 把一个十六进制数转换为ASCII码
#include<reg51.h>
#include<absacc.h>
main()
{ unsigned char a,b,c;
a=DBYTE[0x30];
b=a >> 4;
if(b>9) b=b-10+'A';
else b=b+0x30;
c=a & 0x0F;
if(c>9) c=c-10+'A';
else c=c+0x30;
XBYTE[0x30]=b; XBYTE[0x31]=c;
while(1);
}
4. 把一个ASCII码转换为十六进制数
#include<reg51.h>
#include<absacc.h>
main()
{
unsigned char a,b;
a=DBYTE[0x30];
if(a>=0x30 && a<=0x39)
b=a-0x30;
else if(a>=0x41 && a<=0x46)
b=a-0x41+10;
else if(a>=0x61 && a<=0x66)
b=a-0x61+10;
XBYTE[0x31]=b;
while(1);
}
5. 最小公倍数和最大公约数
#include<reg51.h>
#include<absacc.h>
main()
{ unsigned char a,b,c,d,i,j;
a=DBYTE[0x30]; b=DBYTE[0x31];
c=a*b;
for(i=1;i<=c;i++)
{if((c%i==0)&&(i%b==0)&&(i%a==0))
{DBYTE[0x0A]=i;break;}
else DBYTE[0x0A]=c;}
j=DBYTE[0x0A];
d=c/j;
DBYTE[0x0B]=d;
while(1);
}
6. 实现一个BCD码加法
#include<reg51.h>
#include<absacc.h>
void main()
{
unsigned char a,b,c;
a=DBYTE[0x08];
b=DBYTE[0x09];
c=(a>>4)*10+(a&0x0F)+(b>>4)*10+(b&0x0F);
if(c>100)
{DBYTE[0x0A]=c-100;DBYTE[0x0B]=0x01;}
else DBYTE[0x0A]=c;
while(1);
}
7. 所有偶数的累加和奇数累加和
#include<reg51.h>
#include<absacc.h>
main()
{ unsigned char data a[5],i,sum;
sum=0;
for(i=0;i<5;i++)
{a[i]=DBYTE[0x30+i];
if(!(a[i]&0x01)) {sum=sum+a[i];}
}
DBYTE[0x08]=sum;
while(1);
}
#include<reg51.h>
#include<absacc.h>
main()
{ unsigned char data a[5],i,sum;
sum=0;
for(i=0;i<5;i++)
{a[i]=DBYTE[0x30+i];
if(a[i] & 0x01) {sum=sum+a[i];}
}
DBYTE[0x08]=sum;
while(1);
}
8. 所有偶正数的累加和负数累加和
#include<reg51.h>
#include<absacc.h>
main()
{ unsigned char data a[5],i,sum;
sum=0;
for(i=0;i<5;i++)
{a[i]=DBYTE[0x30+i];
if(a[i]>=0x80) {sum=sum+a[i];}
}
DBYTE[0x08]=sum;
while(1);
}
#include<reg51.h>
#include<absacc.h>
main()
{ unsigned char data a[5],i,sum;
sum=0;
for(i=0;i<5;i++)
{a[i]=DBYTE[0x30+i];
if(a[i]<0x80) {sum=sum+a[i];}
}
DBYTE[0x08]=sum;
while(1);
}
9. 判断是否为素数
#include<reg51.h>
#include<absacc.h>
main()
{
unsigned char a,b,c;
a=DBYTE[0x08];
c=0xFF;
for(b=2;b<a;b++)
{ if(a%b==0)
{c=0;break;}
}
DBYTE[0x09]=c;
while(1);
}
10. 由小到大排序
#include<reg51.h>
#include<absacc.h>
void main()
{ unsigned char data a[10],t;
unsigned char i,j;
for(i=0;i<10;i++)
{a[i]=DBYTE[i+0x30];}
for(i=0;i<9;i++)
{for(j=0;j<9-i;j++)
{if(a[j]>a[j+1])
{t=a[j];a[j]=a[j+1];a[j+1]=t;} }}
for(i=0;i<10;i++)
{DBYTE[i+0x30]=a[i];}
while(1);
}
11. 次数不确定的累加和
#include<reg51.h>
#include<absacc.h>
#include<math.h>
void main()
{ unsigned int sum,i,n,x;
n=DBYTE[0x30];
x=DBYTE[0x31];
sum=0;
for(i=1;i<=n;i++)
{sum=sum+pow(i,x);}
DBYTE[0x35]=sum;
while(1);
}
#include<reg51.h>
#include<absacc.h>
void main()
{ unsigned int sum,i,n;
n=DBYTE[0x30];
sum=0;
for(i=1;i<=n;i++)
{sum=sum+i*i;}
DBYTE[0x35]=sum;
while(1);
}
#include<reg51.h>
#include<absacc.h>
main()
{ unsigned char a,b,i,j,sum;
a=DBYTE[0x30];
sum=0;
for(i=1;i<=a;i++)
{b=1;
for(j=1;j<=i;j++)
{b=j*b;}
sum=sum+b;}
DBYTE[0x31]=sum;
while(1);
}
12. 偶数拆分为两个素数之和
#include<reg51.h>
#include<absacc.h>
#include<math.h>
void main()
{ unsigned char a,b,c,d;
a=DBYTE[0x30];
for(b=3;b<=a/2;b+=2)
{ for(c=2;c<=sqrt(b);c++)
if(b%c==0) break;
if(c>sqrt(b)) d=a-b;
else break;
for(c=2;c<=sqrt(d);c++)
if(d%c==0) break;
if(c>sqrt(d))
{DBYTE[0x31]=b;
DBYTE[0x32]=d;} }
while(1);
}
13. 拆分为四个数的平方和
#include<reg51.h>
#include<absacc.h>
void main()
{ unsigned char a,b,c,d,x;
x=DBYTE[0x30];
for(a=1;a<=x/2;a++)
for(b=0;b<=a;b++)
for(c=0;c<=b;c++)
for(d=0;d<=c;d++)
if(x==a*a+b*b+c*c+d*d)
{ DBYTE[0x20]=a;
DBYTE[0x21]=b;
DBYTE[0x22]=c;
DBYTE[0x23]=d; }
while(1);
}
14.大写字母转换为小写字母,数字则不变
#include<reg51.h>
#include<absacc.h>
main()
{ unsigned char x;
x=DBYTE[0x30];
if(x>=0x30&&x<=0x39) {DBYTE[0x08]=x;}
else {x=x+0x20;}
DBYTE[0x08]=x;
while(1);
}
15.在P1口输出50个矩形脉冲
#include<reg51.h>
#include<absacc.h>
sbit u=P1^4;
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++)
{ u=1;
delay30ms();
u=0;
delay30ms(); }
while(1) ;
}
|