从零开始的单片机学习(六)

六、控制第一个外设--LED灯
    1、单片机编程的一般步骤
        a、目标分析:我们的目标是带你两开发板上的LED灯。

        b、原理图分析
            (1)目标器件(LED)工作原理
            (2)相关模块电路连接
            (3)控制线路分析:相关IO端口是那些?

        c、代码编写、编译

        d、下载与调试

    2、原理图与控制方法分析
        a、原理图概况浏览
            (1)目的1:把原理图中相关部分摘录出来重点看
            (2)目的2:把相关部分的原理图关键部分(74HC573芯片)重点看

        b、74HC573芯片介绍
            (1)要知道这个芯片怎么工作就要看它的数据手册
            (2)第一步:找到这个芯片的数据手册
            (3)OE(output enable)、IE(input enable)
            (4)74HC573是一个锁存器,简单来说就是由输入引脚Dx来控制输出引脚Qx(x = 0~7)。OE和IE影响Dx控制Qx
                的结果。
            (5)当OE为L,LE为L的时候74HC573工作在锁存模式,此时Qx的输出被锁存(进入锁存模式前的状态是高电平就一
                直是高电平,是低电平就一直是低电平,这就是锁存),这就是锁存器的作用。
            (6)当OE为L,LE为H时74HC573工作在跟随模式。此时Qx的输出跟随Dx的输入变化而变化。此时逻辑上可以认为
                74HC573是透明的。

        c、硬件原理图分析结论
            (1)原理图开发板默认跳线帽的方式为:OE = L,LE = H,此时74HC573工作在跟随模式下,相当于是透明的。当
                我们接线(接线方式为P0端口和J12用杜邦线连接起来,当然其实也可以和P1或者别的其他端口连接)后,其实
                相当于P0端口和LED正极直接相连了,而LED的负极接地了。
            (2)结论是:P0端口的8个引脚输出高电平时LED则亮;输出低电平时则LED灭。
    
    3、第一个实验:点亮LED
        a、创建工程和文件
            (1)创建空工程
            (2)创建main.c并关联到工程
            (3)模式化书写:头文件包含与main函数外壳

        b、如何用C语言进行IO端口控制
            (1)P0这个符号在C语言代码中的特殊含义
            (2)十六进制数
            (3)位、字节、IO端口、IO口
            (4)硬件连接方式对编程的影响

        c、点亮LED
            (1)点亮八颗LED
            (2)点亮四颗LED
            (3)隔一颗点亮一颗LED
            (4)全部熄灭八颗LED
            (5)实现以上四个功能的代码:
                #include <REGX51.H>        //头文件包含

                void main(void)                //main函数
                {
                    while(1)
                    {
                        //P0 = 0xff;    //P0端口的八个引脚都输出高电平
                        //P0 = 0xf0;    //P0端口的前四个引脚都输出高电平
                        P0 = 0xaa;        //P0端口每隔一个引脚是高电平
                        //P0 = 0x00;    //P0端口的八个引脚都输出低电平
                    }

                }
    
    4、如何让LED闪烁
        a、闪烁的本质含义:亮-延时-灭-延时-亮
            (1)由于人眼睛有视觉暂留,所以亮和灭之间的延时时间选择非常重要
            (2)如果延时时间太短(譬如20ms),这时候上一次灭眼睛还没有反应过来就到了下一次亮,此时你会觉得灯是一直
                亮,此时你会觉得等是一直亮着的。和一直亮着的区别是亮度低一些。但是看不到闪烁。
            (3)延时时间逐渐增大慢慢就能看到闪烁,大到一定程度就可以看到明显的一两一灭了。

        b、单片机如何实现延时
            (1)单片机执行一条语句要一定的时间
            (2)单片机开机后不能休息
            (3)单片机可以“空转”来“浪费时间”

        c、C语言是实现延时
            (1)笨办法:放多条指令实现延时
            (2)正确方法:使用C语言循环语句实现延时

        要求:
            (1)能够用C语言编写一个delay函数,实现一段时间的延时,从而实现LED闪烁即可。
            (2)改变i和j的数值,去实际观察效果然后思考为什么。

        d、LED闪烁的实现代码:
                            #include <REGX51.H>

                            void delay(unsigned int t)    //delay(1);延时1毫秒,晶振:12.000MHz
                            {
                                while(t--)
                                {    //执行一次循环体为1毫秒,传入的参数为几就循环几毫秒
                                    unsigned char i = 2;
                                    unsigned char j = 239;
                                    do
                                    {
                                        while (--j);
                                    } while (--i);
                                }
                            }
                            void main(void)
                            {
                                P0 = 0xff;        //全亮
                                //延时
                                delay(100);
                                P0 = 0x00;            //全灭
                                //延时
                                delay(100);
                            }
    
    5、C语言循环语句学习
        a、while循环
            (1)格式:
                    while (条件)
                    {
                        //循环体, 若干条代码
                    }
            (2)例程:
                    void delay(unsigned int t)
                    {
                        while (t--)
                        {
                            unsigned char i = 2;
                            unsigned char j = 239;
                            while (i--)
                            {
                                while (j--);
                            }
                        }
                    }

        b、for循环
            (1)格式:
                    for (循环初始化;循环条件;循环增量)
                    {
                        循环体
                    }

            (2)例程:
                    void delay(void)
                    {
                        int i;
                        for (i=100; i<0; i--)
                        {
                            for (i=100; j>0; j--)
                            {
                                ;
                            }
                        }
                    }

        c、do-while循环
    
    6、流水灯效果实现1
        a、什么是流水灯:D1~D8LED灯依次亮起,循环这个过程。

        b、流水灯本质分析
            (1)流水灯的本质其实就是不同的亮的状态相互间隔一定时间
            (2)流水灯的第一个状态:0x80(1000 0000);
                       第二个状态:0x40(0100 0000);
                       第三个状态:0x20(0010 0000);
                       第四个状态:0x10(0001 0000);
                       第五个状态:0x08(0000 1000);
                       第六个状态:0x04(0000 0100);
                       第七个状态:0x02(0000 0010);
                       第八个状态:0x01(0000 0001);
            (3)延时时间越长流水灯就流的越慢,越短就流水越快。
            (4)八个状态依次执行完之后,从头开始,其实就是循环。

        c、编程实现流水灯
            (1)分析发现流水灯和闪烁没有什么区别。
            (2)实现代码:
                        #include <REGX51.H>

                        //依次流水灯
                        //unsigned char num[15]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x10,0x20,0x40};
                        //两边靠拢分开流水灯
                        //unsigned char num1[7]={0x81,0x42,0x24,0x18,0x24,0x42,0x81};
                        void delay(unsigned int t)
                        {
                            while(t--)
                            {
                                unsigned char i = 2;
                                unsigned char j = 239;
                                do
                                {
                                    while(--j);
                                }while(--i);
                            }
                        }
                        void main(void)
                        {
                            int i;

                            while(1)
                            {
                                for(i=0; i<7; i++)
                                {
                                    P0 = num1[i];
                                    delay(500);
                                }
                            }
                        }
    
    7、流水灯效果实现2
        a、上节课程序的缺陷分析(老师上节课演示的是将每一个状态都用P0去输出,本人用数组相对来说简便一些)
            (1)功能实现了,但是写的太笨了,如果状态很多程序会很长编写程序就会困难。
            (2)如果要修改流水灯的效果会很繁琐。
            (3)用数组来实现时,一次数组遍历玩进入下一轮遍历的时候会有一次卡顿,观感不好,有待优化。

        b、改进思路:通过变量运算来得到合适的端口输出值
            (1)首先定义变量unsigned char a,初值为0x80(1000 0000)
            (2)每个状态就是a依次右移0~7位
            (3)我们这样就相当于用C语言让单片机自己运算得到每个状态的端口值,而不用自己事先去计算好。这样就简化了
                程序。

        c、C语言位移运算介绍
            (1)C语言中有位移运算符,>>可以右移,<<可以左移。(无符号数移位:移出去的位丢掉了,空出来的位用0补)

        d、编程实现:
                    #include <REGX51.H>

                    void delay(unsigned int t)
                    {
                        while(t--)
                        {
                            unsigned char i = 2;
                            unsigned char j = 239;
                            do
                            {
                                while(--j);
                            }while(--i);
                        }
                    }
                    //通过位移实现左右跑流水灯
                    void main(void)
                    {
                        unsigned char LED = 0x01;
                        int i;
                        while(1)
                        {
                            for(i=0; i<7; i++)
                            {
                                P0 = LED ;
                                LED = LED << 1;
                                delay(100);
                            }
                            for(i=0; i<7; i++)
                            {
                                P0 = LED;
                                LED = LED >> 1;
                                delay(100);
                            }
                        }
                    }
    
    8、跑马灯效果实现
        a、什么是跑马灯
            跑马灯是和流水灯非常像:流水灯是七颗LED灭一颗亮,亮的在移动;而跑马灯是七颗亮,一颗灭,灭的再移动

        b、实现思路分析
                    第一种状态:0111 1111  0x7f
                    第二种状态:1011 1111  0xbf
                    第三种状态:1101 1111  0xdf
                    第四种状态:1110 1111  0xef
                    第五种状态:1111 0111  0xf7
                    第六种状态:1111 1011  0xfb
                    第七种状态:1111 1101  0xfd
                    第八种状态:1111 1110  0xfe

        c、编程实现
            (1)编程实现跑马灯要用两种C语言技巧:左移(右移)、按位取反
            (2)C语言中“~”代表对一个数字按位取反,譬如0111 1111按位取反后变成1000 0000。而1101 1111按位取反
                后变成0010 0000。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值