dumon 发表于 2024-2-29 23:05:53

数组的应用——利用数组做个交通灯@32G12K128

数组的应用——利用数组做个交通灯@32G12K128

在1~7集中,学习了数组的应用,因此就萌生了用数组来做个交通灯,利用交通灯切换有规律,用2组IO口搭配for循环,就可以实现东西南北红绿灯的切换了。今天时间太晚,明天还要上班,就先上传下成功的图片和视频,后面再来慢慢介绍编程思路和方法72。



WHX 发表于 2024-3-1 07:55:28

{:4_250:}

wan123456 发表于 2024-3-1 09:33:53

挺厉害的,我当初学数组搞的挺头大的…不过一维数组还是挺好理解的

dumon 发表于 2024-3-1 10:18:53

第1集

先讲下我的动手思路
1.第1步动手前先在纸上写好,我用单片机要实现1个什么样的功能,程序动作的流程是怎么样运转的,我大概用什么样的语句或逻辑去编写这个过程,要先把握这个大的方向。
所以第1步是先将程序流程图画出来,并通过流程图分析,是不是都能实现我想要的功能。——流程图
第2步就是要列好我要用的所有硬件,我准备怎么去分配IO,大概需要多少点位,这样单片机的型号也能算出来哪种能满足我的要求。——规划硬件,分配IO
第3步作为1个实用主义者,不是把程序写得多么花里胡哨,而是用最简单的语句和逻辑把要实现的功能表达清楚,让单片机初学者都能看懂。——编写程序
第4步搭配电路,测试并修改程序。——硬件与功能调试


流程图:
假设有1个十字路口,分为东,南,西,北4个方向的红绿灯,当然先不考虑有左转与直行的单独红绿灯情况,我们只考虑有1个绿灯,绿灯亮就可以左转或直行,右转我们就假设有专用车道吧。
红绿黄灯亮起的时序是,先亮绿灯,绿灯亮起一定时间后熄灭,再是黄灯亮起,黄灯亮完后再是红灯,黄灯在绿灯与红灯之间作一个缓冲。
我写的第一版程序是北、南两个方向绿灯同时亮、西、东两个方向绿灯同时亮,
《时序流程图》
北绿-南绿-西红-东红    延时5S南北绿灯点亮5S,东西红灯5S

北黄-南黄-西红-东红    延时1S南北黄灯点亮1S

北红-南红-西绿-东绿    延时5S南北红灯点亮5S,东西绿灯5S

北红-南红-西黄-东黄    延时1S东西黄灯点亮1S



大概执行4次就可以模拟一次十字路口红绿灯工作情况。
《IO分配》把南北方向红绿黄灯分配为P2口,共6个灯,占用6个IO口
                                                        南                                北                               
                                                红        绿        黄                红        绿        黄        0有效点亮       
                                    P2.7P2.6P2.5P2.4P2.3 P2.2P2.1P2.0        Hex        延时
北绿-南绿-西红-东红                1        1        0        1        1        1        0        1        DD        5
北黄-南黄-西红-东红                1        1        1        0        1        1        1        0        EE        1
北红-南红-西绿-东绿                1        0        1        1        1        0        1        1        BB        5
北红-南红-西黄-东黄                1        0        1        1        1        0        1        1        BB        1
把东西方向红绿黄灯分配为P0口,共6个灯,占用6个IO口


                                                        东                                西                               
                                               红        绿        黄                红        绿        黄        0有效点亮       
                                    P0.7P0.6P0.5P0.4P0.3 P0.2P0.1P0.0        Hex        延时
北绿-南绿-西红-东红                1        0        1        1        1        0        1        1        BB        5
北黄-南黄-西红-东红                1        0        1        1        1        0        1        1        BB        1
北红-南红-西绿-东绿                1        1        0        1        1        1        0        1        DD        5
北红-南红-西黄-东黄                1        1        1        0        1        1        1        0        EE        1


现在想下怎么循环,把P2口编为1个数组,P0口编为1个数组,把P2和P0口同步循环:

u8 NS_LED= {0xDD,0xEE,0xBB,0xBB};                // 南北向,绿,黄,红,红
u8 WE_LED= {0xBB,0xBB,0xDD,0xEE};                // 东西向,红,红,绿,黄
u16 time =         {5000,1000,5000,1000};             // 延时设定,


