專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

紅外解碼程序(用1602顯示碼值)

作者:我行天下   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年03月31日   【字體:

#include<reg52.h> 
#define uchar unsigned char
#define uint unsigned int
sbit beep=P1^7;
bit startflag;  //定義一個(gè)掃描開始標(biāo)志位
bit irreceok;//紅外接收OK標(biāo)志位
bit irprosok;//紅外接收處理OK標(biāo)志位
uchar irdata[33];//定義一個(gè)存放編碼的數(shù)組。引導(dǎo)碼1位,客戶碼8位,客戶反碼8位,數(shù)據(jù)碼8位,數(shù)據(jù)反碼8位 ,共33位
uchar bitnum;//接收到的第幾位數(shù)據(jù)的標(biāo)志位
uchar irtime;//定義紅外掃描時(shí)間
uchar ircode[4];//為四個(gè)碼值定義一個(gè)數(shù)組存放,把四位碼分開
uchar disp[8];//四組數(shù)據(jù),每組拆成高四位和低四位,共八個(gè)元素
/**************1602部分******************/
sbit lcden=P1^2;
sbit lcdrs=P1^0;
sbit lcdrw=P1^1;
/*char code Tab[]={'0','1','2','3','4','5','6','7','8',
'9','A','B','C','D','E','F'};*/
char code Tab[]="0123456789abcdef";
void delay(uint z) //延時(shí)子程序
{
  uint x,y;
  for(x=z;x>0;x--)
     for(y=220;y>0;y--);
}

void write_com(uchar com)//定義一個(gè)帶參數(shù)的寫命令子程序
{
 lcdrs=0; //1602的rs為0時(shí),接收命令,為1時(shí)接收數(shù)據(jù)
 P0=com;//把void write_com(uchar com)中的COM中的數(shù)據(jù)給P0口
 delay(2);
 lcden=1;
 delay(2);
 lcden=0;
 delay(2);
}

void init_1602()//定義一個(gè)初始化子程序
{
 lcden=0;
 lcdrw=0;
 write_com(0x38);//調(diào)用 write_com子程序并把0x38賦給P0口,顯示模式打開
 write_com(0x0f);//調(diào)用 write_com子程序并把“開顯示,顯示光標(biāo),光標(biāo)閃爍”指令碼賦給P0口
 write_com(0x06);//調(diào)用 write_com子程序并把“地址指針加1,整屏不移動(dòng)”指令碼賦給P0口
 //write_com(0x80+0x10);//數(shù)據(jù)指針初始化,讓指針指向可顯示的最右端
 write_com(0x80);//數(shù)據(jù)指針初始化,讓指針指向最左端,顯示從第一行開始
 write_com(0x01);//調(diào)用 write_com子程序并把"清零指"令碼賦給P0口
 }
 
void write_dat(uchar dat)//定義一個(gè)帶參數(shù)的寫數(shù)據(jù)子程序
{
 lcdrs=1; //1602的rs為0時(shí),接收命令,為1時(shí)接收數(shù)據(jù)
 P0=dat;//把void write_shu(uchar shu)中的COM中的數(shù)據(jù)給P0口
 delay(2);
 lcden=1;
 delay(2);
 lcden=0;
 delay(2);
}
 
void delayms(uint t)
{
 uint i,j;
 for(i=t;i>0;i--)
  for(j=110;j>0;j--);
}
void timer0init()//定時(shí)器O初始化
{
 TMOD=0x02;//定時(shí)器設(shè)成方式2,因?yàn)榉绞?可以自動(dòng)重裝初值
 TH0=0x00;//高位設(shè)為O
 TL0=0x00;//低位設(shè)為O
 ET0=1; //中斷打開
 EA=1;//總中斷打開
 TR0=1;//定時(shí)器打開
}

void int0init()//外部中斷O初始化,按P3。2
{
 IT0=1;//設(shè)為下降沿觸發(fā)方式。IT0=0為低電平觸發(fā)。因?yàn)榧t外輸入高時(shí),接收為低,要從低開始計(jì)時(shí)
 EX0=1;//外部中斷打開
 EA=1;//總中斷打開
}

