P3=0x30; temp=P3;
if((temp&0x30)!=0x30) { P3=0x03; temp2=P3; keycode=temp|temp2; for(j=0;j<4;j++) { if(keycode==key_code[j]) { key=j; } }
if(key==0) dir=1;//正转 if(key==1) dir=0;//反转 if(key==2) { speed++; if(speed==5) speed=4;//换档 } if(key==3) { if(speed==0) speed++;//换档 speed--; } switch (speed) { case 0:P0=0xef;break; case 1:P0=0xf7;break; case 2:P0=0xfb;break; case 3:P0=0xfd;break; case 4:P0=0xfe;break; default:break; } P3=0x03; while(!(P3==0x03)); } }
if(dir==1)//正转时执行 { P1=aa; for(j=0;j } } } delay(); aa=_crol_(aa,1);//左移 if(dir==0)//反转时执行 { P1=aa; for(j=0;j 5、电路图: 6、仿真结果: D1~D8 八个发光二极管构成彩色旋转灯,D9~D13 为档位指示灯,一档旋转速度最慢,二档较快,三档更快,四档再快,五档最快。四个按键 KEY0-KEY1于设定旋转方向为顺时针旋转或者逆时针旋转,KEY2-KEY3 用于增快或则减慢旋转速度。 实验五 定时器计数器实验 自我完成实验 1、实验要求 用 NE555 构成的脉冲信号发生器,右边是用定时/计数器 0 和定时/计数器 1构成的频率计。为了检验频率计量是否准确,用 Proteus 的虚拟频率计来进行测量脉冲信号频率进行比对。 7SEG1-7SEG6 用于频率计百分位、十分位、个位、十位、百位、千位的显示, 单位为 Hz。要求单片机上电运行后作为频率计将一直运行,改变脉冲发生器所产生的脉冲 频率,则频率计的显示将跟随变化。 2、编程思路 定时/计数器 0 工作在定时器模式方式 1(16 位),定时/计数器 1 工作在计数器模式方 式 2(8 位自动重装初值)。 定时/计数器 1 计数 200 个脉冲后(每计数 200 个脉冲产生一次中断)统计这 200 个脉 冲总的时间长度,计算出平均每个周期的时间长度。 200 个脉冲所用时间长度的测量是靠定时/计数器 0 来实现的,定时/计数器 0 的初值为 0。当定时/计数器 1 产生中断时,读出定时/计数器 0 当前计数器值,再加上在定时/计数器0 中断中累积的值即可得到。 3、实验步骤 ① 根据上述实验内容,参考 1.2.2,在 Proteus 环境下建立图 3.11 所示原理图,并将其保存为 frequencycounter.DSN 文件。 ② 根据(2)和(3)编写控制源程序,将其保存为 frequencycounter.c。 ③ 运行 Keil uVision2 开发环境,按照 1.1.3 节介绍的方法建立工程 frequencycounter.uV2,CPU 为 AT89C51,包含启动文件 STARTUP.A51。 ④ 按照 1.2.2 第(6)节介绍的方法将 C 语言源程序 frequencycounter.c 加入工程 frequencycounter.uV2,并设置工程 frequencycounter.uV2 属性,将其晶振频率设置 为 12MHz,选择输出可执行文件,仿真方式为选择硬仿真,并选择其中的“PROTEUS VSM MONITOR 51 DRIVER”仿真器。 ⑤ 构造(Build)工程 frequencycounter.uV2。如果输入有误进行修改,直至构造正确, 生成可执行程序 frequencycounter.hex 为止。 ⑥ 为 AT89C51 设置可执行程序 frequencycounter.hex。 ⑦ 运行程序,观察数码管的显示与虚拟频率计是否一致。 ⑧ 改变 RV2 的值,继续观察频率测量结果,观察数码管的显示与虚拟频率计是否一致。 4、源程序 #include\ #define uchar unsigned char #define uint unsigned int uchar code led_table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar xdata da001 _at_ 0xfe00; uchar xdata da01 _at_ 0xfd00; uchar xdata da1 _at_ 0xfb00; uchar xdata da10 _at_ 0xf700; uchar xdata da100 _at_ 0xef00; uchar xdata da1k _at_ 0xdf00; uchar dv001,dv01,dv1,dv10,dv100,dv1k; long sumtime=0;//总时间 float frequency,ptime;//分别为 频率, 单周期时间 uint timer0H; uint timer0L; void s_timer0() interrupt 1 { EA=0; sumtime=sumtime+65536; TH0=timer0H; TL0=timer0L; EA=1; } void s_timer1() interrupt 3 { EA=0; sumtime=sumtime+TH0*256+TL0; TH0=timer0H; TL0=timer0L; ptime=(float)sumtime/200; sumtime=0; frequency=(float)1000000/ptime; dv1k=(uchar)(frequency/1000); frequency=frequency-dv1k*1000; dv100=(uchar)(frequency/100); frequency=frequency-dv100*100; dv10=(uchar)(frequency/10); frequency=frequency-dv10*10; dv1=(uchar)frequency; frequency=frequency-dv1; frequency=frequency*10; dv01=(uchar)frequency; frequency=frequency-dv01; frequency=frequency*10; dv001=(uchar)frequency; da001=led_table[dv001]; da01=led_table[dv01]; da1=led_table[dv1]; da10=led_table[dv10]; da100=led_table[dv100]; da1k=led_table[dv1k]; EA=1; } void main()