可以看下上面的程序总共执行4步,用1个循环4次就搞定了。是不是非常简单。

                for(a = 0; a<4; a++)
                {
                        P2 = NS_LED;
                        P0 = WE_LED;
                        b = time;
                        delay_ms(b);
                }




这样的编程等于是说把P口想要执行的动作,提前编辑好在数组里,只能按步就班的顺序执行,并且每一步执行时间还要一样。
当然这只是个最基础的,2个方向绿灯同时亮这是会发生交通事故的,但可以在这个基础上我们引用这个执行思路继续完善红绿灯功能。
完整程序代码在下面。
/*--------------------------------------------------------------------------------------

        1个十字路口交通灯演示:
        分为北、南、西、东4个方向,每个方向有红绿黄3个LED灯,绿灯亮7s后转黄灯亮2s,
        每次只许1个方向变绿灯,工作顺序:
        1.北绿-南红-西红-东红        延时7s        由南往北为绿灯,可左转,直行,右转
        2.北黄-南红-西红-东红        延时2s黄灯亮2s后转红灯
        3.北红-南绿-西红-东红        延时7s        由北往南为绿灯,可左转,直行,右转
        4.北红-南黄-西红-东红        延时2s黄灯亮2s后转红灯
        5.北红-南红-西绿-东红        延时7s        由东往西为绿灯,可左转,直行,右转
        6.北红-南红-西黄-东红        延时2s        黄灯亮2s后转绿灯
        7.北红-南红-西红-东绿        延时7s        由西往东为绿灯,可左转,真行,右转
        8.北红-南红-西红-东黄        延时2s        黄灯亮2s后转到1依次循环。
       
        IO分配:每个IO串联1个4.7K给LED限流电阻
        P2.7        P2.6        P2.5        P2.4        P2.3        P2.2        P2.1        P2.0
        无                南-红        南-绿        南-黄        无                北-红        北-绿        北-黄
       
        P0.7        P0.6        P0.5        P0.4        P0.3        P0.2        P0.1        P0.0
        无                东-红        东-绿        东-黄        无                西-红        西-绿        西-黄                       
       
        编写日期:2024年2月28日                版本:V01        开发者:dumon
        版本更新记录:
        2024-02-28 :        南北方向绿灯同时亮,东西方向绿灯同时亮。

--------------------------------------------------------------------------------------*/

#include <STC32G.H>
#include "comm/stc32_stc8_usb.h"

#define MAIN_Fosc 24000000UL                // 定义1个主时钟为24MHz

// 流水灯相关说明,P2.0~P2.7为共阳极连接,P4.5接三极管基极,为低电平时发射极与基极接通,
// 电流饱合后,发射极到集电极接通,LED得到高电平,P2.0~P2.7输出低电平即可点灯。
sbit ON_LED = P4^5;                // 点灯总开关,三极管是小电流控制大电流的开关
sbit LED_1        = P2^0;                // 流水灯LED1
sbit LED_2        = P2^1;                // 流水灯LED2
sbit LED_3        = P2^2;                // 流水灯LED3
sbit LED_4        = P2^3;                // 流水灯LED4
sbit LED_5        = P2^4;                // 流水灯LED5
sbit LED_6        = P2^5;                // 流水灯LED6
sbit LED_7        = P2^6;                // 流水灯LED7
sbit LED_8        = P2^7;                // 流水灯LED8

// 数码管相关说明,P0.0~P0.7为数码管的8个段码,P1.0,P1.1,P1.3为3个位码,共阴极数码管
// 位码要接低电平、段码接高电平,共阳极数码管位码要接高电平、段码接低电平
sbit DIG_A        = P0^0;                // 数码管段码‘A’
sbit DIG_B        = P0^1;                // 数码管段码‘B’
sbit DIG_C        = P0^2;                // 数码管段码‘C’
sbit DIG_D        = P0^3;                // 数码管段码‘D’
sbit DIG_E        = P0^4;                // 数码管段码‘E’
sbit DIG_F        = P0^5;                // 数码管段码‘F’
sbit DIG_G        = P0^6;                // 数码管段码‘G’
sbit DIG_P        = P0^7;                // 数码管段码‘dP’

