这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » STC51单片机实例之31红外解码1602显示

共1条 1/1 1 跳转至

STC51单片机实例之31红外解码1602显示

高工
2014-08-19 01:49:17     打赏
/********************************************************************
* 文件名  :  红外解码LCD.c
* 描述    :  实现了红外解码遥控器上的按键的值并在1602上显示出来。
			 按遥控器的“0”会在数码管的最后一位显示0.	
			 按遥控器的“1”会在数码管的最后一位显示1.	
			 。
			 。
			 。
			 。
			 。
			 。
			 。
			 。
			 按遥控器的“8”会在数码管的最后一位显示8.	
			 按遥控器的“9”会在数码管的最后一位显示9.			 

***********************************************************************/

#include <reg51.h>
#include <intrins.h>

#define uchar unsigned char
#define uint  unsigned int

uchar LCD_ID_1[16] = {"Red Control"};
uchar LCD_ID_2[16] = {"You press the:-"};

void delay(uchar x);  //x*0.14MS
void delay1(int ms);

uchar distemp = 0;

sbit IRIN = P3^3;         //红外接收器数据线

uchar IRCOM[7];

sbit E=P2^7;		//1602使能引脚
sbit RW=P2^6;		//1602读写引脚	
sbit RS=P2^5;		//1602数据/命令选择引脚

/********************************************************************
* 名称 : Delay()
* 功能 : 延时,延时时间大概为1毫秒
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)
{
	uint x,j;
	for(j=0;j<i;j++)
	for(x=0;x<=148;x++);	
}

/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为140US。
* 输入 : 无
* 输出 : 无
***********************************************************************/

void Delay2()
{
	int i,j;
	for(i=0; i<=10; i++)
	for(j=0; j<=2; j++)
	;
}

/********************************************************************
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/ 
void enable(uchar del)
{
	P0 = del;
	RS = 0;
	RW = 0;
	E = 0;
	Delay2();
	E = 1;
	Delay2();
}

/********************************************************************
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/

void write(uchar del)
{
	P0 = del;
	RS = 1;
	RW = 0;
	E = 0;
	Delay2();
	E = 1;
	Delay2();
}

/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
	enable(0x38);
	Delay_1ms(5);
	enable(0x38);
	Delay_1ms(5);
	enable(0x38);
	Delay_1ms(5);
	enable(0x38);
	enable(0x08);	
	enable(0x0c);
	enable(0x04);
	enable(0x01);
}

/********************************************************************
* 名称 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
		 L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
	uchar a;
	if(hang == 1) a = 0x80;
	if(hang == 2) a = 0xc0;
	a = a + lie - 1;
	enable(a);
	write(sign);
}

/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
	 	 L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
	uchar a;
	if(hang == 1) a = 0x80;
	if(hang == 2) a = 0xc0;
	a = a + lie - 1;
	enable(a);
	while(1)
	{
		if(*p == '\0') break;
		write(*p);
		p++;
	}
}

/*******************************************************************/
main()
{
 
    IE = 0x84;                 //允许总中断中断,使能 INT1 外部中断
    TCON = 0x10;               //触发方式为脉冲负边沿触发
    
    IRIN=1;                    //I/O口初始化
	
    delay1(10);                 //延时
    L1602_init();               //初始化LCD             
	L1602_string(1, 1, LCD_ID_1);
	L1602_string(2, 1, LCD_ID_2);
    while(1);

} //end main
/**********************************************************/
void IR_IN() interrupt 2 using 0
{
  unsigned char j,k,N=0;
     EX1 = 0;   
	 delay(15);
	 if (IRIN==1) 
     { EX1 =1;
	   return;
	  } 
                           //确认IR信号出现
  while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
    {delay(1);}

 for (j=0;j<4;j++)         //收集四组数据
 { 
  for (k=0;k<8;k++)        //每组数据有8位
  {
   while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
     {delay(1);}
    while (!IRIN)          //等 IR 变为高电平
     {delay(1);}
     while (IRIN)           //计算IR高电平时长
      {
    delay(1);
    N++;           
    if (N>=30)
	 { EX1=1;
	 return;}                  //0.14ms计数过长自动离开。
      }                        //高电平计数完毕                
     IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
     if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”
     N=0;
  }//end for k
 }//end for j
   
   if (IRCOM[2]!=~IRCOM[3])
   { EX1=1;
     goto LOOP; }

   switch(IRCOM[2])
   {
   		case 0x16:
			distemp = 0;
			break;
		case 0x0c:
			distemp = 1;
			break;
		case 0x18:
			distemp = 2;
			break;
		case 0x5e:
			distemp = 3;
			break;
		case 0x08:
			distemp = 4;
			break;
		case 0x1c:
			distemp = 5;
			break;
		case 0x5a:
			distemp = 6;
			break;
		case 0x42:
			distemp = 7;
			break;
		case 0x52:
			distemp = 8;
			break;
		case 0x4a:
			distemp = 9;
			break;
   }
    L1602_char(2,15,distemp+48);
    EX1 = 1;
	LOOP:; 
} 
/**********************************************************/
void delay(unsigned char x)    //x*0.14MS
{
 unsigned char i;
  while(x--)
 {
  for (i = 0; i<13; i++) {}
 }
}

/**********************************************************/
void delay1(int ms)
{
 unsigned char y;
  while(ms--)
 {
  for(y = 0; y<250; y++)
  {
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  }
 }
}

 


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]