zoukankan      html  css  js  c++  java
  • 51单片机交通灯(定时器+38译码器+中断)

    51单片机交通灯这个实例主要用到的知识点有:

    >如何点亮LED

    >38译码器位选与段选

    >定时器控制

    >中断控制

    #include <reg52.h>
    
    /************ 交通灯 ***********/
    
    #define GPIO_DIG P0  //数码管显示交通灯等待的时间
    #define GPIO_TRAFFIC    P1 //定义交通灯
    
    sbit RED10 = P1^0;                //上面的人行道红灯
    sbit GREEN10 = P1^1;             //上面的人行道绿灯
    sbit RED11 = P1^2;                //上面的机动车通行红灯
    sbit YELLOW11 = P1^3;            //上面的机动车通行黄灯
    sbit GREEN11 = P1^4;                //上面的机动车通行绿灯
    
    sbit RED00 = P3^0;                //右边的人行道红灯
    sbit GREEN00 = P3^1;             //右边的人行道绿灯
    sbit RED01 = P1^5;                //右边的机动车通行红灯
    sbit YELLOW01 = P1^6;            //右边的机动车通行黄灯
    sbit GREEN01 = P1^7;                //右边的机动车通行绿灯
    
    //38译码器的位选输入端
    sbit A1 = P2^2;
    sbit B1 = P2^3;
    sbit C1 = P2^4;
    
    typedef unsigned int u16;
    typedef unsigned char u8;
    
    u16 second = 1;
    
    void timer_init(){
        TMOD |= 0x01;
          //定时器工作方式1,启用T0定时器, GATE位为0,用TCON的TR0控制T0定时器的启动
        //设置定时器的初始计数值
        //计算方法
        //假设定时器为1ms,一个机器周期为 1/单片机的晶振频率  即: 1/12M = 1us
        //而1个机器周期 = 12个时钟周期 所以: n x 机器周期 = 1ms ===> n x 1us = 1ms
        //所以n = 1000,也就是经过1000个机器周期,定时器要溢出(从0开始计数)
        //所以定时器的初始值为65535 - 1000 + 1 = 64536 ===> 0xFC18
        TH0 = 0xFC;  //计时器初始值的高8位
        TL0 = 0x18;  //计时器初始值的低8位
        EA = 1;  //总中断开关
        ET0 = 1; //T0中断
        TR0 = 1;//启动T0定时器
    }
    
    void delay( u16 i ) {
        while( i-- );
    }
    
    void trigger_timer() interrupt 1{
        static u16 i = 0;
        TH0 = 0xFC;
        TL0 = 0x18;
        i++;
        if( i == 1000 ) { //1秒
            i = 0;
            second++;
        }
    }
    
    u8 digital[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 
                            0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c,
                            0x39, 0x5e, 0x79, 0x71 };
    u8 DisplayData[8];
    
    void showDigital(){
        int i = 0;
        for ( i = 0; i < 8; i++ ) {
            switch( i ) {
                case 0:  //位选第一个数码管
                    A1 = 0x0; B1 = 0x0; C1 = 0x0;
                    break;
                case 1:
                    A1 = 0x1; B1 = 0x0; C1 = 0x0;
                    break;
                case 2:
                    A1 = 0x0; B1 = 0x1; C1 = 0x0;
                    break;
                case 3:
                    A1 = 0x1; B1 = 0x1; C1 = 0x0;
                    break;
                case 4:
                    A1 = 0x0; B1 = 0x0; C1 = 0x1;
                    break;
                case 5:
                    A1 = 0x1; B1 = 0x0; C1 = 0x1;
                    break;
                case 6:
                    A1 = 0x0; B1 = 0x1; C1 = 0x1;
                    break;
                case 7:
                    A1 = 0x1; B1 = 0x1; C1 = 0x1;
                    break;
            }
            GPIO_DIG = DisplayData[ i ];
            delay( 100 );
            GPIO_DIG = 0x00; //消隐
        }
    }
    
    void main(){
        u8 shiwei = 0, gewei = 0;
        timer_init();
        while( 1 ){
            if( second == 70 ) {  //红绿灯总共70秒 然后轮回
                second = 1;
            }
            
            if( second < 31 ) {
                DisplayData[0] = 0x00;  //数码管1显示的数字
                DisplayData[1] = 0x00;  //数码管2显示的数字
                shiwei = ( 30 - second ) % 100 / 10;
                gewei = ( 30 - second ) % 10;
                DisplayData[2] = digital[ shiwei ];
                DisplayData[3] = digital[ gewei ];
    
                DisplayData[4] = 0x00;  //数码管5显示的数字
                DisplayData[5] = 0x00;  //数码管6显示的数字
                DisplayData[6] = DisplayData[2];
                DisplayData[7] = DisplayData[3];
    
                //宝田路通行
                GPIO_TRAFFIC = 0xFF; //熄灭所有的灯
                RED00 = 1;
                GREEN00 = 1;
    
                GREEN11 = 0; //宝田路绿灯亮
                RED10 = 0;   //宝田路人行道 红灯亮
                
                GREEN00 = 0; //前进路人行道绿灯亮
                RED01 = 0;    //前进路红灯亮
    
                showDigital();
            } else if ( second < 36 ){  //黄灯切换
    
                DisplayData[0] = 0x00;  //数码管1显示的数字
                DisplayData[1] = 0x00;  //数码管2显示的数字
                shiwei = ( 35 - second ) % 100 / 10;
                gewei = ( 35 - second ) % 10;
                DisplayData[2] = digital[ shiwei ];
                DisplayData[3] = digital[ gewei ];
    
                DisplayData[4] = 0x00;  //数码管5显示的数字
                DisplayData[5] = 0x00;  //数码管6显示的数字
                DisplayData[6] = DisplayData[2];
                DisplayData[7] = DisplayData[3];
    
                //宝田路黄灯切换
                GPIO_TRAFFIC = 0xFF; //熄灭所有的灯
                RED00 = 1;
                GREEN00 = 1;
    
                YELLOW11 = 0; //宝田路黄灯亮
                RED10 = 0;   //宝田路人行道 红灯亮
                
                GREEN00 = 0; //前进路人行道绿灯亮
                RED01 = 0;    //前进路红灯亮
    
                showDigital();            
            } else if ( second < 66 ){  //前进路通行
            
                DisplayData[0] = 0x00;  //数码管1显示的数字
                DisplayData[1] = 0x00;  //数码管2显示的数字
                shiwei = ( 65 - second ) % 100 / 10;
                gewei = ( 65 - second ) % 10;
                DisplayData[2] = digital[ shiwei ];
                DisplayData[3] = digital[ gewei ];
    
                DisplayData[4] = 0x00;  //数码管5显示的数字
                DisplayData[5] = 0x00;  //数码管6显示的数字
                DisplayData[6] = DisplayData[2];
                DisplayData[7] = DisplayData[3];
    
                //前进路通行
                GPIO_TRAFFIC = 0xFF; //熄灭所有的灯
                RED00 = 1;
                GREEN00 = 1;
                
                GREEN01 = 0; //前进路绿灯亮
                RED00 = 0;   //前进路人行道 红灯亮
                
                GREEN10 = 0; //宝田路人行道绿灯亮
                RED11 = 0;    //宝田路红灯亮
    
                showDigital();    
            } else {   //黄灯切换
                DisplayData[0] = 0x00;  //数码管1显示的数字
                DisplayData[1] = 0x00;  //数码管2显示的数字
                shiwei = ( 70 - second ) % 100 / 10;
                gewei = ( 70 - second ) % 10;
                DisplayData[2] = digital[ shiwei ];
                DisplayData[3] = digital[ gewei ];
    
                DisplayData[4] = 0x00;  //数码管5显示的数字
                DisplayData[5] = 0x00;  //数码管6显示的数字
                DisplayData[6] = DisplayData[2];
                DisplayData[7] = DisplayData[3];
    
                //前进路通行
                GPIO_TRAFFIC = 0xFF; //熄灭所有的灯
                RED00 = 1;
                GREEN00 = 1;
                
                YELLOW01 = 0; //前进路黄灯亮
                RED00 = 0;   //前进路人行道 红灯亮
                
                GREEN10 = 0; //宝田路人行道绿灯亮
                RED11 = 0;    //宝田路红灯亮
    
                showDigital();                
            }
        }
    }
  • 相关阅读:
    阿米巴
    linux系统和依赖包常用下载地址
    chm格式文件能打开,但看不到内容问题
    云计算的三层SPI模型
    云计算相关的一些概念Baas、Saas、Iaas、Paas
    IOS 开发环境,证书和授权文件等详解
    Android MDM参考
    理解RESTful架构
    联想小新Air2020锐龙版在Ubuntu下添加指纹识别
    避免踩坑,这才是为知笔记导入印象笔记数据的正确姿势
  • 原文地址:https://www.cnblogs.com/ghostwu/p/9164414.html
Copyright © 2011-2022 走看看