sbit SEG_1        = P1^0;                // 第1位数码管位码
sbit SEG_2        = P1^1;                // 第2位数码管位码
sbit SEG_3        = P1^3;                // 第3位数码管位码

// 蜂鸣器参照STC32G实验箱V9.4增加,P5.4输出低电平接三极管基极,同流水灯控制原理,
// 在蜂鸣器负责两端并联反接1个二极管,防止短路
sbit BEEP        = P5^4;                // 蜂鸣器端口

// 数组变量                                                      
u8 NS_LED= {0xDD,0xEE,0xBB,0xBB};                // 绿,黄,红,红
u8 WE_LED= {0xBB,0xBB,0xDD,0xEE};                // 红,红,绿,黄
u16 time =         {5000,1000,5000,1000};

u16 a,b,c,d;                                                                // 循环计数变量       
                                       
void delay_ms(u16 ms)                                                // 自定义延时函数
{
        u16 i;
        do{
                i = MAIN_Fosc/6000;
                while(--i);
        } while(--ms);
}       
void main()
{
        WTST = 1;
        // IO口模式配置
        P0M1 = 0x00;        P0M0 = 0x00;
        P1M1 = 0x00;        P1M0 = 0x00;
        P2M1 = 0x00;        P2M0 = 0x00;
        P3M1 = 0x00;        P3M0 = 0x00;
        P4M1 = 0x00;        P4M0 = 0x00;
        P5M1 = 0x00;        P5M0 = 0x00;
               
        while(1)
        {
                for(a = 0; a<4; a++)
                {
                        P2 = NS_LED;
                        P0 = WE_LED;
                        b = time;
                        delay_ms(b);
                }


               
        }
}

73


xxkj2010 发表于 2024-3-1 13:52:16

新思路,不错!

dumon 发表于 2024-3-3 22:04:09

V2版,更新4个方向,单次只有1个方向亮起绿灯,保证车辆安全。
更新的地方在于蓝色标注的部分。

演示视频如下:83



/*--------------------------------------------------------------------------------------

        1个十字路口交通灯演示:
        分为北、南、西、东4个方向,每个方向有红绿黄3个LED灯,绿灯亮7s后转黄灯亮2s,
        每次只许1个方向变绿灯,工作顺序:
        1.北绿-南红-西红-东红        延时7s        由83南往北为绿灯,可左转,直行,右转
        2.北黄-南红-西红-东红        延时2s黄灯亮2s后转红灯
        3.北红-南绿-西红-东红        延时7s        由北往南为绿灯,可左转,直行,右转
        4.北红-南黄-西红-东红        延时2s黄灯亮2s后转红灯
        5.北红-南红-西绿-东红        延时7s        由东往西为绿灯,可左转,直行,右转
        6.北红-南红-西黄-东红        延时2s        黄灯亮2s后转绿灯
        7.北红-南红-西红-东绿        延时7s        由西往东为绿灯,可左转,真行,右转
        8.北红-南红-西红-东黄        延时2s        黄灯亮2s后转到1依次循环。
       
        IO分配:每个IO串联1个4.7K给LED限流电阻
        P2.7        P2.6        P2.5        P2.4        P2.3        P2.2        P2.1        P2.0
        无                南-红        南-绿        南-黄        无                北-红        北-绿        北-黄
       
        P0.7        P0.6        P0.5        P0.4        P0.3        P0.2        P0.1        P0.0
        无                东-红        东-绿        东-黄        无                西-红        西-绿        西-黄                       
       
        编写日期:2024年2月28日                版本:V01        开发者:dumon
        版本更新记录:
        2024-02-28 :        每个路口方向只亮1个绿灯,不会出现南北,东西2个绿灯同时亮起。

--------------------------------------------------------------------------------------*/

#include <STC32G.H>
#include "comm/stc32_stc8_usb.h"

#define MAIN_Fosc 24000000UL                // 定义1个主时钟为24MHz

