Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1965244
  • 博文数量: 356
  • 博客积分: 8284
  • 博客等级: 中将
  • 技术积分: 4580
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-15 20:25
个人简介

天行健,君子以自强不息

文章分类

全部博文(356)

文章存档

2018年(1)

2016年(4)

2015年(13)

2014年(14)

2013年(2)

2012年(25)

2011年(43)

2010年(65)

2009年(189)

分类: C/C++

2012-11-25 11:44:12

/*-----------------------------------------------
程序功能:红外遥控器控制继电器开关,并将按键号和其编码制串口输出
硬件平台:51单片机(12M晶振)
串口输出波特率:4800
作者:Mr Lee
创建日期:2012.11.24
更新日期:2012.11.25
------------------------------------------------*/
#include    //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include
#include

#define uchar unsigned char
#define uint  unsigned int
#define LZ_LCD160_DEBUG 0

#define TURE 1
#define FALSE 0

sbit IR=P3^2;  //红外接口标志(1803红外接收头凸面朝上,从左至右依次是信号线、地、电源)
sbit jidianqi_out1=P1^2;//继电器1控制输出脚
sbit jidianqi_out2=P1^3;//继电器2控制输出脚

sbit RS = P2^4;//Pin4
sbit RW = P2^5;//Pin5
sbit E  = P2^6;//Pin6
#define Data P0//数据端口

void uart_printf(unsigned char *buff);
void mDelay(unsigned int Delay) 
{ unsigned int i;
 for(;Delay>0;Delay--)
 { for(i=0;i<124;i++)
  {;}
 }
}

unsigned int hour,minute,second,count;
char code Tab[16]="0123456789ABCDEF";

char data TimeNum[]="                ";
char data Test1[]="                  ";

/******************************************************************/
/*                    变量声明                                    */
/******************************************************************/
unsigned char  irtime;//红外用全局变量
bit irpro_ok,irok;
unsigned char   IRcord[4];  //处理后的红外码,分别是 客户码,客户码,数据码,数据码反码
unsigned char   irdata[33]; //33个高低电平的时间数据

/******************************************************************/
/*                    函数声明                                    */
/******************************************************************/
void Ir_work(void);
void Ircordpro(void);
void ShowString (unsigned char line,char *ptr);
/******************************************************************/
/*                    定时器0中断服务函数                         */
/******************************************************************/

void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数
{
  irtime++;                             //用于计数2个下降沿之间的时间
}

/******************************************************************/
/*                    外部中断0函数                               */
/******************************************************************/
void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数
{
  static unsigned char  i;             //接收红外信号处理
  static bit startflag;                //是否开始处理标志位

 if(startflag)                         
 {
   
    if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
            i=0;
     
    irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
    irtime=0;
    i++;
    if(i==33)
      {
  irok=1;
i=0;
  }
          }
 
  else
{irtime=0;startflag=1;}

}

/******************************************************************/
/*                   定时器0初始化                                */
/******************************************************************/
/*
void TIM0init(void)//定时器0初始化
{

  TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  TH0=0x00; //重载值
  TL0=0x00; //初始化值
  ET0=1;    //开中断
  TR0=1;    
}  */
/******************************************************************/
/*                   外部中断初始化                               */
/******************************************************************/
/*
void EX0init(void)
{
 IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
 EX0 = 1;   //使能外部中断
 EA = 1;    //开总中断
}
*/
/******************************************************************/
/*                    红外键值处理                                */
/******************************************************************/

 void Ir_work(void)        //红外键值散转程序
 {
       unsigned short temp;
       TimeNum[5] = Tab[IRcord[0]/16];   //处理客户码并显示
  TimeNum[6] = Tab[IRcord[0]%16];
  TimeNum[8] = Tab[IRcord[1]/16];   //处理客户码并显示
  TimeNum[9] = Tab[IRcord[1]%16];
  TimeNum[11] = Tab[IRcord[2]/16];  //处理数据码并显示
  TimeNum[12] = Tab[IRcord[2]%16];
  TimeNum[14] = Tab[IRcord[3]/16];  //处理数据反码并显示
  TimeNum[15] = Tab[IRcord[3]%16];
 
       #ifdef LCD1602
       ShowString(1,TimeNum);//显示处理过后的码值
  #else
  #if 1
  temp=(IRcord[0] << 8) | IRcord[1];
  if(temp!=0x00ff)
  return;
  
  temp=(IRcord[2] << 8) | IRcord[3];
  
  switch(temp)
  {
  case 0x16E9: uart_printf("k0");break;
case 0x0cf3:    uart_printf("k1");jidianqi_out1=0;break;
case 0x18E7: uart_printf("k2");jidianqi_out2=0;break;
case 0x5EA1: uart_printf("k3");break;
case 0x08F7: uart_printf("k4");jidianqi_out1=1;break;
case 0x1CE3: uart_printf("k5");jidianqi_out2=1;break;
case 0x5AA5: uart_printf("k6");break;
case 0x42BD: uart_printf("k7");break;
case 0x52AD: uart_printf("k8");break;
case 0x4AB5: uart_printf("k9");break;
case 0x45BA: uart_printf("on off");break;
case 0x46B9: uart_printf("mode");break;
case 0x47B8: uart_printf("sound");break;
case 0x44BB:   uart_printf("left");break;
case 0x40BF:   uart_printf("right");break;
case 0x43BC:   uart_printf("pause");break;
case 0x07f8:   uart_printf("-");break;
case 0x15EA:   uart_printf("+");break;
case 0x09F6:   uart_printf("EQ");break;
case 0x19E6:   uart_printf("100+");break;
case 0x0DF2:   uart_printf("return");break;
default:
uart_printf("unkown key or err");break;
  }
  uart_printf("\r\n");
  #endif
  uart_printf(TimeNum);
  uart_printf("\r\n");
  #endif
  irpro_ok=0;           //处理完成后清楚标志位

  }

