标题:
32*32点阵led交通灯设计
[打印本页]
作者:
huge
时间:
2015-2-19 01:00
标题:
32*32点阵led交通灯设计
http://player.youku.com/player.php/sid/XNDQxODE4MDAw/v.swf
看了不少的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;
}
}
作者:
huge
时间:
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;
}
}
作者:
虫子哥哥
时间:
2016-6-20 15:49
简直不要太棒了
作者:
leileiq910
时间:
2016-6-25 11:17
太好了,谢谢分享了。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1