51单片机跑马灯·

51单片机第4章--跑马灯实验

Hugh

Hugh

4158 0

4.1进制转换基础知识

进制实际是一个非常简单易懂的概念,对于初学者来说也很容易上手。我们接触最多的就是十进制了,它的特点为逢十进一,包含0,1,2,3,4,5,6,7,8,9共十个元素。在生活中我们用到的基本都是十进制了,所以大家对它已经非常熟悉并能应用自如,但是在计算机(包括单片机)世界里,所有都是以二进制为基础的。二进制的特点为逢二进一,包含0,1共两个元素。计算机中的数据都是以二进制存储的,这就是我们所说的0,1世界。通常我们讲的32位或64位操作系统这里的位指的就是二进制位数。因为我们实际多用十进制,那么我们在和计算机系统沟通过程中,十进制与二进制之间的转换就变得很重要了。进制之间的转换如下表所示。 二进制转换十进制公式如下: 其中,n表示二进制的位数。 下面我们举个例子来更加直观的说明这个公式: 例如:1101,这是一个4位的二进制数,计算如下, 大家可以利用这个公式计算的结果和上表进行一一对照。 十六进制也是我们常用的进制,它的特点为逢十六进一,包括0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共十六个元素。实际上十六进制是二进制的一种特殊形式,十六进制的1位等价于二进制的4位,在C语言编程中我们常用十六进制来表示二进制数。在实际应用中我们常常该数字之前加一个前缀来表示他的进制:“0b”表示二进制,“0x”表示十六进制。下面我们举例说明: 0b10010010 = 0x92 上面一个八位的二进制数转换为一个两位的十六进制数。二进制的前4位等于十六进制的第1位: 0b1001 = 0x9 二进制数的后4位等于十六进制的第2位: 0b0010 = 0x2 在计算机中,我们通常所说的二进制的1位也叫1bit,8位表示1个字节,也叫1Byte。根据二进制与十六机制的关系,一个2位的十六进制数则可表示1个字节。在运用的过程中牢记0~15的十进制与二进制、十六进制之间的转换关系对于程序的编写有很大的好处。

4.2闪烁LED小灯

怎么让LED小灯闪烁?我们最先想到的办法当然是先让LED小灯点亮,延时一段时间,熄灭LED小灯,再延时一段时间,一直循环上面的步骤就能实现LED小灯的闪烁了。根据第3章的知识我们知道点亮LED的语句为“led0 = 0;”,熄灭LED的语句为“led0 = 1;”。按照第3章介绍我们重新建立一个LED小灯闪烁的工程。程序代码设计如下:

#include<reg52.h> //寄存器声明头文件  
sbit led0 = P1^0; // 位声明,将P1.0管脚声明为led0  
  
void main()  //程序主函数入口,每个C语言程序有且只有一个  
{  
 int i; //变量声明  
 while(1) //循环  
 {  
 led0 = 0; //赋值管脚P1.0为低电平,点亮LED小灯  
 for(i=0;i<5000;i++);//延时一段时间  
 led0 = 1;//熄灭LED小灯  
 for(i=0;i<5000;i++);//再延时一段时间  
 }  
}

4.3 跑马灯设计

在我们的开发板上设计了8个依次排列的LED小灯,让小灯依次点亮和熄灭实现跑马灯的效果是我们这一节的主要内容。

4.3.1硬件设计

8个LED小灯的硬件电路设计原理图如下图所示: 如上图所示,8个LED小灯LED0-LED7的正极和电源VCC之间均串联了一个1K的限流电阻。LED7-LED0的负极与74HC573锁存器的Q0-Q7一一相连接。锁存器74HC573的功能我们这里不详细介绍,把它的D0-D7与Q0-Q7之间看作是电气上一一联通的。由图所示,锁存器的D0-D7和单片机的P1.7-P1.0是一一连接的。因此,LED小灯LED7-LED0的负极与单片机的P1.7~P1.0管脚一一相连,在单片机程序中通过控制P1.7-P1.0管脚的高低电平便可控制8个LED小灯的亮灭。 该实验要实现的功能为:首先点亮LED0,然后延迟一段时间,熄灭LED0,熄灭LED0点亮LED1,延迟一段时间,熄灭LED1点亮LED2,延迟一段时间,一直到熄灭LED6点亮LED7,依照上面的步骤一直循环下去,便实现了一个简单的跑马灯的效果。