// 流水灯相关说明,P2.0~P2.7为共阳极连接,P4.5接三极管基极,为低电平时发射极与基极接通,
// 电流饱合后,发射极到集电极接通,LED得到高电平,P2.0~P2.7输出低电平即可点灯。
sbit ON_LED = P4^5;                // 点灯总开关,三极管是小电流控制大电流的开关
sbit LED_1        = P2^0;                // 流水灯LED1
sbit LED_2        = P2^1;                // 流水灯LED2
sbit LED_3        = P2^2;                // 流水灯LED3
sbit LED_4        = P2^3;                // 流水灯LED4
sbit LED_5        = P2^4;                // 流水灯LED5
sbit LED_6        = P2^5;                // 流水灯LED6
sbit LED_7        = P2^6;                // 流水灯LED7
sbit LED_8        = P2^7;                // 流水灯LED8

// 数码管相关说明,P0.0~P0.7为数码管的8个段码,P1.0,P1.1,P1.3为3个位码,共阴极数码管
// 位码要接低电平、段码接高电平,共阳极数码管位码要接高电平、段码接低电平
sbit DIG_A        = P0^0;                // 数码管段码‘A’
sbit DIG_B        = P0^1;                // 数码管段码‘B’
sbit DIG_C        = P0^2;                // 数码管段码‘C’
sbit DIG_D        = P0^3;                // 数码管段码‘D’
sbit DIG_E        = P0^4;                // 数码管段码‘E’
sbit DIG_F        = P0^5;                // 数码管段码‘F’
sbit DIG_G        = P0^6;                // 数码管段码‘G’
sbit DIG_P        = P0^7;                // 数码管段码‘dP’

sbit SEG_1        = P1^0;                // 第1位数码管位码
sbit SEG_2        = P1^1;                // 第2位数码管位码
sbit SEG_3        = P1^3;                // 第3位数码管位码

// 蜂鸣器参照STC32G实验箱V9.4增加,P5.4输出低电平接三极管基极,同流水灯控制原理,
// 在蜂鸣器负责两端并联反接1个二极管,防止短路
sbit BEEP        = P5^4;                // 蜂鸣器端口

// 数组变量                                                      
<font color="#0000ff">u8 NS_LED= {0xBD,0xBE,0xDB,0xEB,0xBB,0xBB,0xBB,0xBB};                // 南北方向红绿灯为1个数组
u8 WE_LED= {0xBB,0xBB,0xBB,0xBB,0xBD,0xBE,0xDB,0xEB};                // 东西方向红绿灯为1个数组
u16 time =         {7000,2000,7000,2000,7000,2000,7000,2000};                // 延时</font>

u16 a,b,c,d;                                                                // 循环计数变量       
                                       
void delay_ms(u16 ms)                                                // 自定义延时函数
{
        u16 i;
        do{
                i = MAIN_Fosc/6000;
                while(--i);
        } while(--ms);
}       
void main()
{
        WTST = 1;
        // IO口模式配置
        P0M1 = 0x00;        P0M0 = 0x00;
        P1M1 = 0x00;        P1M0 = 0x00;
        P2M1 = 0x00;        P2M0 = 0x00;
        P3M1 = 0x00;        P3M0 = 0x00;
        P4M1 = 0x00;        P4M0 = 0x00;
        P5M1 = 0x00;        P5M0 = 0x00;       
       
        while(1)
        {
                // 根据红绿灯运行时序,制作1个循环完成动作演示。
                for(a = 0; a<8; a++)
                {
                        P2 = NS_LED;
                        P0 = WE_LED;
                        delay_ms(time);
                }               
        }
}


dumon 发表于 2024-3-4 14:00:00

V3版,由绿灯转为黄灯时,黄灯为闪烁状况,黄灯闪烁后切为红灯。


注意,分别增加了4个自定义函数用来控制东、西、南、北的黄灯闪烁。何时执行则由在for循环里当a=奇数值判定执行。

请看具体语句内容。

void Northyellow_Blinker(u16 ms,u16 times) 这里定义了2个参数,ms为闪烁间隔,times为闪烁次数。通过调整这2个参数就可以控制黄灯闪烁频率和次数。定义4个不同函数则可以将东西南北4个黄灯设定不同的闪烁频率与次数,做到区别化。



那简单了,怎么让黄灯闪烁起来,不就是第6集里面最简单的点灯吗,先将黄灯的Pn.n口赋0值,延时ms后,再将Pn.n口赋1值,再延时ms,不就闪烁起来了。


