实验二流水灯实验目的1、熟练掌握keil软件的基本操作;2、掌握8051单片机GPI0驱动能力的计算;3、掌握按键去抖的原理及实现。实验设备与文件PC机、Stc89c52实验箱、USB线、stc89c52实验板原理图。2HvCC流水灯电源酰线中流水灯模块S2P30/TXDP31/RXDSAP32/INTOO1S5P33/INT1独立键盘模块图1原理图1
1 实验二 流水灯 一、 实验目的 1、熟练掌握 keil 软件的基本操作; 2、掌握 8051 单片机 GPIO 驱动能力的计算; 3、掌握按键去抖的原理及实现。 二、 实验设备与文件 PC 机、stc89c52 实验箱、USB 线、stc89c52 实验板原理图。 图 1 原理图
三、实验原理3.1GPIO驱动能力的计算图2是stc89c52单片机DataSheet中芯片的直流特性参数:DCSpecification (5VMCU)SpecificationSymParameterTest ConditionMin.TypMax.UnitVoD3.85.5VOperating Voltage5.0Ln<0.1uA5VPowerDownCurrent2.05VLIDLIdle CurrentmA.Lcc.4205VmAOperatingCurrentViLl0.8V5VInput Low (PO.P1.P2.P3P4)+5VViu21.5vInput Low voltage (RESET,XTALI)v5VVim2.0Input High (PO.P1,P2,P3. P4, /EA)Vu2V5VInput High (RESET)3.06mA5VLoLiSinking Currentforoutput low (P1.P2.P3.P4)412loL28mA5VSinking Current for output low(PO,ALE,PSEN)1502205VLomuASourcing Current for output high (P1,P2,P3,P4)205VLoR214mASourcingCurrent for output high (ALE,PSEN)La1850uALogicO inputcurrent (P1.P2.P3,P4)Vpin=0V270600uAInLogic1to0transition current (P1,P2P3,P4)Vpin=2.0V图2stc85c52的直流特性从图2可以看出GPIO输入低电平最大的阀值是0.8V,0.8V以下辨别为低电平;输入高电平最小的阀值是2.0V,2.0V以上辨别为高电平,输入电平在0.8V~2.0V之间判别的值不确定,应该避免处于这种状态。IOL(SinkingCurrentforoutputlow,灌电流)输出低电平吸收外部电流的能力为6mA,IOH(SourcingCurrentforoutputhigh,拉电流)输出高电平向外提供电流的能力为200uA。单片机的灌电流比拉电流大得多,所以发光二极管阳极接电源,阴极接单片机IO,电流方向是从电源到单片机的。参考流水灯原理图可以得出此时单片机IO的电流为:I=(5V-2V)/1K=3mA<6mA电源为5V,发光二极管导通时两端电压为2V,IO口输出低电平,计算通过1K排阻支路的电流就可以得到通过IO口的电流为3mA,小于极限值的6mA。2
2 三、 实验原理 3.1 GPIO 驱动能力的计算 图 2 是 stc89c52 单片机 DataSheet 中芯片的直流特性参数: 图 2 stc85c52 的直流特性 从图 2 可以看出 GPIO 输入低电平最大的阀值是 0.8V,0.8V 以下辨别为低电 平;输入高电平最小的阀值是 2.0V,2.0V 以上辨别为高电平,输入电平在 0.8V~2.0V 之间判别的值不确定,应该避免处于这种状态。 IOL(Sinking Current for output low,灌电流)输出低电平吸收外部电流的能力为 6mA, IOH(Sourcing Current for output high,拉电流)输出高电平向外提供电流的能力 为 200uA。 单片机的灌电流比拉电流大得多,所以发光二极管阳极接电源,阴极接单片 机 IO,电流方向是从电源到单片机的。 参考流水灯原理图可以得出此时单片机 IO 的电流为: I = (5V - 2V)/1K=3mA<6mA 电源为 5V,发光二极管导通时两端电压为 2V,IO 口输出低电平,计算通过 1K 排阻支路的电流就可以得到通过 IO 口的电流为 3mA,小于极限值的 6mA
3.2按键去抖处理图3是独立按键按下时,输出的电压波形:断开断开闭合ttoto+t图3抖动波形可以看出由于机械振动,按键按下的瞬间有电压的抖动。单片机的程序执行速度很快,如果不加去抖处理,会将按键的一次按下作为多次按下处理。用软件延时可以消除按键抖动,基本思想:在检测到某个按键所对应的10口为低电平时,可以初步认为该按键按下,执行一段延时10mS的子程序后,再次检测该10口电平是否仍为低电平,如果仍为低电平,则确认该按键被按下。当按键抬起时,对应的I0口低电平变为高电平,执行一段延时10ms的子程序后,检测该I0是否仍为高电平,如果为仍高电平,则确认按键已抬起。参考程序如下://如果某键按下if(S2==0)1delay_ms(10);//延时10msif(S2==0)//再次检测,确认这个键按下1//编写相应的事件处理程序:13
3 3.2 按键去抖处理 图 3 是独立按键按下时,输出的电压波形: 图 3 抖动波形 可以看出由于机械振动,按键按下的瞬间有电压的抖动。单片机的程序执行 速度很快,如果不加去抖处理,会将按键的一次按下作为多次按下处理。 用软件延时可以消除按键抖动,基本思想:在检测到某个按键所对应的 IO 口为低电平时,可以初步认为该按键按下,执行一段延时 10ms 的子程序后,再 次检测该 IO 口电平是否仍为低电平,如果仍为低电平,则确认该按键被按下。 当按键抬起时,对应的 IO 口低电平变为高电平,执行一段延时 10ms 的子程 序后,检测该 IO 是否仍为高电平,如果为仍高电平,则确认按键已抬起。 参考程序如下: if(S2==0) //如果某键按下 { delay_ms(10); //延时 10ms if(S2==0) //再次检测,确认这个键按下 { ; //编写相应的事件处理程序 } }
3.3C51基本程序结构1/包含头文件,特殊功能寄存器地址的定义在reg52.h中1/或者包含其他要引用的函数对应头文件#include<reg52.h>/单片机头文件,定义特殊功能寄存器地址I/#define标识符字符串,是一种宏定义,下文中可以用标识符代替字符串#defineucharunsignedchar//下文中可以用uchar代替unsignedchar#define uint unsigned int#define u8 unsigned charI/无符号8位,另一种常用写法,更容易区分变量的类型1/无符号16位#define ul6 unsigned int#define s8 char//有符号8位#define s16 int//有符号16位#defineDELAY_TIME2//将常量定义为宏,修改程序时达到修改一次,多处修改的目的I/定义硬件接口sbit LED1=P1^0;uchari,I/定义全局变量,全局变量的作用域在整个文件1/可以在这里写一些自定义的函数1/如实现软件延时函数等void delay(uint x);31/主函数void main()1ucharj;I定义局部变量,作用域在大括号中在这里可以对中断,定时器,串口等一些外设进行设置//以下内容不是固定的,这里列出是举例说明I/定时器1为IT模式AUXR = 0x40;1/定时器1为模式0(16位自动重载)TMOD = 0x00;TL1=(65536-(FOSC/4/BAUD));1/设置波特率重装值TH1=(65536 - (FOSC/4/BAUD))>>8;TR1 = 1;I定时器1开始启动ES =1;1/使能串口中断ITO = 1;//设置INTO的中断类型EX0=1;1/使能INTO中断EA=1;//开启总中断/IC51程序需要一个大循环,反复循环执行大循环内的程序段/可以在大循环里处理各种事件,如果没有大循环单片机程序会跑“飞”4
4 3.3 C51 基本程序结构 //包含头文件,特殊功能寄存器地址的定义在 reg52.h 中 //或者包含其他要引用的函数对应头文件 #include<reg52.h> //单片机头文件,定义特殊功能寄存器地址 //#define 标识符 字符串,是一种宏定义,下文中可以用标识符代替字符串 #define uchar unsigned char //下文中可以用 uchar 代替 unsigned char #define uint unsigned int #define u8 unsigned char //无符号 8 位,另一种常用写法,更容易区分变量的类型 #define u16 unsigned int //无符号 16 位 #define s8 char //有符号 8 位 #define s16 int //有符号 16 位 #define DELAY_TIME 2 //将常量定义为宏,修改程序时达到修改一次,多处修改的目的 sbit LED1 = P1^0; //定义硬件接口 uchar i; //定义全局变量,全局变量的作用域在整个文件 //可以在这里写一些自定义的函数 //如实现软件延时函数等 void delay(uint x) { ; } //主函数 void main() { uchar j; //定义局部变量,作用域在大括号中 //在这里可以对中断,定时器,串口等一些外设进行设置 //以下内容不是固定的,这里列出是举例说明 AUXR = 0x40; //定时器 1 为 1T 模式 TMOD = 0x00; //定时器 1 为模式 0(16 位自动重载) TL1 = (65536 - (FOSC/4/BAUD)); //设置波特率重装值 TH1 = (65536 - (FOSC/4/BAUD))>>8; TR1 = 1; //定时器 1 开始启动 ES = 1; //使能串口中断 IT0 = 1; //设置 INT0 的中断类型 EX0 = 1; //使能 INT0 中断 EA = 1; //开启总中断 //C51 程序需要一个大循环,反复循环执行大循环内的程序段 //可以在大循环里处理各种事件,如果没有大循环单片机程序会跑“飞
while(1)ifo)//如果发生了某种事件,进行相应的处理11/可以调用自己写的函数delay(100);3ifo/如果发生了其他的事件,则进行相应的处理t3for(i=0; i<8; i++)1.31/中断处理函数,如果需要中断处理可以在这里写出1/中断处理函数的代码要简短,达到“快进快出”/不要在中断处理函数中写延时、多次循环和调用别的函数等影响执行速度的语句//中断处理函数名可以任意,但参数和返回值必须是void/interruptn(n=0~4):n是对应的中断号//usingx(x=0~3)指定这个中断处理函数使用四组工作寄存器中的哪一组,可省略voidtimero()interrupt1using0IF四、实验内容及步骤1、利用keil4软件搭建好实验环境;2、注意事项:P1口不能接任何设备、杜邦线等,否则影响实验效果;3、依照实验参考程序,实现LED流水灯模块流水式点亮,烧录程序后从LED8~LED1循环点亮;4、实现LED流水灯模块流水式点亮,烧录程序后从LED1~LED8循环点亮;5、实现利用S4按键控制LED1~LED8循环点亮,S5按键控制LED1~LED8全灭,按键加去抖处理。5
5 while(1) { if() //如果发生了某种事件,进行相应的处理 { delay(100); //可以调用自己写的函数 } if() //如果发生了其他的事件,则进行相应的处理 { ; } for(i = 0; i < 8; i++) { ; } } } //中断处理函数,如果需要中断处理可以在这里写出 //中断处理函数的代码要简短,达到“快进快出” //不要在中断处理函数中写延时、多次循环和调用别的函数等影响执行速度的语句 //中断处理函数名可以任意,但参数和返回值必须是 void //interrupt n (n = 0~4) n 是对应的中断号 //using x (x = 0~3) 指定这个中断处理函数使用四组工作寄存器中的哪一组,可省略 void timer0() interrupt 1 using 0 { ; } 四、 实验内容及步骤 1、 利用 keil4 软件搭建好实验环境; 2、 注意事项:P1 口不能接任何设备、杜邦线等,否则影响实验效果; 3、 依照实验参考程序,实现 LED 流水灯模块流水式点亮,烧录程序后从 LED8~LED1 循环点亮; 4、 实现 LED 流水灯模块流水式点亮,烧录程序后从 LED1~LED8 循环点亮; 5、 实现利用 S4 按键控制 LED1~LED8 循环点亮,S5 按键控制 LED1~LED8 全灭,按键加去抖处理