找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 17343|回复: 1
收起左侧

51单片机流水灯跑马灯程序设计

[复制链接]
ID:101489 发表于 2016-1-3 00:50 | 显示全部楼层 |阅读模式
51单片机流水灯跑马灯程序设计 (STC89C52RC)
本文针对虾米I代单片机开发板

单片机C编程和普通C编程的区别是基于硬件编程。因此,在编程时经常要看电路原理图。

一般用低电平来点亮LED

多看原理图和实物板子,把图记在脑子里,一边回忆图一边写代码。回忆图形是运用右脑的记忆方法。我们不光是学习单片机,还要借这个机会训练右脑。


用STC ISP下载程序到单片机时,先点击"Download/下载"按钮,然后单片机电源慢慢开到on,如果开太快,可能下载不进去。


把单片机正放身前,左下是USB转串口,右上是数码管,LED。

看板子个的LED,从右到左分别是LED2-LED9, 然后看51开发板原理图,LED2-LED9分别通到DB0-DB7。再查DB0-DB7对应的IO口,分别是P0.0到 P0.7. 要点亮LED2,也就是右边第一个LED,一般情况代码如下:
#include <reg52.h>

sbit LED0 = P0^0;
void turnLED()
{
        while(1)
        {
                LED0 = 0;
        }
}

int main(void)                 
{               
        turnLED();

        return 0;
}



但是此开发板因为IO紧张,用74HC138进行了端口复用。必须先设置74HC138,切换到LED2-LED9才能点亮所需LED。

再次查看原理图,8个LED的共阳极和PNP三极管的集电极连接,三极管的基极接到LEDS6,只有LEDS6是低电平时,三极管电路才会导通。查看74HC138的电路,LEDS6对应于74HC138的Y6.

查看74HC138的手册,要Y0-Y7要输出低电平,必须G1=H, G2=L, 要Y6输出低电平,必须C=H, B=H,A=L. 发现此表很有规律,CBA组成三位二进制数,C高位,H表示1. HHL也就是二进制的6, 所以Y6输出低电平。


接下来要找到51单片机开发板上,74HC138和开发板上的IO的对应关系。还是查开发板原理图。
G1=ADDR3=P1.3
G2=ENLED=P1.4
C=ADDR2=P1.2
B=ADDR1=P1.1
A=ADDR0=P1.0


于是我们可以写出下面函数让LEDS6输出低电平(如果你的板子没有用到138译码器,下面代码可以略过):

sbit enableG1 = P1^3;
sbit enableG2 = P1^4;

sbit selectC = P1^2;
sbit selectB = P1^1;
sbit selectA = P1^0;

void hc138()
{
        enableG1 = 1;
        enableG2 = 0;

        selectC = 1;
        selectB = 1;
        selectA = 0;
}


现在,点亮LED2的完整代码如下:


#include <reg52.h>

sbit enableG1 = P1^3;
sbit enableG2 = P1^4;

sbit selectC = P1^2;
sbit selectB = P1^1;
sbit selectA = P1^0;

//74HC138译码器
void hc138()
{
        enableG1 = 1;
        enableG2 = 0;

        selectC = 1;
        selectB = 1;
        selectA = 0;
}

//点亮LED
void turnLED()
{
        while(1)
        {
                P0 = 254;
        }
}

int main(void)                 
{        
        hc138();        
        turnLED();

        return 0;
}

注意,点亮LED2的代码我们写成了P0=254, 这是一次设置1 byte的方法。1 byte最大的数字是255,第1位变成0,就是254了。用16进制赋值更简单: P0 = 0xFE


下面变换些花样,我只给出turnLED函数,其他代码同前:

typedef unsigned char uint8;
typedef unsigned int  uint16;

//6种单片机LED流水灯跑马灯示例代码
void turnLED()
{         
        uint8 i = 0;
        uint16 j = 0;
        while(1)
        {               
                //P0 = 1 << i++; //一熄灭灯从右到左
                //P0 = ~(1 << i++); //一灯从右到左
                //P0 = ~(0x80 >> i++); //一灯从左到右
                //P0 = ~(0xC0 >> i++); //二灯从左到右

                //左右来回振荡
                /*
                P0 = ~(0x80 >> i++); //一灯从左到右
                for(j = 0; j < 33000; j++);        //延时不要太短,以看得更清楚
                if( i == 8 )
                {
                        i -= 2;
                         while(i > 0)
                        {
                                P0 = ~(0x80 >> i--);
                                for(j = 0; j < 33000; j++);        //延时不要太短,以看得更清楚
                        }
                }
                */        
                                                        
                P0 = ~(0x80 >> i++); //一灯从左到右
                for(j = 0; j < 33000; j++);        //延时不要太短,以看得更清楚

                i %= 8;
        }
}

回复

使用道具 举报

ID:68814 发表于 2017-12-9 18:54 | 显示全部楼层
谢谢分享

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表