可控跑马灯仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<regx51.h> //加入头文件
- #define uchar unsigned char //宏定义用uchar来代替unsigned char
- #define uint unsigned int //宏定义用uint来代替unsined int
- uint code unm[]={0,1,3,5,7,9,15,60,100,200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500};
- //用于调速的数组
- uchar unm1[]={0xff,0xef,0xc7,0xab,0xef,0xef,0xef,0xff};
- //用于显示箭头的数组
- uchar m,n,j,y; //定义全局变量
- uint l,g;
- //==========延时子程序============
- void delay(uint i)
- {
- uchar j; //定义局部变量
- while(i--) //循环执行空指令用于延时
- for(j=0;j<120;j++);
- }
- //===========定时器初始化子程序===================
- void init()
- {
- TMOD = 0x11; //设置定时器0、1都工作在方式1
- TH0 = 0x00; //设置定时器0初值
- TL0 = 0x00;
- TH1 = 0xaa; //设置定时器1初值
- TL1 = 0xbb;
- EA = 1; //打开总中断
- ET0 = 1; //打开定时器0中断
- ET1 = 1; //打开定时器1中断
- TR0 = 1; //启动定时器0
- TR1 = 1; //启动定时器1
- }
- //=================================================
- //函数名:ce_anjian ( )
- //功能:检测是否有按键按下,并返回是否有按键按下
- //输出参数:key
- //说明:有按键按下,key=1;无键按下,key=0;
- //=================================================
- bit ce_anjian ( )
- {
- bit key=0; //定义局部变量
- P1=0xf3; //输出扫描信号,将行置高电平,将列置低电平
- if(P1!=0xf3) //读入P1口数据,与扫描信号比较判断是否有键按下
- key=1; //如果有键按下,key赋值为1
- else
- key=0; //如果没有键按下,key赋值为0
- return(key); //返回key值
- }
- //=================================================
- //函数名:ce_jianzhi ( )
- //功能:测按键值并去除按键按下和按键松开时的抖动
- //调用函数:doudong_ys();ce_anjian();
- //说明:键值y=i*2+j+1;
- //=================================================
- void ce_jianzhi ( )
- {
- uchar i,j,p; //定义局部变量
- do
- {
- while(ce_anjian()==0); //是否有按键按下?若按键没有按下,原地等待
- //若按键按下,则返回值为1,则继续往下执行
- delay(50); //调用去抖延时子程序
- }while(ce_anjian()==0); //再次判断是否有键按下?若没有按下,返回0
- for(i=0;i<2;i++)
- {
- P1=(0xfe<<i)|i; //循环扫描输出行扫描信号
- for(j=0;j<2;j++)
- {
- p=P1&0x0c; //读取并保留键盘的列数据,其余清0
- if(p==0x08>>j) //是否有1或2列按键按下?
- {
- y=i*2+j+1; //计算键值
- goto D1; //跳出循环,使程序跳转至D1
- }
- }
- }
- D1: delay(50); //调用去抖延时子程序
- do
- {
- while(ce_anjian()==1); //判断按键是否释放,若按键没有释放,继续判断
- //若按键有释放,返回值为0,则继续往下执行
- delay(50); //调用去抖延时子程序
- }while(ce_anjian()==1); //再次判断是否释放,若按键没有释放,继续判断
- }
- //=======蜂鸣器鸣叫子程序==========
- void mingjiao()
- {
- uchar t; //定义局部变量
- for(t=0;t<50;t++)
- {
- P1_7=0;
- }
- P1_7=1; //停止鸣叫
- }
- //============主程序===============
- void main()
- {
- init(); //调用定时器初始化子程序
- n=5; //单片机一上电,速度设置在第5挡
- while(1) //主程序无限循环执行
- {
- l=unm[n]; //设置定时器的设定值
- if(ce_anjian()==1) //快速判断是否有按键按下
- {
- ce_jianzhi(); //若有按键按下,则侧键值
- switch(y)
- {
- case 1: {m=1;j=0x7f;mingjiao();}break; //键值为1,则P2口赋值0xfe,点亮P2.0LED
- case 2: {m=2;j=0xfe;mingjiao();}break; //键值为2,则P2口赋值0xfd,点亮P2.1LED
- case 3: {n=n+1;if(n==24)n=23;mingjiao();}break;//键值为3,则P2口赋值0xfb,点亮P2.2LED
- case 4: {n=n-1;if(n==0)n=1;mingjiao();}break; //键值为4,则P2口赋值0xf7,点亮P2.3LED
- default: break;
- }
- }
- }
- }
- //=========定时器1中断子程序=======
- void t_1()interrupt 3
- {
- uchar a,k; //定义局部变量
- TH1 = 0xaa; //设置定时器初值
- TL1 = 0xbb;
- switch(m) //判断模式
- {
- case 1: //模式1
- {
- a=0x01; //显示左移箭头
- for(k=0;k<8;k++)
- {
- P2=a;
- P3=unm1[k];
- delay(2);
- a=a<<1;
- if(a==0)a=0x01;
- P0=j;
- }
- }break;
- case 2: //模式2
- {
- a=0x80; //显示右移箭头
- for(k=0;k<8;k++)
- {
- P2=a;
- P3=unm1[k];
- delay(2);
- a=a>>1;
- if(a==0)a=0x80;
- P0=j; //跑马灯右移
- }
- }
- }
- }
- //=======定时器0中断子程序=========
- void t_0()interrupt 1
- {
- uchar b1,b2,b3,b4,b5,b6,b7,b8; //定义局部变量
- if(++g<l) return; //如果g+1小于设定值l那么跳出中断
- g=0; //如果g+1大于设定值l则g清零
- switch(m)
- {
- case 1:{ j=(j>>1)|0x80;
- if(j==0xff)j=0x7f;}break;
- case 2:{ j=(j<<1)|0x01;
- if(j==0xff)j=0xfe;}break;
- }
- b1=unm1[0]; //箭头移动
- b2=unm1[1];
- b3=unm1[2];
- b4=unm1[3];
- b5=unm1[4];
- b6=unm1[5];
- b7=unm1[6];
- b8=unm1[7];
- unm1[0]=b2;
- unm1[1]=b3;
- unm1[2]=b4;
- unm1[3]=b5;
- unm1[4]=b6;
- unm1[5]=b7;
- unm1[6]=b8;
- unm1[7]=b1;
- }
复制代码
所有资料51hei提供下载:
项目1.zip
(76.45 KB, 下载次数: 25)
|