找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7660|回复: 3
收起左侧

32*32点阵led交通灯设计

[复制链接]
ID:73735 发表于 2015-2-19 01:00 | 显示全部楼层 |阅读模式



看了不少的Proteus仿真、单片机设计,都没看到有关人行道交通灯的设计,针对机动车而设计的红绿灯倒是不少,难道就这么忽视行人的安全,所以就有了设计一个这样的交通灯的想法。

        取材是来自水南汽车站旁边的交通灯。
由于是仿真、资源也有限,点阵是用单色的,所以,“停”的效果不好,译码器用74LS154,这个太贵,实际肯定要用138了。
PS:取字模软件是我自己破解的,所以用起来感觉很不一样。

下面是源程序,有什么不足之处,请指出:

#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
/***************************************/
void sendbyteR(uchar temp); //发送数据
sbit RSDA=P2^4;
sbit CLK=P2^5;
sbit RCK=P2^6;
uchar code signature[][128]={    };         。。。。代码太长省略
uchar code num[][128]={      };               。。。。代码太长省略

/***************************************/
void main()
{
        P1=0x00;
        TMOD=0x01;
        TH0=0x3c;  //T0定时50ms
        TL0=0xb0;
        EA=1;
        ET0=1;
        TR0=1;
        while(1);
}
/***************************************/
void sendbyteR(uchar temp) //发送数据
{
        uchar c;
        for(c=0;c<8;c++){
                temp=temp>>1;
                RSDA=CY ;
                CLK=1 ; //上升沿
                _nop_() ;
                _nop_() ;
                CLK=0 ;
        }
}
/***************************************/
void time0()interrupt 1
{
        uchar j,k,count,count1,diff;
        uint n,n1;
        TH0=0x3c;
        TL0=0xb0;
        for(j=0;j<32;j++){
                if(diff){
                        if((n>33)){     //倒计时“5”时,开始闪动
                                if((n1%2)==0) k=3;
                                else{
                                        if((n1%4)==1) k=0;
                                        else k=1;
                                        }
                                }
                                else k=n1%2; //行走
                        }
                        else k=2;       //停
                       
                        sendbyteR(num[n][j*4+3]); //显示数字
                        sendbyteR(num[n][j*4+2]);
                        sendbyteR(num[n][j*4+1]);
                        sendbyteR(num[n][j*4]);

                        sendbyteR(signature[k][j*4+3]);  //显示人
                        sendbyteR(signature[k][j*4+2]);
                        sendbyteR(signature[k][j*4+1]);
                        sendbyteR(signature[k][j*4]);

                        P1=j;
                        RCK=1;
                        RCK=0;
                }
                if(j==32) j=0;
                count++;
                count1++;
                if(count==20){
                        count=0;
                        n++;    //计时1s
                }
                if(count1==5){
                        count1=0;
                        n1++;  //计时0.25s
                }
                if(n1==39) n1=0;
                if(n==39){
                        diff=!diff;  //diff "0":停 ,"1":行走
                        if(diff) n=10;
                        else n=0;
                }
}








评分

参与人数 1黑币 +5 收起 理由
treenewbee + 5 很给力!

查看全部评分

回复

使用道具 举报

ID:73735 发表于 2015-2-19 01:03 | 显示全部楼层
       玩了一天的游戏,太没意思了,无聊下就编了个AVR单片机的程序。还记得上次发表的点阵led交通灯,原来核心是51,这学期学的是AVR,所以就换了,改用ATmega16。
       由于是从51上移植过来的,自然思路也差不多。只是这次在中断使用上,做了调整,使之尽可能的短!




                                           核心改变:

下面是在CVAVR下的源程序,有什么不足之处,请指出 :




#include <mega16.h>
#define uchar unsigned char
int time_counter1s,time_counter250ms;
bit diff;
uchar j,n,k,time250ms;
//RSDA PORTC.1;
//CLK PORTC.0;
//RCK PORTC.2;
flash uchar signature[][128]={
     .....//00: "walk1",点阵32x32,长度128字节
     .....//02: "walk2",点阵32x32,长度128字节
     .....//03: "stop",点阵32x32,长度128字节
     .....//04: "blank",点阵32x32,长度128字节
};
flash uchar num[][128]={
     .....//"39"~"1",点阵32x32,长度128字节
};

void sendbyteR(uchar temp) //发送数据
{
        uchar c;
        for(c=0;c<8;c++)
    {
                PORTC.1=(temp)&(0x01);
                temp=temp>>1;
                PORTC.0=1; //上升沿
                PORTC.0=0;
        }
}

void display(void)  //显示图像
{   
    for(j=0;j<32;j++)
    {   
        if(diff)
        {
          if(n>33) //倒计时“5”时,开始闪动
          {
            if((time250ms%2)==0) k=3;
            else{
                    if((time250ms%4)==1) k=0;
                    else k=1;
                }  
          }
          else k=time250ms%2; //行走   
        }
        else k=2;            //停
        sendbyteR(num[n][j*4+3]); //显示数字
            sendbyteR(num[n][j*4+2]);
            sendbyteR(num[n][j*4+1]);
            sendbyteR(num[n][j*4]);

            sendbyteR(signature[k][j*4+3]);  //显示人
            sendbyteR(signature[k][j*4+2]);
            sendbyteR(signature[k][j*4+1]);
            sendbyteR(signature[k][j*4]);
            PORTA=j;
            PORTC.2=1;
            PORTC.2=0;      
    }   
}
// Timer 0 比较匹配中断服务
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{  
    if(++time_counter1s>=500)
    {
        time_counter1s=0;
        n++;                     //计时1s
    }
    if(++time_counter250ms>=125)
    {
        time_counter250ms=0;    //计时0.25s   
        time250ms++;
    }
}

void main(void)
{
PORTA=0x00;
DDRA=0x1F;
PORTC=0x00;
DDRC=0x07;       //显示控制I/O口初始化

// Timer/Counter 0 初始化

TCCR0=0x0B;   //内部时钟,64分频,CTC模式
TCNT0=0x00;
OCR0=0x7C;   //OCR0=2ms
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;

n=0;          //赋初始值
k=0;
diff=0;
#asm("sei")   //使能全局中断
while (1)
      {
      // Place your code here
        display();    //显示图像
        if(n>=39)
        {   
            diff=!diff;          //diff "0":停 ,"1":行走
            if(diff) n=10;
            else n=0;
        }
        if(time250ms>=39) time250ms=0;
      }
}



回复

使用道具 举报

ID:127379 发表于 2016-6-20 15:49 | 显示全部楼层
简直不要太棒了
回复

使用道具 举报

ID:104183 发表于 2016-6-25 11:17 | 显示全部楼层
太好了,谢谢分享了。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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