这样是不是一步步接近现实生活中红绿灯的工作状态了。

/*--------------------------------------------------------------------------------------

        1个十字路口交通灯演示:
        分为北、南、西、东4个方向,每个方向有红绿黄3个LED灯,绿灯亮7s后转黄灯亮2s,
        每次只许1个方向变绿灯,让“黄灯闪烁起来”,工作顺序:
        1.北绿-南红-西红-东红        延时7s        由南往北为绿灯,可左转,直行,右转
        2.北黄-南红-西红-东红        延时2s黄灯亮2s后转红灯
        3.北红-南绿-西红-东红        延时7s        由北往南为绿灯,可左转,直行,右转
        4.北红-南黄-西红-东红        延时2s黄灯亮2s后转红灯
        5.北红-南红-西绿-东红        延时7s        由东往西为绿灯,可左转,直行,右转
        6.北红-南红-西黄-东红        延时2s        黄灯亮2s后转绿灯
        7.北红-南红-西红-东绿        延时7s        由西往东为绿灯,可左转,直行,右转
        8.北红-南红-西红-东黄        延时2s        黄灯亮2s后转到1依次循环。
                                       
        编写日期:2024年2月28日                版本:V01        开发者:dumon
        IO分配:每个IO串联1个4.7K给LED限流电阻
        P2.7        P2.6        P2.5        P2.4        P2.3        P2.2        P2.1        P2.0
        无                南-红        南-绿        南-黄        无                北-红        北-绿        北-黄
       
        P0.7        P0.6        P0.5        P0.4        P0.3        P0.2        P0.1        P0.0
        无                东-红        东-绿        东-黄        无                西-红        西-绿        西-黄                       
       
        编写日期:2024年2月28日                版本:V02        开发者:dumon
        版本更新记录:
        2024-02-28 :        每个路口方向只亮1个绿灯,不会出现南北,东西2个绿灯同时亮起。
        2024-02-28 :        绿灯转黄灯,黄灯会闪烁后再切换为红灯。

--------------------------------------------------------------------------------------*/

#include <STC32G.H>
#include "comm/stc32_stc8_usb.h"

#define MAIN_Fosc 24000000UL                // 定义1个主时钟为24MHz

// 流水灯相关说明,P2.0~P2.7为共阳极连接,P4.5接三极管基极,为低电平时发射极与基极接通,
// 电流饱合后,发射极到集电极接通,LED得到高电平,P2.0~P2.7输出低电平即可点灯。
sbit ON_LED = P4^5;                // 点灯总开关,三极管是小电流控制大电流的开关
sbit LED_1        = P2^0;                // 流水灯LED1
sbit LED_2        = P2^1;                // 流水灯LED2
sbit LED_3        = P2^2;                // 流水灯LED3
sbit LED_4        = P2^3;                // 流水灯LED4
sbit LED_5        = P2^4;                // 流水灯LED5
sbit LED_6        = P2^5;                // 流水灯LED6
sbit LED_7        = P2^6;                // 流水灯LED7
sbit LED_8        = P2^7;                // 流水灯LED8

// 数码管相关说明,P0.0~P0.7为数码管的8个段码,P1.0,P1.1,P1.3为3个位码,共阴极数码管
// 位码要接低电平、段码接高电平,共阳极数码管位码要接高电平、段码接低电平
sbit DIG_A        = P0^0;                // 数码管段码‘A’
sbit DIG_B        = P0^1;                // 数码管段码‘B’
sbit DIG_C        = P0^2;                // 数码管段码‘C’
sbit DIG_D        = P0^3;                // 数码管段码‘D’
sbit DIG_E        = P0^4;                // 数码管段码‘E’
sbit DIG_F        = P0^5;                // 数码管段码‘F’
sbit DIG_G        = P0^6;                // 数码管段码‘G’
sbit DIG_P        = P0^7;                // 数码管段码‘dP’

sbit SEG_1        = P1^0;                // 第1位数码管位码
sbit SEG_2        = P1^1;                // 第2位数码管位码
sbit SEG_3        = P1^3;                // 第3位数码管位码