/******************************************************************/
/*                    红外解码函数处理                            */
/******************************************************************/
void Ircordpro(void)//红外码值处理函数
  unsigned char i, j, k;
  unsigned char cord,value;

  k=1;
  for(i=0;i<4;i++)      //处理4个字节
     {
      for(j=1;j<=8;j++) //处理1个字节8位
         {
          cord=irdata[k];
          if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
   {
             value=value|0x80;
}
          else 
   {
             value=value;
}
          if(j<8)
   {
value=value>>1;
}
           k++;
         }
     IRcord[i]=value;
     value=0;     
     } irpro_ok=1;//处理完毕标志位置1
    
}

#if LZ_LCD160_DEBUG==1
/******************************************************************/
/*                    微秒延时函数                                */
/******************************************************************/
void DelayUs(unsigned char us)//delay us
{
 unsigned char uscnt;
 uscnt=us>>1;/* Crystal frequency in 12MHz*/
 while(--uscnt);
}
/******************************************************************/
/*                    毫秒函数声明                                */
/******************************************************************/
void DelayMs(unsigned char ms)//delay Ms
{
 while(--ms)
   {
     DelayUs(250);
     DelayUs(250);
DelayUs(250);
DelayUs(250);
   }
}

/******************************************************************/
/*                   写入命令函数                                 */
/******************************************************************/
void WriteCommand(unsigned char c)
{
 DelayMs(5);//操作前短暂延时,保证信号稳定
 E=0;
 RS=0;
 RW=0;
 _nop_();
 E=1;
 Data=c;
 E=0;
}
/******************************************************************/
/*                   写入数据函数                                 */
/******************************************************************/
void WriteData(unsigned char c)
{
 DelayMs(5);  //操作前短暂延时,保证信号稳定
 E=0;
 RS=1;
 RW=0;
 _nop_();
 E=1;
 Data=c;
 E=0;
 RS=0;
}
/******************************************************************/
/*                   写入字节函数                                 */
/******************************************************************/
void ShowChar(unsigned char pos,unsigned char c)
{
 unsigned char p;
 if (pos>=0x10)
    p=pos+0xb0; //是第二行则命令代码高4位为0xc
 else 
    p=pos+0x80; //是第二行则命令代码高4位为0x8
 WriteCommand (p);//写命令
 WriteData (c);   //写数据
}
/******************************************************************/
/*                   写入字符串函数                               */
/******************************************************************/
void ShowString (unsigned char line,char *ptr)
{
 unsigned char l,i;
 l=line<<4;
 for (i=0;i<16;i++)
  ShowChar (l++,*(ptr+i));//循环显示16个字符
}
/******************************************************************/
/*                   初始化函数                                   */
/******************************************************************/
void InitLcd()
{
 DelayMs(15);
 WriteCommand(0x38); //display mode
 WriteCommand(0x38); //display mode
 WriteCommand(0x38); //display mode
 WriteCommand(0x06); //显示光标移动位置
 WriteCommand(0x0c); //显示开及光标设置
 WriteCommand(0x01); //显示清屏

}

#endif
/******************************************************************/
/*                   主函数                                       */
/******************************************************************/
void uart_init(void)
{
 TMOD=0x20;     //TMOD=0
 TH1=0xf3;      //12MHZ   ,BPS:4800,N,8,1,0xf3=243
 TL1=0xf3;
 PCON=0x80;     //方式一,8位数据位,一位起始位和一位结束位
 TR1=1;         //开启定时器1
 SCON=0x40;     //串口通信控制寄存器  模式一
}
void uart_putchar(unsigned char dat)
{
SBUF=dat; //把数据送给sbuf缓存器中
while(TI!=1);//发送标志位 TI如果发送了为1,没发送为0,没发送等待,到了退出循环
TI=0;  //到了,TI清为0

}
void uart_printf(unsigned char *buff)
{

while(*buff)
        uart_putchar(*buff++);
}
   
#if 0
void main1()
 uchar t[]="12";
 uart_init();
 while(1)
 {
   uart_printf("aba");
   mDelay(500);
 }
 
 
#endif

void main(void)
{
//EX0init(); //初始化外部中断
IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1;   //使能外部中断
EA = 1;    //开总中断
//TIM0init();//初始化定时器
TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
TH0=0x00; //重载值
TL0=0x00; //初始化值
ET0=1;    //开中断
TR0=1; 
TMOD|=0x20;     //TMOD=0
TH1=0xf3;      //12MHZ   ,BPS:4800,N,8,1,0xf3=243
TL1=0xf3;
PCON=0x80;     //方式一,8位数据位,一位起始位和一位结束位
TR1=1;         //?????????????????????????????
SCON=0x40;     //串口通信控制寄存器  模式一

 #if LZ_LCD1602_DEBUG==1
InitLcd(); //初始化液晶
DelayMs(15);
sprintf(Test1," ");  //显示第一行固定信息
ShowString(0,Test1);
sprintf(TimeNum,"Code            ");//显示第二行固定信息
ShowString(1,TimeNum);
 #endif


 while(1)//主循环
   {
    if(irok)                        //如果接收好了进行红外处理
 {   
  Ircordpro();
    irok=0;
 }

    if(irpro_ok)                  //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
 {
  Ir_work();
   }
   }
}
//1838红外接收头
从左至右:依次为:信号、GND、VCC.
注:本工程仅main.c一个c文件。
实物图:
阅读(3668) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~