1.STC89C52单片机最小系统:
原理:最右侧电源5V供电,左侧是滤波电容,起到滤波作用(就是说电源过来,会有一定的电源干扰。加上滤波电容,保证电路稳定)。左下角的是晶振电路,晶振的存在保证程序的运行(没有晶振程序是无法运行的,晶振旁边的电容叫做起步电容)左侧上边的去实现复位功能。
晶振:给单片机提供时钟;12M:单片机接收到的频率;
STC(生产公司的简称)89(系列 12T/16T 8051)C(工作电压 电源5.5V-3.8V)52(程序及RAM空间大小);封装类型:PDIP/LQFP/PLCC/PQFP;
VCC代表电源的正极;
D1-D8:LED灯;
2.点亮一个LED
Keil 新建工程 Microchip AT89C52
LED:中文名称:发光二极管;
发光二极管图(右图)中:小的一侧为正极,大的一侧为负极;
电阻的读法:102 前两位是有效数字,第三位是倍率,10 00 表示1K;
473 前两位是倍率 47 000 表示47K; 1001 前三位是有效数字,最后一位是倍率,100 0 表示1K 同理:1002 前三位是有效数字 第四位是倍率,100 00 表示10K;
发光二极管的接线方式:VCC表示正极,右侧安装两个排阻(限流电阻);左侧负极接到芯片引脚上。
0V-5V:5V高电平;0V低电平;
上图所示:单片机如何控制硬件电路执行相应的功能-------(例如控制LED灯的亮灭)
首先:每个单片机中一定存在CPU,一定有寄存器存在,寄存器(寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果)含有8个存储区域;对应寄存器的有相应的驱动器,驱动器直接连接引脚和寄存器,当寄存器收到CPU的指令时,执行相应的功能。例如:CPU发出指令1,输出高电平---5V---LED灭;CPU发出指令0,输出低电平-----0V----LED亮。
单片机识别的是十六进制,所以通常将二进制数转化为十六进制数;
例如:0XFE是十六进制数-------表示二进制下的1111 1110,其中0X是十六进制数的前缀,二进制1111转化为十六进制数是F,二进制1110转化为十六进制数是E;
点亮一个LED灯;低电平0亮灯;
实现单片机亮灭亮灭;低电平0亮;
总结来说:点亮的原则是低电平点亮;1111 1110 就是第一个灯点亮(从右往左);写程序的时候用十六进制位去写,0X表示十六进制位的前缀;后面1-9就是0 1 2 3 4 5 6 7 8 9 ,10是A,11B,12C,13D,14E,15F;
此程序可以保证第一个灯进行闪烁,但是由于闪烁的频率过快,不易观察,所以考虑在每个程序中间加上延迟函数;方便观察;
#include <REGX52.H>//定义头函数P2=0XFE
#include <INTRINS.H>//定义头函数Delay500ms
void Delay500ms()//12.000MHZ晶振
{
unsigned char i,j,k;
_nop_();
i=4;
j=205;
k=187;
do
{
do
{
while(--k);
}
while(--j);
}
while(--i);
}
void main()
{
while(1)
{//保证第一个灯进行循环闪烁
P2=0XFE;//1111 1110
Delay500ms();
P2=0XFF;//1111 1111
Delay500ms();
}
}
其中引用函数Delay500ms表示延迟函数;
在此基础之上,设想进行每个灯都循环闪烁的功能,进行进阶:
#include <REGX52.H>//定义头函数P2=0XFE
#include <INTRINS.H>//定义头函数Delay500ms
void Delay500ms()//12.000MHZ晶振
{
unsigned char i,j,k;
_nop_();
i=4;
j=205;
k=187;
do
{
do
{
while(--k);
}
while(--j);
}
while(--i);
}
void main()
{
while(1)
{//保证每一个灯进行循环闪烁
P2=0XFE;//1111 1110
Delay500ms();
P2=0XFF;//1111 1111
Delay500ms();
P2=0XFD;//1111 1101
Delay500ms();
P2=0XFF;//1111 1111
Delay500ms();
P2=0XFB;//1111 1011
Delay500ms();
P2=0XFF;//1111 1111
Delay500ms();
P2=0XF7;//1111 0111
Delay500ms();
P2=0XFF;//1111 1111
Delay500ms();
P2=0XEF;//1110 1111
Delay500ms();
P2=0XFF;//1111 1111
Delay500ms();
P2=0XDF;//1101 1111
Delay500ms();
P2=0XFF;//1111 1111
Delay500ms();
P2=0XBF;//1011 1111
Delay500ms();
P2=0XFF;//1111 1111
Delay500ms();
P2=0X7F;//0111 1111
Delay500ms();
P2=0XFF;//1111 1111
Delay500ms();
}
}
3.LED流水灯:
需要注意的是:
该程序相对于上面的程序,虽然都是实现8个LED循环闪烁,也就是流水灯,但是上面的程序本身会存在延时熄灭的程序,所以每次循环时,本身会闪烁一次再循环下一个LED灯。
而下述程序,自身之间不存在延时返回程序,本身闪烁状态直接转到下一个LED灯;
#include <REGX52.H>
#include <INTRINS.H>
void Delay500ms()
{
unsigned char i,j,k;
_nop_();
i=4;
j=205;
k=187;
do
{
do
{
while(--k);
}
while(--j);
}
while(--i);
}
void main()
{
while(1)
{
P2=0XFE;//1111 1110
Delay500ms();
P2=0XFD;//1111 1101
Delay500ms();
P2=0XFB;//1111 1011
Delay500ms();
P2=0XF7;//1111 0111
Delay500ms();
P2=0XEF;//1110 1111
Delay500ms();
P2=0XDF;//1101 1111
Delay500ms();
P2=0XBF;//1011 1111
Delay500ms();
P2=0X7F;//0111 1111
Delay500ms();
}
}
实现自定义延迟时间的流水灯:为了防止每次更改流水灯延迟时间之间的麻烦,使用函数自定义每次流水灯延迟的时间;
首先定义单位时间内的流水灯延迟函数:void Delay1ms ; 然后给定形参unsigned int xms 定义无符号整型的延迟时间----Xms ;使用while(xms)循环,只要xms不为0,也就是真,循环往复;但需要注意,每次循环后xms--;
#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int xms)
{
unsigned char i,j;
while(xms)
{
i=2;
j=239;
do
{
while(--j);
}
while(--i);
xms--;
}
}
void main()
{
while(1)
{
P2=0XFE;//1111 1110
Delay1ms(200);
P2=0XFD;//1111 1101
Delay1ms(200);
P2=0XFB;//1111 1011
Delay1ms(200);
P2=0XF7;//1111 0111
Delay1ms(200);
P2=0XEF;//1110 1111
Delay1ms(200);
P2=0XDF;//1101 1111
Delay1ms(200);
P2=0XBF;//1011 1111
Delay1ms(200);
P2=0X7F;//0111 1111
Delay1ms(200);
}
}