文章目录
环境安装
要想把程序写入单片机并执行就需要通过某些特定的软件来转化写入
我们所需要的就是两个软件keil_5(负责编写代码)和stc(负责将程序烧录进入单片机)
我的keil是在公众号软件管家上找的上面的各种软件都比较齐全且附带安装方法,安装起来比较快捷;stc则可以去百度上查找下载地址或者在csdn找找大佬的文章。用usb连接单片机时能检测到新的usb端口就可以开始正常烧录程序了,可能会出现连接不正常的情况(这个就需要去找大佬的文章了)。
开始写单片机程序
首先要学会创立项目,且需要根据不同的单片机型号进行选择
如图点击new project,然后选择你要保存文件的地方,再给你的新建工程取一个名字,最好建一个专门放新工程的文件夹,因为会产生其他散乱的文件
>然后在search框搜索AT89C52,我用的时STC89C52但是因为没有所以选择AT,但其实也是可以的,然后点击ok进行下一步。
然后我们要点击这里创建一个c语言编写的环境,然后给程序取个名字,一般取main。
创建完成之后我们需要右击插入头文件,选择创建完成后就可以开始进行代买编写了。
学习实例
LED
点亮一个LED
首先要知道开发板上有很多不同的I/O口,不同I/O可以控制不同的外设,这些I/O口的对应都有相应的规则,我们可以通过查找每块开发板自己的原理图来了解,了解了对应的端口我们才能正确编写程序,原理图一般的原商家都会有,可以直接要。
比如我的开发板使用的就是P1口控制LED,LED是二极管,开发板的VCC端连着二极管的阴极(VCC即高电平端),因此,要想形成通路的话就需要给另一端附上低电平,在单片机中1代表高低电平,0代表低电平,且LED有八个,就需要用两个16进制的数字来表示每个LED的状态。代码实现如下
#include <REGX52.H>
void main()
{
P1=0x55;//0101 0101
}
写好程序之后我们要将文件烧录进单片机,点击下载,重启单片机开关就会发现LED亮了。
LED闪烁
LED闪烁就是利用LED亮灭亮灭的规律进行程序运行
代码示例如下:
#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()
{
P1=0xFE;
P1=0xFF;
while(1)
{
P1=0xFE;
Delay500ms();
P1=0xFF;
Delay500ms();
}
}
这里用到了延迟函数Delay,这是通过stc的软件延时器生成的代码
需要延迟是因为程序执行的速度非常快,要是不延迟肉眼是无法分清它的亮灭,所以我们生成所需的延迟函数然后复制进入程序然后调用,各种设置要和单片机的型号匹配,不然测试结果会出现问题。
LED流水灯
LED流水灯的本质和LED的亮灭一样,只需要一盏灯亮,然后全部灯灭,然后亮起下一盏灯,代码示例如下
#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)
{
P1=0xFE;//1111 1110
Delay500ms();
P1=0xFF;
Delay500ms();
P1=0xFD;//1111 1101
Delay500ms();
P1=0xFF;
Delay500ms();
P1=0xFB;//1111 1011
Delay500ms();
P1=0xFF;
Delay500ms();
P1=0xF7;//1111 0111
Delay500ms();
P1=0xFF;
Delay500ms();
P1=0xEF;//1110 1111
Delay500ms();
P1=0xFF;
Delay500ms();
P1=0xDF;//1101 1111
Delay500ms();
P1=0xFF;
Delay500ms();
P1=0xBF;//1011 1111
Delay500ms();
P1=0xFF;
Delay500ms();
P1=0x7F;//0111 1111
Delay500ms();
P1=0xFF;
Delay500ms();
}
}
独立按键
独立按键控制一盏LED的亮灭
代码示例如下
#include <REGX52.H>
void main()
{
while(1)
{
if(P3_0==0)
{
P1_1=0;
}
else
{
P1_1=1;
}
}
}
由于我的开发板没有独立按键我就使用矩阵按键代替,但效果是一样的。
按键有对应的端口,我的就是P3端口,按键按下的时候就接通,代表低电平,为0,松开就为1.所以实现按键控制用上if语句就可以了
独立按键控制LED的状态
代码实例如下
#include <REGX52.H>
void Delay(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)
{
if(P3_0==0)
{
Delay(20);
while(P3_0==0);
Delay(20);
P1++;
}
}
}
这里的最后测试结果是按下再松手就变化一种状态,用到了两个Delay是为了消抖,while()是用来检测是否松手
独立按键控制LED显示二进制
显示二进制就是利用灯的亮灭来表示0和1,我使用亮来表示1,代码示例如下
#include <REGX52.H>
void Delay(int unsigned xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
P1=0xFF;
while(1)
{
if(P3_0==0)
{
Delay(20);
while(P3_0==0);
Delay(20);
P1--;
}
if(P3_1==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
P1++;
}
}
}
这里就是用了两个按键,一个按下加一,一个按下减一
按键控制LED移位
代码示例如下
#include <REGX52.H>
void Delay(int unsigned xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
P1=0xFE;
while(1)
{
if(P3_0==0)
{
Delay(20);
while(P3_0==0);
Delay(20);
if(P1==0xFE)
{
P1=0x7F;
}
else
{
P1=(~P1)>>1;
P1=~P1;
}
}
if(P3_1==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
if(P1==0x7F)
{
P1=0xFE;
}
else
{
P1=(~P1)<<1;
P1=~P1;
}
}
}
}
数码管的显示
数码管有一位、四位一体等不同的类型,因此引脚的定义也是不同的,每一位都由8个发光二极管组成
每一位的数码管又由三个端口控制
静态数码管显示
代码示例如下
#include <REGX52.H>
unsigned int num[]={0x3F,0x06,0x58,0x4F,0x66,0x6D,0x7D,0x07,0x7F ,0x6F};
void fun(unsigned int loca,number)
{
switch(loca)
{
case 8:P2_2=1;P2_1=1;P2_0=1;
break;
case 7:P2_2=1;P2_1=1;P2_0=0;
break;
case 6: P2_2=1;P2_1=0;P2_0=1;
break;
case 5: P2_2=1;P2_1=0;P2_0=0;
break;
case 4: P2_2=0;P2_1=1;P2_0=1;
break;
case 3: P2_2=0;P2_1=1;P2_0=0;
break;
case 2: P2_2=0;P2_1=0;P2_0=1;
break;
case 1: P2_2=0;P2_1=0;P2_0=0;
break;
}
P0=num[number];
}
void main()
{
while(1)
{
fun(7,9);
}
}
这里提前写好一个数组储存每一位数字显示时的16进制,写进函数直接调用即可,switch用来执行所要显示的位置
动态数码管显示
要显示不同的数字就是利用快速闪烁来使人眼无法分辨,从而达到同时显示的“假象”。
代码示例如下
#include <REGX52.H>
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
unsigned int num[]={0x3F,0x06,0x58,0x4F,0x66,0x6D,0x7D,0x07,0x7F ,0x6F};
void fun(unsigned int location,number)
{
switch(location)
{
case 8:
P2_2=1;
P2_1=1;
P2_0=1;
break;
case 7:
P2_2=1;
P2_1=1;
P2_0=0;
break;
case 6: P2_2=1;P2_1=0;P2_0=1;break;
case 5: P2_2=1;P2_1=0;P2_0=0;break;
case 4: P2_2=0;P2_1=1;P2_0=1;break;
case 3: P2_2=0;P2_1=1;P2_0=0;break;
case 2: P2_2=0;P2_1=0;P2_0=1;break;
case 1: P2_2=0;P2_1=0;P2_0=0;break;
}
P0=num[number];
Delay(1);
P0=0x00;
}
void main()
{
while(1)
{
fun(1,7)
fun(2,8);
fun(3,9);
}
}
这里我们要给函数内部加一个延时,叫做消影,要是没有延时,显示就会位置错乱,因为执行过快,导致上一个段选还没结束就进行到下一个位选,即产生数据错位。