// 蜂鸣器参照STC32G实验箱V9.4增加,P5.4输出低电平接三极管基极,同流水灯控制原理,
// 在蜂鸣器负责两端并联反接1个二极管,防止短路
sbit BEEP        = P5^4;                // 蜂鸣器端口

// 数组变量                                                      
u8 NS_LED= {0xBD,0xBE,0xDB,0xEB,0xBB,0xBB,0xBB,0xBB};                // 南北方向红绿灯为1个数组
u8 WE_LED= {0xBB,0xBB,0xBB,0xBB,0xBD,0xBE,0xDB,0xEB};                // 东西方向红绿灯为1个数组
u16 time =         {10000,20,10000,20,10000,20,10000,20};                // 延时,time,time,time,time的时间缩短,主要由闪烁函数来执行。

u16 a,b,c,d;                                                                // 循环计数变量       
                                       
void delay_ms(u16 ms)                                                // 自定义延时函数
{
        u16 i;
        do{
                i = MAIN_Fosc/6000;
                while(--i);
        } while(--ms);
}

void Northyellow_Blinker(u16 ms,u16 times)// 定义北向黄灯闪烁频率与次数
{
        for(c=0; c<times; c++)
        {
                P2 = 0xBE;
                delay_ms(ms);
                P2 = 0xBF;
                delay_ms(ms);
        }
}

void Southyellow_Blinker(u16 ms,u16 times) // 定义南向黄灯闪烁频率与次数
{
        for(c=0; c<times; c++)
        {
                P2 = 0xEB;
                delay_ms(ms);
                P2 = 0xFB;
                delay_ms(ms);
        }
}

void Westyellow_Blinker(u16 ms,u16 times) // 定义西向黄灯闪烁频率与次数
{
        for(c=0; c<times; c++)
        {
                P0 = 0xBE;
                delay_ms(ms);
                P0 = 0xBF;
                delay_ms(ms);
        }
}

void Eastyellow_Blinker(u16 ms,u16 times) // 定义东向黄灯闪烁频率与次数
{
        for(c=0; c<times; c++)
        {
                P0 = 0xEB;
                delay_ms(ms);
                P0 = 0xFB;
                delay_ms(ms);
        }
}

void main()
{
        WTST = 1;
        // IO口模式配置
        P0M1 = 0x00;        P0M0 = 0x00;
        P1M1 = 0x00;        P1M0 = 0x00;
        P2M1 = 0x00;        P2M0 = 0x00;
        P3M1 = 0x00;        P3M0 = 0x00;
        P4M1 = 0x00;        P4M0 = 0x00;
        P5M1 = 0x00;        P5M0 = 0x00;       
       
        while(1)
        {
                // 根据红绿灯运行时序,制作1个循环完成动作演示。
                for(a = 0; a<8; a++)
                {
                        P2 = NS_LED;
                        P0 = WE_LED;       
                        delay_ms(time);
                        if(a == 1)// 执行北向黄灯闪烁函数
                        {
                                Northyellow_Blinker(500,5);
                        }
                        if(a == 3)// 执行南向黄灯闪烁函数
                        {
                                Southyellow_Blinker(500,5);
                        }
                        if(a == 5)// 执行西向黄灯闪烁函数
                        {
                                Westyellow_Blinker(500,5);
                        }
                        if(a == 7)// 执行东向黄灯闪烁函数
                        {
                                Eastyellow_Blinker(500,5);
                        }


                }               
        }
}

dumon 发表于 2024-3-4 14:20:07

补充下图表说明:

蓝底白字填充部分是黄灯状态,想让哪个黄灯闪烁就将其状态由0改为1并循环几次就能达到闪烁显示效果。

参照图片,比照下面语句就能理解了。

void Northyellow_Blinker(u16 ms,u16 times)        // 定义北向黄灯闪烁频率与次数
{
        for(c=0; c<times; c++)
        {
                P2 = 0xBE;
                delay_ms(ms);
                P2 = 0xBF;
                delay_ms(ms);
        }
}

咫尺天涯 发表于 2024-3-4 20:30:09

学习了

dumon 发表于 2024-3-5 10:12:48