4.3.2软件设计

前面我们试验中都是只对P1.0这个管脚进行赋值,来控制LED小灯led0的亮灭。实际在编写程序的过程中我们可以对P1寄存器进行直接赋值来同时控制8个LED小灯。 如上表所示,P1寄存器是一个8位的寄存器,最高位到最低位依次对应的P1.7管脚到P1.0管脚。点亮某个LED小灯的二进制,十六进制赋值如上表所示。例如P1 = 0xFE;表示点亮led0,P1=0x7F;则表示点亮led7。在软件代码设计时,我们想到的第一个方法为依次点亮小灯并延时,代码如下所示。

#include<reg52.h> //加载头文件
int i;

void main()//主函数入口
{
    P1 = 0xFE; //点亮LED0
    for(i=0;i<5000;i++);//延时一段时间
    P1 = 0xFD; //点亮LED1
    for(i=0;i<5000;i++);//延时一段时间
    P1 = 0xFB; //点亮LED2
    for(i=0;i<5000;i++);//延时一段时间
    P1 = 0xF7; //点亮LED3
    for(i=0;i<5000;i++);//延时一段时间
    P1 = 0xEF; //点亮LED4
    for(i=0;i<5000;i++);//延时一段时间
    P1 = 0xDF; //点亮LED5
    for(i=0;i<5000;i++);//延时一段时间
    P1 = 0xBF; //点亮LED6
    for(i=0;i<5000;i++);//延时一段时间
    P1 = 0x7F; //点亮LED7
    for(i=0;i<5000;i++);//延时一段时间
}

我们对代码进行一下小的改进,这个方法这里称之为“左移取反”法,这个方法在很多的应用中都能用到,非常实用。代码如下图所示。

#include<reg52.h> //加载头文件
int i;
int flag=0;
 
void main()//主函数入口
{ 
 P0 = 0xff;
    while(1)
    {
        P1 = ~(0x01<<flag);//P1的值等于1左移flag位后取反,点亮第flag位LED小灯亮
        for(i=0;i<25000;i++);//延时一段时间

        if(flag>=8)   //flag大于7时,置零,从零开始
        {
            flag=0;
        }
        else
        {
            flag++;  //flag累加
        }
    }
}

我们对上面代码进行分析,flag是一个从0到7依次循环的数,P1等于1向左移flag位再取反。当flag等于2时,0b0000,0001左移2位等于0b0000,0100,再取反等于0b1111,1011=0xFB,并赋值给P1,点亮了小灯led2。同理,当flag等于6时,0b0000,0001左移6位等于0b0100,0000,再取反等于0b1011,1111=0xBF并赋值给P1,点亮了小灯led6。flag为其他值时,大家可以进行一一分析。

4.3.3下载验证

将程序通过STC-isp软件下载到单片机,观察8个LED小灯效果与设想的效果是否一致?至此,本章的内容讲解完毕,内容包括进制转换的基础知识、LED小灯闪速程序以及跑马灯的两种程序。大家在动手操作的过程中多多下载到单片机中观察现象,加深印象。

所属系列

从当前文章继续阅读它所在合集中的前后内容。

51单片机 第 4 / 19 篇
查看合集

本专栏C语言开发为基础,旨在深入解析51单片机技术开发,嵌入式C语言编程。 订阅了本专栏您将可以收获的技能: 1. 系统学习 51单片机开发 2. 掌握嵌入式C语言开发流程 3. 深度剖析51单片机工作原理 4. 了解更多嵌入式开发原理、流程 适宜人群: 1. 所有想了解 51单片机开发的人 2. 从事嵌入式开发的工程师 3. 想要了解C语言、单片机等技术之外的内容的人 作为订阅福利,我们建立了微信技术交流群,大家在这里可以认识更多做朋友。需要的朋友加微信:「RYMCU交流1群」。欢迎关注微信公众号「rymcucom」,订阅最新内容。

相关文章

优先推荐同专题、同标签和同作者内容,补足热门文章。

评论 0

登录 后参与评论

评论

成为第一个评论的人