void irpros()//紅外提取處理程序
{
  uchar i,k,j,irvalue;
  k=1;//第一k=0是引導(dǎo)碼,不須要。所以從K=1開始提取編碼,把K=0的引導(dǎo)碼去掉
 for(j=0;j<4;j++)//共有四個(gè)碼,所以循環(huán)四次
   {
     for(i=0;i<8;i++)//每個(gè)碼八位,循環(huán)八次
    {
     irvalue=irvalue>>1;//irvalue低位在前,高位在后,所以右移,判斷8次,右移7次
   if(irdata[k]>6)//如果兩個(gè)中斷的時(shí)間為1.125MS,說明傳的是0,1.125/0.255=4.4個(gè)irtime,
   //如果兩個(gè)中斷的時(shí)間為1.125MS,說明傳的是1,2.25/0.255=8.8個(gè)irtime,
   //我取中斷值6;如果irdata大于6,說明是1,小于6說明是0;
    {
     irvalue=irvalue|0x80;
    }
    k++;//每提一次,K自增一次,一共要33次
  }
  ircode[j]=irvalue;
   }
  irprosok=1;
  beep=0;
  delay(3);
  beep=1;
}
void irwork()
{
 disp[0]=ircode[0]/16;//取高四位
 disp[1]=ircode[0]%16;//取低四位
 disp[2]=ircode[1]/16;//取高四位
 disp[3]=ircode[1]%16;//取低四位
 disp[4]=ircode[2]/16;//取高四位
 disp[5]=ircode[2]%16;//取低四位
 disp[6]=ircode[3]/16;//取高四位
 disp[7]=ircode[3]%16;//取低四位
}
void display()
{
 write_com(0x80);
 write_dat(Tab[disp[0]]);
 write_dat(Tab[disp[1]]);
 write_dat(Tab[disp[2]]);
 write_dat(Tab[disp[3]]);
 write_dat(Tab[disp[4]]);
 write_dat(Tab[disp[5]]);
 write_dat(Tab[disp[6]]);
 write_dat(Tab[disp[7]]);
}
void main()
{
 init_1602();
 timer0init();
 int0init();
   while(1)
     {
  if(irreceok)//判斷接收是否OK
     {
   irpros();//接收OK就要處理.把數(shù)據(jù)從irdata中提出來
         irreceok=0;//要把irreceok清0,為下一次接收做準(zhǔn)備
  }
  if(irprosok)
     {
   irwork();//如果處理OK,把數(shù)據(jù)分離,可以去顯示
   irprosok=0;//要把irprosok清0,為下一次處理做準(zhǔn)備
  }
    display();//顯示函數(shù)還沒寫,有待完善
  
  }
 
}

void timer0() interrupt 1//定時(shí)器0中斷函數(shù)
{
irtime++;/*irtime為字符型,最大為255,輸入開始時(shí)讀一次irtime
然后清0,結(jié)束再讀一次,irtime乘以255就是一次掃描定時(shí)的時(shí)間*/
}
void int0() interrupt 0//外部中斷0函數(shù),這是關(guān)鍵
{
 if(startflag)//如果startflag=1就開始接數(shù)據(jù)
  {
     if(irtime>30) //接收引導(dǎo)碼,引導(dǎo)碼有9MS,9/0.256=33.15,在這就取32即可
                //說明這時(shí)檢測(cè)到了引導(dǎo)碼
  {
    bitnum=0;//收到引導(dǎo)碼后,bitnum清O準(zhǔn)備裝數(shù)據(jù)
  }
  irdata[bitnum]=irtime;//第1個(gè)bitnum=0的數(shù)據(jù)被裝入數(shù)組。
  irtime=0;//清0就不會(huì)對(duì)下次有影響
     bitnum++; //不停地給數(shù)組加入新數(shù)據(jù)
 
   if(bitnum==33)//如果bitmun=33,說明一幀數(shù)據(jù)傳完
    {
     bitnum=0;//bitnum清0為接收下一幀做準(zhǔn)備
     irreceok=1;//主函數(shù)只要判斷irreceok是否為1做出后面的決定
    }
     
  }
else //
    {
  startflag=1;
  irtime=0;
 }
}

關(guān)閉窗口

相關(guān)文章