#include <reg52.h>
sbit UPD = P1^4;//更新允许.上跳变更新输出
sbit CLK = P1^5;//移位时钟,上升沿移动数据
sbit SDA = P1^6;//数据线,低电平点亮LED
sbit OEN = P1^7;//输出允许控制,低电平允许显示
sbit SPEEDUP=P2^0;//滚屏速度增加
sbit SPEEDDOWN=P2^1;//滚屏速度减慢
sbit pause=P2^2;//暂停滚屏
sbit turnleft=P2^3;//左转
sbit turnright=P2^4;//右转
sbit slow_down=P2^5;//刹车
bit gunping;//是否滚屏
bit disp_on;//是否显示
bit disp_flash;//是否闪烁显示
unsigned int zhou_ping,speed;//走屏计数变量,速度控制变量
unsigned int pian_yi_liang;//刷新显示偏移量
unsigned char hang;//当前扫描行
unsigned char san_shuo;//闪烁计数变量
unsigned char *disp;//显示指针
unsigned char code linescan[]={15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
unsigned char code right[]={点阵数据};
unsigned char code left[]={点阵数据};
unsigned char code STOP[]={点阵数据};
unsigned char code LEDDOT[]={点阵数据};
void send595(unsigned char sendata)
{
if(disp_on)
{
CLK=0;//拉低时钟线
SDA=sendata&0x01;//提取最低位
CLK=1;//数据移入
CLK=0;
SDA=sendata&0x02;//提取最低位
CLK=1;//数据移入
CLK=0;
SDA=sendata&0x04;//提取最低位
CLK=1;//数据移入
CLK=0;
SDA=sendata&0x08;//提取最低位
CLK=1;//数据移入
CLK=0;
SDA=sendata&0x10;//提取最低位
CLK=1;//数据移入
CLK=0;
SDA=sendata&0x20;//提取最低位
CLK=1;//数据移入
CLK=0;
SDA=sendata&0x40;//提取最低位
CLK=1;//数据移入
CLK=0;
SDA=sendata&0x80;//提取最低位
CLK=1;//数据移入
CLK=0;
}
else
{
SDA=1;CLK=0;
CLK=1;CLK=0;CLK=1;CLK=0;CLK=1;CLK=0;CLK=1;CLK=0;
CLK=1;CLK=0;CLK=1;CLK=0;CLK=1;CLK=0;CLK=1;CLK=0;
}
}
void ledlinesend(unsigned int line)
{
unsigned char sdata;//临时数据
UPD=0;//冻结595输出
sdata=disp[line*10];//取对应行第一字节数据
send595(sdata);
sdata=disp[line*10+1];//取对应行第一字节数据
send595(sdata);
sdata=disp[line*10+2];//取对应行第一字节数据
send595(sdata);
sdata=disp[line*10+3];//取对应行第一字节数据
send595(sdata);
sdata=disp[line*10+4];//取对应行第一字节数据
send595(sdata);
sdata=disp[line*10+5];//取对应行第一字节数据
send595(sdata);
sdata=disp[line*10+6];//取对应行第一字节数据
send595(sdata);
sdata=disp[line*10+7];//取对应行第一字节数据
send595(sdata);
sdata=disp[line*10+8];//取对应行第一字节数据
send595(sdata);
sdata=disp[line*10+9];//取对应行第一字节数据
send595(sdata);
UPD=1;//595输出
}
void LED_shuaxin(void)
{
hang++;
OEN=1;//关闭显示(黑屏)
ledlinesend((hang&0x0f)+pian_yi_liang);
P3=linescan[hang&0x0f];
OEN=0;//显示
}
void Timer0(void) interrupt 1
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
zhou_ping++;//走屏速度延时变量
if(zhou_ping>=speed)//判断毫秒数是否到达预定速度
{
zhou_ping=0;//辅助变量复位
if(gunping)//是否允许滚屏
{
pian_yi_liang=pian_yi_liang+16;//换一屏数据
}
if(pian_yi_liang>288)//判断内容是否显示完毕
{
pian_yi_liang=0;//返回头头开始
}
if(pause==0)//判断滚屏暂停按钮是否按下
{
gunping=!gunping;//启动、暂停
}
}
LED_shuaxin();//每毫秒刷新一次LED屏
}
void Timer1(void) interrupt 3 using 1
{
TH1=(65536-50000)/256;//置初值
TL1=(65536-50000)%256;
san_shuo++;//闪烁辅助变量
if(san_shuo>=3&&disp_flash)//闪烁频率控制,是否闪烁
{
san_shuo=0;//辅助变量清零
disp_on=!disp_on;//闪烁
}
if(SPEEDUP==0&&speed>=200)//调整内容切换频率
{
speed-=10;//增加速度
}
if(SPEEDDOWN==0&&speed<10000)//调整内容切换频率
{
speed+=10;//降低速度
}
}
void init(void)
{
TMOD=0X11;//定时器方式1
ET0=1;//打开T0中断
ET1=1;//打开T1中断
TR0=1;//T0运行
TR1=1;//T1运行
PX0=1;//T0优先
EA=1;//总中断使能
}
void main(void)
{
speed=2000;//开机设置内容更新频率
disp=&LEDDOT;//置显示指针
init();//初始化
disp_on=1;//打开显示
gunping=0;//允许切换内容
while(1)
{
if(turnleft==0)//左转?
{
disp=&left;
pian_yi_liang=0;
disp_flash=1;
gunping=0;
while(turnleft==0);
disp=&LEDDOT;
disp_flash=0;
gunping=1;
disp_on=1;
}
if(turnright==0)//右转??
{
disp=&right;
pian_yi_liang=0;
disp_flash=1;
gunping=0;
while(turnright==0);
disp=&LEDDOT;
disp_flash=0;
gunping=1;
disp_on=1;
}
if(slow_down==0)//刹车??
{
disp=&STOP;
pian_yi_liang=0;
disp_flash=1;
gunping=0;
while(slow_down==0);
disp=&LEDDOT;
disp_flash=0;
gunping=1;
disp_on=1;
}
}
}
|