V4 版,增加黄灯与红灯一起闪烁,比如当前北向是黄灯,南向是红灯,则让北向黄灯与南向红灯一起闪烁,用于提示下面哪个路口是绿灯。并且闪烁的时候增加蜂鸣器短响。

也许你跟我用的开发板不一样,分配来执行的P口也不一样,所以不要完全照搬我的程序,但是可以参照我的思路。

STC8H,STC32F,STC32G可以把工程复制过来,确认好用的头文件就可以。

84



/*--------------------------------------------------------------------------------------

        1个十字路口交通灯演示:
        分为北、南、西、东4个方向,每个方向有红绿黄3个LED灯,绿灯亮7s后转黄灯亮2s,
        每次只许1个方向变绿灯,让“黄灯闪烁起来”,工作顺序:
        1.北绿-南红-西红-东红        延时7s        由南往北为绿灯,可左转,直行,右转
        2.北黄-南红-西红-东红        延时2s黄灯亮2s后转红灯
        3.北红-南绿-西红-东红        延时7s        由北往南为绿灯,可左转,直行,右转
        4.北红-南黄-西红-东红        延时2s黄灯亮2s后转红灯
        5.北红-南红-西绿-东红        延时7s        由东往西为绿灯,可左转,直行,右转
        6.北红-南红-西黄-东红        延时2s        黄灯亮2s后转绿灯
        7.北红-南红-西红-东绿        延时7s        由西往东为绿灯,可左转,直行,右转
        8.北红-南红-西红-东黄        延时2s        黄灯亮2s后转到1依次循环。
       
        IO分配:每个IO串联1个4.7K给LED限流电阻
        P2.7        P2.6        P2.5        P2.4        P2.3        P2.2        P2.1        P2.0
        无                南-红        南-绿        南-黄        无                北-红        北-绿        北-黄
       
        P0.7        P0.6        P0.5        P0.4        P0.3        P0.2        P0.1        P0.0
        无                东-红        东-绿        东-黄        无                西-红        西-绿        西-黄                       
       
        编写日期:2024年2月28日                版本:V03        开发者:dumon
        版本更新记录:
        2024-02-28 :        每个路口方向只亮1个绿灯,不会出现南北,东西2个绿灯同时亮起。
        2024-02-28 :        绿灯转黄灯,黄灯会闪烁后再切换为黄灯。
        2024-02-28 :        增加黄灯与红灯一起闪烁,北黄与南红一起闪,南黄与西红一起闪,西黄与东红一起闪
                                        北红与东黄一起闪。或者理解为黄灯与下个要切换绿灯的灯一起闪,并且闪烁的时候增加蜂鸣器短响。

--------------------------------------------------------------------------------------*/

#include <STC32G.H>
#include "comm/stc32_stc8_usb.h"

#define MAIN_Fosc 24000000UL                // 定义1个主时钟为24MHz

// 流水灯相关说明,P2.0~P2.7为共阳极连接,P4.5接三极管基极,为低电平时发射极与基极接通,
// 电流饱合后,发射极到集电极接通,LED得到高电平,P2.0~P2.7输出低电平即可点灯。
sbit ON_LED = P4^5;                // 点灯总开关,三极管是小电流控制大电流的开关
sbit LED_1        = P2^0;                // 流水灯LED1
sbit LED_2        = P2^1;                // 流水灯LED2
sbit LED_3        = P2^2;                // 流水灯LED3
sbit LED_4        = P2^3;                // 流水灯LED4
sbit LED_5        = P2^4;                // 流水灯LED5
sbit LED_6        = P2^5;                // 流水灯LED6
sbit LED_7        = P2^6;                // 流水灯LED7
sbit LED_8        = P2^7;                // 流水灯LED8

// 数码管相关说明,P0.0~P0.7为数码管的8个段码,P1.0,P1.1,P1.3为3个位码,共阴极数码管
// 位码要接低电平、段码接高电平,共阳极数码管位码要接高电平、段码接低电平
sbit DIG_A        = P0^0;                // 数码管段码‘A’
sbit DIG_B        = P0^1;                // 数码管段码‘B’
sbit DIG_C        = P0^2;                // 数码管段码‘C’
sbit DIG_D        = P0^3;                // 数码管段码‘D’
sbit DIG_E        = P0^4;                // 数码管段码‘E’
sbit DIG_F        = P0^5;                // 数码管段码‘F’
sbit DIG_G        = P0^6;                // 数码管段码‘G’
sbit DIG_P        = P0^7;                // 数码管段码‘dP’

