/********************************************************************
* 文件名 : 独立按键.c
* 描述 : 该程序实现独立按键去控制 LED灯 的亮灭,并讲诉了对按键的处理方法。
独立按键相应的IO口平时为高电平,一旦按键按下,单片机便检测到低电平。
按下P3.2,P0.0口对应的LED亮灭交替变化。
按下P3.3,P0.1口对应的LED亮灭交替变化。
按下P3.4,P0.2口对应的LED亮灭交替变化。
* 创建人 : 东流,2009年8月27日
* 版本号 : 1.0
***********************************************************************/
#include<reg52.h>
#include"lop.h"
#define uchar unsigned char
#define uint unsigned int
#define u8 unsigned char
#define u16 unsigned int
typedef u8 a;
sbit KEY1 = P1^2;
sbit KEY2 = P1^3;
sbit KEY3 = P1^4;
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
sbit LED5 = P1^0;
sfr P4 =0Xe8;
sbit P4_0 = P4^0;
static u16 count;
char cost;
bit lixc=1;
sfr WDT_CONTR=0xe1; //1110 0001
//extern enu;
u8 cmd;
void KEY();
typedef struct
{
u8 i;
u8 *p;
}enu;
enu number;
/********************************************************************
* 名称 : Delay()
* 功能 : 延时,延时时间为 10ms * del
* 输入 : del
* 输出 : 无
***********************************************************************/
void Delay(uint del)
{
uint i,j;
for(i=0; i<del; i++)
for(j=0; j<1827; j++);
}
/********************************************************************
* 名称 : Delay()
* 功能 : 实现按键功能,当按键按下时,相应的LED亮灭交替
* 输入 : 无
* 输出 : 无
***********************************************************************/
void KEY()
{
a i;
number.i=0;
// Delay(2);
if(KEY1==0 || KEY2==0 || KEY3==0)
{
Delay(5); //20毫秒软件防抖
if(KEY1 == 0)
{
Delay(5);
// while(!KEY1);
// P4_0 = 0 ; //LED显示取反
Delay(1);
++cost; SBUF= cost;
while(!TI);TI=0;
}
if(KEY2 == 0)
{
// P4_0 = 1;
--cost;
SBUF= cost;
while(!TI);TI=0;
}
else
{
LED3 = !LED3;
}
Delay(50); //延时0.5秒再进行下次按键的检测
if(cost>=3)
{
lixc=0; P4_0=1;
}
else
lixc=1;
}
}
/*------------------------------------------------
串口初始化
------------------------------------------------*/
void InitUART (void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
// // TMOD: timer 1, mode 2, 8-bit 重装
TMOD |= 0x21;
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TL1 = 0xFD; //波特率
TR1 = 1; // TR1: timer 1 打开
IE |= 0x92; //开启中断
EA = 1; //打开总中断
ES = 1; //打开串口中断
// SM0=0;
// SM1=1; //串口方式1
// REN=1; //允许接收
// PCON=0x00; //关倍频
}
void Init_Timer1(void)
{
// TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
// TH0=0x0c; //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
// TL0=0x0c;
// ET0=1; //定时器中断打开
// TR0=1; //定时器开关打开
// EA=1; //总中断打开
TMOD &= 0xf0; //定时器0
TMOD |= 0x01;
TH0 = (65536-2000)/256; //2ms溢出
TL0 = (65536-2000)%256;
}
void Init_Timer2(void)
{
// TMOD=0x21; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH1=(65536-50000)/256; //给TH1和初初值,由15536开始计数,到65535溢出
TL1=(65536-50000)%256; //外部晶振为12MHz,对应的延时时间为50ms
ET1=1; //定时器中断打开
TR1=1; //定时器开关打开
EA=1; //总中断打开
}
void timer0(void) interrupt 1
{
// TH0=0x00; //重新赋值
// TL0=0x00;
TH0 = 0xDC; //10MS
TL0 = 0x00;
if(count>100&&lixc==1)
{
count=0;
P4_0 =!P4_0 ;
}
count++;
// if(count>=15)
// {
// count=0;
// WDT_CONTR|=0x10; // 00010000 || 1110 0001
// }
}
void timer1(void) interrupt 3 using 1
{
// TH1=(65536-50000)/256; //给TH1和初初值,由15536开始计数,到65535溢出
// TL1=(65536-50000)%256; //外部晶振为12MHz,对应的延时时间为50ms
TH1 = 0xDC; //10MS
TL1 = 0x00;
if(cmd>150)
{
cmd=0;
LED5 =!LED5 ;
}
cmd++;
}
void ET0_init()//定时器0初始化
{
EA=1; //打开总中断
TR0=1; //打开定时器0中断
ET0=1; //启动定时器0中断
TH0=(65536-50000)/256;//无脑赋值 相当于50毫秒进入一次中断函数,20次就是1秒
TL0=(65536-50000)%256; //无脑赋值
TMOD= 0x01;//设置定时器t0的工作方式
}
void UartInit() //串口定时器1初始化
{
EA=1; //打开总中断
TMOD|=0x21; //设置定时器1工作方式为方式2
TR1=1; //启动定时器1
TH1=0xfd; //波特率9600
TL1=0xfd;
SCON=0X50; //允许接收
// ES=0;
}
void USART_IRQ(void) interrupt 4
{
unsigned char Temp; //定义临时变量
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
Temp=SBUF; //读入缓冲区的值
// P1=Temp; //把值输出到P1口,用于观察
SBUF=Temp; //把接收到的值再发回电脑端
}
if(TI) //如果是发送标志位,清零
TI=0;
}
/********************************************************************
* 名称 : Main()
* 功TMOD=0x11,转为二进制就是00010001,即T0和T1的最低两位均为01,工作方式为方式1--16位定时器或计数器。第三位为0,
设定T0,T1为定时器,对内部脉冲进行计数,用来折算时间。第四位也是0,说明不参考INTx引脚电平,
由内部寄存器来控制定时器的启停。能 : 实现按键控制LED的亮灭
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main(void)
{
// Init_Timer1();
// Init_Timer2();
// InitUART();
ET0_init();
UartInit();
WDT_CONTR = 0x24;
while(1)
{
KEY();
// WDT_CONTR = 0x24;
WDT_CONTR|=0x10;
}
}
|