在这里插入代码片从今天起,我可以心无旁骛的准备蓝桥杯了。
首先是对入门阶段的基础知识的复习与巩固,初识单片机的我,先接触到的是流水灯的程序。
我们先看一下51单片机的样板图的一部分:
从中我们可以看出上面有8个LED灯,总共有8个I/o口与这8个LED灯相连,下面,我们来看一个原理图:
在这里面,我们可以看出8个LED 灯的位置。那么问题随之而来,我们如何将这些灯点亮呢?这需要用到数电的知识,数电中的电平特性:指的是电路中两点或几点在相同的阻抗下电量的相对比值。不要看理论这么高深,其实你只需要记住一点就可以解决问题了。数电中只有两种电平:高电平和低电平。而高电平是1,低电平是0.我们给灯一个低电平时,它才会亮。下面我会贴一个程序给大家看一下:
// 点亮一个或多个LED灯
#include<stc15f2k60s2.h>//51单片机的头文件
void main()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序,必须要写。
P00=0;P04=0;P07=0;//让第一个,第五个,第八个灯点亮。
while(1);//这是一个死循环,目的让灯一直亮着
}
我们又会在想能不能让灯闪烁起来,答案是肯定的
。
// LED1闪烁程序
#include<stc15f2k60s2.h>
unsigned int i;
void main()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序
while(1)//让程序一直循环,就能实现闪烁了
{
P00=0;
for(i=0;i<60000;i++);//这个是让灯延时的for循环,才会有灯的闪烁
P00=1;
for(i=0;i<60000;i++);
}
}
我们在来看看简化后的程序,这需要用到单片机和数电的知识。例如:sbit LED 1=P0^0;首先这是对寄存器中未编量的定义;^这个是异或运算,逻辑关系为:必须相同,否则就没有。这样做的好处是:可以自定义变量,在自己忘了输入口时,而不会出错。例程如下:
#include<stc15f2k60s2.h>
sbit LED1=P0^0;
void main()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序
LED1=0;
while(1);
}
这一个灯闪烁太没有意思,那能不能多个灯交替闪烁呢?那也是可以的。
//LED1 LED2 交替闪烁程序
#include<stc15f2k60s2.h>
unsigned int i
void main()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序
while(1)
{
P00=0;
for(i=0;i<60000;i++);
P01=0;P00=1;//程序最关键的部分在这里,需要把第一个灯管了,把第二个灯打开
for(i=0;i<60000;i++);
P01=1;
}
}
那既然叫流水灯,它肯定是可以实现8个灯依次流动的。
//流水灯程序
#include<stc15f2k60s2.h>
unsigned int i;
void main()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序 以后讲
while(1)
{
P00=0;P01=1;P02=1;P03=1;P04=1;P05=1;P06=1;P07=1;
for(i=0;i<60000;i++);
P00=1;P01=0;P02=1;P03=1;P04=1;P05=1;P06=1;P07=1;
for(i=0;i<60000;i++);
P00=1;P01=1;P02=0;P03=1;P04=1;P05=1;P06=1;P07=1;
for(i=0;i<60000;i++);
P00=1;P01=1;P02=1;P03=0;P04=1;P05=1;P06=1;P07=1;
for(i=0;i<60000;i++);
P00=1;P01=1;P02=1;P03=1;P04=0;P05=1;P06=1;P07=1;
for(i=0;i<60000;i++);
P00=1;P01=1;P02=1;P03=1;P04=1;P05=0;P06=1;P07=1;
for(i=0;i<60000;i++);
P00=1;P01=1;P02=1;P03=1;P04=1;P05=1;P06=0;P07=1;
for(i=0;i<60000;i++);
P00=1;P01=1;P02=1;P03=1;P04=1;P05=1;P06=1;P07=0;
for(i=0;i<60000;i++);
}
}
这样写这个程序有些笨拙,我们又要用到数电中的知识,将程序进行简化。在这里我们需要着重掌握二进制与十六进制之间的转换关系。我们看对应的表就能一目了然。
我们可以根据这个图,写程序了。不过我们还需要知道一点,根据原理图,我们知道P0口控制整个LED灯,所以就只用对P0进行赋值就可以了。
我们想打开第一个灯怎么写,按照我刚才的思路:P0=0xFE;这样就打开了第一个灯了。那么后面的这是什么意思呢?F:1111 E:1110 ,这个逻辑顺序为从后往前依次是:P00到P07,P00赋值为0,所以只有一个P00灯被点亮。剩下的依次类推,程序如下:
//流水灯的简洁写法
#include<stc15f2k60s2.h>
unsigned int i;
void main()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序 以后讲
while(1)
{
P0=0XFE;
for(i=0;i<60000;i++);
P0=0XFD;//1111 1101
for(i=0;i<60000;i++);
P0=0XFB;
for(i=0;i<60000;i++);
P0=0XF7;
for(i=0;i<60000;i++);
P0=0XEF; //从这里往后有一个小窍门,剩下的四个灯只需要依照前四段,将后两位颠倒一下即可
for(i=0;i<60000;i++);
P0=0XDF;
for(i=0;i<60000;i++);
P0=0XBF;
for(i=0;i<60000;i++);
P0=0X7F;
for(i=0;i<60000;i++);
}
}
我们还可以讲这个程序在进行简化,只不过这次是将延时的写成一个函数。
例程如下:
//写入延时函数
#include<stc15f2k60s2.h>
void delayms(int ms);
void main()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序 以后讲
while(1)
{
P0=0XFE;
delayms(1000);
P0=0XFD;//1111 1101
delayms(1000);
P0=0XFB;
delayms(1000);
P0=0XF7;
delayms(1000);
P0=0XEF;
delayms(1000);
P0=0XDF;
delayms(1000);
P0=0XBF;
delayms(1000);
P0=0X7F;
delayms(1000);
}
}
void delayms(int ms)//这个函数为固定写法,不理解也没有关系
{
int i,j;
for(i=0;i<ms;i++)
for(j=845;j>0;j--);
}
接下来我们看看有点技术含量的,事实上这个程序还可以简化,这里需要用到数电的知识。~这个是取反符,作用是将二进制数按位取反;<<这个是左移符,作用是依次向左加1。我们先看核心程序:P0=~(1<<num);逻辑顺序为:先向左加一,然后按位取反。举个栗子:原来是0000 0000,左移后为0000 0001,再进行取反为1111 1110,就能让第一个灯亮 了。例程如下:
//流水灯最简板的程序
#include<stc15f2k60s2.h>
void delayms(int ms);
unsigned char num;
void main()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序
while(1)
{
for(num=0;num<8;num++)
{
P0=~(1<<num);//0000 0001 --1111 1110> 0000 0001 -- 0000 0010 --- 1111 1101 逐次向左移动1位
delayms(1000);
}
}
}
void delayms(int ms)
{
int i,j;
for(i=0;i<ms;i++)
for(j=845;j>0;j--);
}