一、单片机开发软件安装
1.Keil5
(1)百度搜索Keil,打开官网,点击“Downloads”,选择“C51”,填写信息并安装软件。
(2)通过b站up主江协科技《51单片机入门教程-2020版 程序全程纯手打 从零开始入门》视频下方提供的链接进行下载。
2.STC-ISP
(1)百度搜索STC,进入下方链接,下滑找到“STC-ISP下载编程烧录软件”进行安装。
(2)通过b站up主江协科技《51单片机入门教程-2020版 程序全程纯手打 从零开始入门》视频下方提供的链接进行下载。
注意:方法(1)能下载最新版但较为有难度,方法(2)轻松且可以跟着视频一步一步学习。
二、单片机介绍
1.总体概述
单片机(Micro Controller Unit,简称MCU)是了解计算机原理与结构的最佳选择。内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑常用硬件功能,性能与计算机相差甚远,但成本低、体积小、结构简单。
它的任务是信息采集(传感器)、处理(CPU)和硬件设备的控制(电机、LED)。
应用领域广泛,使产品升级换代、冠以“智能型”的形容。
2.不同类型单片机资料获取
打开http://www.stcmcudata.com/,通过Ctrl+F搜索自己的单片机型号从而下载详细资料,由此查看单片机内部结构及各种功能。
三、单片机实例操作
1.准备工作
(1)首先将单片机通过USB插入插口,接着进入上方从江协科技视频下方下载的stc-isp,选择USB to UART Driver中的CH340_CH341,打开ch341ser.exe,单击“安装”。
(2)打开Keil5,选择Project中的New μVision Project,新建一个文件夹专门存放该项目的文件,命名并点击保存。
(3)选择Atmel的AT89C52,单击“OK”,点击“否”。
(4)按左方Target1的加号,右击Source Group1,选择第二个选项,接着选择C File(.c),并命名为main,单击Add。
(5)完成代码的编写后点击下方图标,选择Output,勾选Create HEX File,单击OK,接着按下F7。
(6)打开stc-isp.exe,将单片机型号改为STC89C52RC/LE52RC,选择“打开程序文件”,进入刚才建的文件夹中的Objects文件夹,选择后缀为.hex的程序文件打开,接着点“下载/编程”,按几下单片机的开关直至右方出现如下图所示的“操作成功!”。
2.LED
(1)点亮一个LED
在keil5中输入如下代码。
注意:第一个LED亮翻译为二进制1111 1110,二进制转化为十六进制就是FE(0x表示后面指的是十六进制),依此类推可知要使LED亮应将LED的亮灭翻译为二进制,再转化为十六进制。
#include <REGX52.H>
void main()
{
P2=0xFE;
}
如1中操作可得到如下所示。
二进制0101 0101转化为十六进制55。
若将P2=0xFE;修改为P2=0x55;可得到下图所示。
(2)LED闪烁
通过stc-isp中的软件延时计算器可以得到延时500毫秒的C代码,将代码复制到keil5中。
在keil5中输入如下代码。
#include <REGX52.H>
#include <INTRINS.H>
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;
Delay500ms();
P2=0xFF;
Delay500ms();
}
}
如1中操作可得到如下所示。
LED闪烁
(3)LED流水灯
在keil5中输入如下代码。
#include <REGX52.H>
#include <INTRINS.H>
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;
Delay500ms();
P2=0xFF;
Delay500ms();
P2=0xFD;
Delay500ms();
P2=0xFB;
Delay500ms();
P2=0xF7;
Delay500ms();
P2=0xEF;
Delay500ms();
P2=0xDF;
Delay500ms();
P2=0xBF;
Delay500ms();
}
}
如1中操作可得到如下所示。
LED流水灯
(4)流水灯plus
如果需要延时不同时间,每次都需要打开stc-isp中的软件延时计算器来改变延时时间实在有些麻烦,所以提出以下改进方式使在括号中填入延时时间即可实现延时不同时间。
操作过程:打开stc-isp中的软件延时计算器复制延时1ms的C语言代码,在函数名后的括号加上unsigned int xms,在代码中加入循环使延时xms次1毫秒,当xms=0时循环为假,则跳出循环。
#include <REGX52.H>
void Delay1ms(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
while(1)
{
P2=0xFE;
Delay1ms(800);
P2=0xFF;
Delay1ms(700);
P2=0xFD;
Delay1ms(600);
P2=0xFB;
Delay1ms(500);
P2=0xF7;
Delay1ms(400);
P2=0xEF;
Delay1ms(300);
P2=0xDF;
Delay1ms(200);
P2=0xBF;
Delay1ms(100);
}
}
如1中操作可得到如下所示。
流水灯plus
3.独立按键
(1)控制LED亮灭
在keil5中输入如下代码。
注意:该类型单片机的第一个独立按键对应的是P3_1,第二个独立按键对应的是P3_0。
#include <REGX52.H>
void main()
{
while(1)
{
if(P3_1==0)
{
P2_0=0;
}
else
{
P2_0=1;
}
}
}
如1中操作可得到如下所示。
独立按键控制LED亮灭
(2)控制LED状态
在keil5中输入如下代码。
注意:
(1)按下独立按键时按键会有波动,可能影响单片机的判断,因此需要加入一段程序防止错误判断抖动。
(2)~在单片机语言中表示取反。
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{ i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
while(1)
{
if(P3_1==0)
{
Delay(20);
while(P3_1==0)
{
Delay(20);
}
P2_0=~P2_0;
}
}
}
如1中操作可得到如下所示。
独立按键控制LED亮灭
(3)控制LED显示二进制
在keil5中输入如下代码。
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{ i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
unsigned char LEDNum=0;
while(1)
{
if(P3_1==0)
{
Delay(20);
while(P3_1==0)
{
Delay(20);
}
LEDNum++;
P2=~LEDNum;
}
}
}
如1中操作可得到如下所示。
独立按键控制LED显示二进制
(4)控制LED移位
在keil5中输入如下代码。
注意:<<1表示二进制左移1位,补0;>>1表示二进制右移1位,补0。
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{ i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
unsigned char LEDNum=0;
P2=~0x01;
while(1)
{
if(P3_1==0)
{
Delay(20);
while(P3_1==0)
{
Delay(20);
}
LEDNum++;
if(LEDNum>=8)
{
LEDNum=0;
}
P2=~(0x01<<LEDNum);
}
if(P3_0==0)
{
Delay(20);
while(P3_0==0)
{
Delay(20);
}
if(LEDNum==0)
{
LEDNum=7;
}
else
{
LEDNum--;
}
P2=~(0x01<<LEDNum);
}
}
}
如1中操作可得到如下所示。
独立按键控制LED移位
4.数码管
(1)静态数码管
在keil5中输入如下代码。
#include <REGX52.H>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char location,number)
{
switch(location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[number];
}
void main()
{
Nixie(5,2);
}
如1中操作可得到如下所示。
(2)动态数码管
在keil5中输入如下代码。
#include <REGX52.H>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void Nixie(unsigned char location,number)
{
switch(location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[number];
Delay(1);
P0=0x00;
}
void main()
{
while(1)
{
Nixie(1,1);
// Delay(20);
Nixie(2,2);
// Delay(20);
Nixie(3,3);
// Delay(20);
}
}
如1中操作可得到如下所示。
作业
在keil5输入如下代码。
#include <REGX52.H>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3E,0x40};
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void Nixie(unsigned char location,number)
{
switch(location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[number];
Delay(1);
P0=0x00;
}
void main()
{
unsigned int i=0;
//mode 1
if(P3_1==0)
{
Delay(20);
while(P3_1==0)
{
Delay(20);
}
while(1)
{
Nixie(1,10);
Nixie(2,1);
Nixie(7,0);
Nixie(8,1);
if(P3_0==0||P3_2==0||P3_3==0)
{
break;
}
}
}
//mode 2
if(P3_0==0)
{
Delay(20);
while(P3_0==0)
{
Delay(20);
}
while(P3_0==1)
{
i=0;
for(i=0;i<=2200;i++)
{
Nixie(1,10);
Nixie(2,2);
if(i<2000)
{
Nixie(7,0);
Nixie(8,i/200);
}
else
{
Nixie(7,1);
Nixie(8,0);
}
if(P3_1==0||P3_2==0||P3_3==0)
{
break;
}
}
if(P3_1==0||P3_2==0||P3_3==0)
{
break;
}
}
}
//mode 3
if(P3_2==0)
{
Delay(20);
while(P3_2==0)
{
Delay(20);
}
for(i=0;i<=300;i++)
{
Nixie(1,10);
Nixie(2,3);
Nixie(7,0);
Nixie(8,3);
if(i<150)
{
Nixie(5,11);
Nixie(6,11);
}
else if(i==300)
{
i=0;
}
if(P3_0==0||P3_1==0||P3_3==0)
{
break;
}
}
}
//mode 4
if(P3_3==0)
{
Delay(20);
while(P3_3==0)
{
Delay(20);
}
for(i=0;i<10;)
{
Nixie(1,10);
Nixie(2,4);
Nixie(7,i);
Nixie(8,i);
if(P3_3==0)
{
Delay(20);
while(P3_3==0)
{
Delay(20);
}
i++;
if(i==10)
{
i=0;
}
}
if(P3_0==0||P3_1==0||P3_2==0)
{
break;
}
}
}
}
如1中操作可得到如下所示。
作业