sbit SEG_1        = P1^0;                // 第1位数码管位码
sbit SEG_2        = P1^1;                // 第2位数码管位码
sbit SEG_3        = P1^3;                // 第3位数码管位码

// 蜂鸣器参照STC32G实验箱V9.4增加,P5.4输出低电平接三极管基极,同流水灯控制原理,
// 在蜂鸣器负责两端并联反接1个二极管,防止短路
sbit BEEP        = P5^4;                // 蜂鸣器端口

// 数组变量                                                      
u8 NS_LED= {0xBD,0xBE,0xDB,0xEB,0xBB,0xBB,0xBB,0xBB};                // 南北方向红绿灯为1个数组
u8 WE_LED= {0xBB,0xBB,0xBB,0xBB,0xBD,0xBE,0xDB,0xEB};                // 东西方向红绿灯为1个数组
u16 time =         {10000,20,10000,20,10000,20,10000,20};                // 延时

u16 a,b,c,d;                                                                // 循环计数变量       
                                       
void delay_ms(u16 ms)                                                // 自定义延时函数
{
        u16 i;
        do{
                i = MAIN_Fosc/6000;
                while(--i);
        } while(--ms);
}

void Northyellow_Blinker(u16 ms,u16 times)        // 北黄和南红一起闪
{
        for(c=0; c<times; c++)
        {
                P2 = 0xBE;
                delay_ms(ms);
                BEEP = 0;
                delay_ms(3);
                BEEP = 1;
                delay_ms(3);
                P2 = 0xFF;
                delay_ms(ms);
               
        }
}

void Southyellow_Blinker(u16 ms,u16 times)        // 南黄和西红一起闪
{
        for(c=0; c<times; c++)
        {
                P2 = 0xEB;
                P0 = 0xBB;
                delay_ms(ms);
                BEEP = 0;
                delay_ms(3);
                BEEP = 1;
                delay_ms(3);
                P2 = 0xFB;
                P0 = 0xBF;
                delay_ms(ms);
               
        }
}

void Westyellow_Blinker(u16 ms,u16 times)        // 西黄和东红一起闪
{
        for(c=0; c<times; c++)
        {
                P0 = 0xBE;
                delay_ms(ms);
                BEEP = 0;
                delay_ms(3);
                BEEP = 1;
                delay_ms(3);
                P0 = 0xFF;
                delay_ms(ms);
               
        }
}

void Eastyellow_Blinker(u16 ms,u16 times)        //东黄和北红一起闪
{
        for(c=0; c<times; c++)
        {
                P0 = 0xEB;
                P2 = 0xBB;
                delay_ms(ms);
                BEEP = 0;
                delay_ms(3);
                BEEP = 1;
                delay_ms(3);
                P0 = 0xFB;
                P2 = 0xBF;
                delay_ms(ms);
               
        }
}

void main()
{
        WTST = 1;
        // IO口模式配置
        P0M1 = 0x00;        P0M0 = 0x00;
        P1M1 = 0x00;        P1M0 = 0x00;
        P2M1 = 0x00;        P2M0 = 0x00;
        P3M1 = 0x00;        P3M0 = 0x00;
        P4M1 = 0x00;        P4M0 = 0x00;
        P5M1 = 0x00;        P5M0 = 0x00;       
       
        while(1)
        {
                // 根据红绿灯运行时序,制作1个循环完成动作演示。
                for(a = 0; a<8; a++)
                {
                        P2 = NS_LED;
                        P0 = WE_LED;       
                        delay_ms(time);                       
                        if(a == 1)
                        {
                                Northyellow_Blinker(500,5);
                        }
                        if(a == 3)
                        {
                                Southyellow_Blinker(500,5);
                        }
                        if(a == 5)
                        {
                                Westyellow_Blinker(500,5);
                        }
                        if(a == 7)
                        {
                                Eastyellow_Blinker(500,5);
                        }


                }               
        }
}



页: [1] 2
查看完整版本: 数组的应用——利用数组做个交通灯@32G12K128