【51单片机】1. 基础点灯大师
1. 新建一个项目集一些基本操作
打开Keli软件,然后:
-
【Project】→【new μVision Project】→选择项目保存位置
-
建议文件名选一些通用的名字,如【Project】
-
左下角选择【Atmel】的【AT89C52】
-
弹出的【是否添加启动文件到文件夹下】,可以选【否】
-
在左侧新建出了一个【Target1】,点击【+】号展开后,我们的代码在【Source Group 1】下写
-
右键【Source Group 1】,选择【Add New Item to Group ‘Source Group 1’】
- 选择【C File】,即C语言文件,命名为【main】
- 三个按钮分别代表编译、编译和建立工程、全部重新编译和建立工程
- 可以修改编辑框中的字体大小
2. 发光二极管(LED)原理
从电路原理图的角度来看,左侧为正极,右侧负极
从实物角度来看:
-
正极内电极小,引脚长
-
负极内电极大,引脚短
若正负极接反,LED是不会亮的
3. 电路板上的发光二极管
-
板子上的原理如上图,右侧是正极,左侧接入单片机
-
由2所知,发光二极管朝向向左,只有右侧为正极,左侧为负极的时候才会亮,右侧VCC为正极
-
左侧单片机的引脚给5V时(高电平)不会亮,因为没有形成从高向低流动的电压差;只有引脚给0V(低电平)时形成电压差才会亮
单片机中,1表示高电平,0表示低电平
知道以上原理后可以写代码
4. 点亮一个LED(点灯大师、嵌入式Hello World)
代码如下所示:
#include <REGX52.H>void main()
{P2 = 0xFE; // 1111 1110
}
分析一下,从板子上可以看到,LED模块对应P20-P27,意思是LED模块连接到单片机的P2引脚,P2由8位(0~7)组成,分别对应这8盏灯
由3分析的原理可知,单片机给低电平的时候,LED才会亮,我们希望点亮第一盏灯,也就是希望点亮的那盏灯的信号给0,其他信号给1
二进制信号1111 1110转换为十六进制就是FE,在C语言代码中就写成P2=0xFE
,0x
开头表示十六进制
这里的P2由#include <REGX52.H>
中定义,这里边给了P2的具体地址:
代码写好后需要编译和生成工程文件,由于keli默认不生成.hex
的文件,需要设置一下:
再次点build(快捷键F7)就会有hex文件
注意:代码中写的0xFE表示1111 1110
,对应板子上从右至左的灯,根据3分析的原理,亮起的应该是D1,了解这个原理后想亮哪盏都可以
5. 烧录流程
单片机连接至电脑,启动单片机(按一下板子上的蓝色按钮),并打开STC-ISP软件,按照以下流程操作:
-
单片机型号选择STC89C52RC/LE52RC
-
串口号一般会自动识别出来,没识别出来就手动选择一下最长的那个(还没识别出来需要检查一下驱动是否安装好)
-
打开程序文件,找到生成的
.hex
结尾的文件 -
在单片机打开的情况下,【点击下载】→【关闭单片机】→【打开单片机】;如果是单片机关闭的情况下,【点击下载】→【打开单片机】就可以
-
显示“操作成功”后表示烧录成功,可以看到红灯亮起
效果如下:
6. LED灯闪烁
让一个LED灯闪烁,代码如下:
#include <REGX52.H>
#include <INTRINS.H>void Delay500ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 4;j = 129;k = 119;do{do{while (--k);} while (--j);} while (--i);
}void main()
{while(1){ P2 = 0xFE;Delay500ms();P2 = 0xFF;Delay500ms();}
}
实际上就是给P2赋予不同的值,一下亮一下灭,由于执行代码的速度很快,中间还需要加上延时0.5s,延时代码的函数通过STC-ISP生成,步骤如下:
效果如下:
7. LED流水灯
知道上面的原理,写LED流水灯也很简单了:),只需要分析出每个灯亮的情况就可以,分别是:
1111 1110 // FE
1111 1101 // FD
1111 1011 // FB
1111 0111 // F7
1110 1111 // EF
1101 1111 // DF
1011 1111 // BF
0111 1111 // 7F
由此可以写出下面的代码:
#include <REGX52.H>
#include <INTRINS.H>void Delay500ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 4;j = 129;k = 119;do{do{while (--k);} while (--j);} while (--i);
}void main()
{while(1){P2 = 0xFE;Delay500ms();P2 = 0xFD;Delay500ms();P2 = 0xFB;Delay500ms();P2 = 0xF7;Delay500ms();P2 = 0xEF;Delay500ms();P2 = 0xDF;Delay500ms();P2 = 0xBF;Delay500ms();P2 = 0x7F;Delay500ms();}
}
效果如下:
8. 指定时长的延时
这个就是一些代码层面的简单改进了,利用STC-ISP生成1ms延时的代码:
void Delay1ms() //@11.0592MHz
{unsigned char i, j;_nop_();i = 2;j = 199;do{while (--j);} while (--i);
}
接着写一个延时指定长度的函数,或者直接改这个Delay1ms的代码也行,我是直接写了一个延时指定长度的函数:
void DelaySpecificTime(unsigned int ms)
{while (ms){Delay1ms();ms--;}
}
就可以实现控制速度的流水灯,只需要简单调整传输给DelaySpecificTime的参数就行,完整代码如下
#include <REGX52.H>
#include <INTRINS.H>void Delay1ms() //@11.0592MHz
{unsigned char i, j;_nop_();i = 2;j = 199;do{while (--j);} while (--i);
}void DelaySpecificTime(unsigned int ms)
{while (ms){Delay1ms();ms--;}
}void main()
{while(1){P2 = 0xFE;DelaySpecificTime(100);P2 = 0xFD;DelaySpecificTime(100);P2 = 0xFB;DelaySpecificTime(100);P2 = 0xF7;DelaySpecificTime(100);P2 = 0xEF;DelaySpecificTime(100);P2 = 0xDF;DelaySpecificTime(100);P2 = 0xBF;DelaySpecificTime(100);P2 = 0x7F;DelaySpecificTime(100);}
}
效果如下: