找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1319|回复: 0
收起左侧

51单片机走马灯设计

[复制链接]
ID:786355 发表于 2020-6-22 10:02 | 显示全部楼层 |阅读模式
用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;
        }
}

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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