找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4651|回复: 4
收起左侧

单片机红外接收程序(Nokia5110液晶屏显示)

[复制链接]
ID:137504 发表于 2016-9-11 22:23 | 显示全部楼层 |阅读模式
0.png

本例程,实现单片机红外接收解码,并用nokia5110液晶屏来显示内容。完整keil工程文件下载:
http://www.51hei.com/bbs/dpj-55490-1.html


下面是部分程序代码的预览:
主程序:
  1. #include "IR_Receive.h"
  2. #include "Nokia5110.h"
  3. #include "delay.h"

  4. extern uint8_t  IRcode_Type;//红外数据类型,RCA或NEC8或NEC16
  5. extern uint16_t IRcode[2];  //红外数据中的系统码IRcode[0],红外数据中的用户码IRcode[1]
  6. extern uint32_t RCAcode_Original;//RCA协议原码       
  7. extern uint32_t NECcode_Original;//NEC原始数据

  8. void main(void)
  9. {
  10.         IRreceiver_Init();
  11.         Nokia5110_Init();
  12.        
  13.         Nokia5110_WriteString(0,0,"*IR_Receiver*");
  14.         Nokia5110_WriteString(2,0,"Rev:**********");                               
  15.         Nokia5110_WriteString(3,0,"CodeType:****");
  16.         Nokia5110_WriteString(4,0,"SysCode :****");
  17.         Nokia5110_WriteString(5,0,"UserCode:****");
  18.         while(1)
  19.         {
  20.                 if(IRdata_Analysis())//解析成功串口打印正确红外码值
  21.                 {
  22.                         Nokia5110_Clear(1,5);
  23.                         switch(IRcode_Type)
  24.                         {
  25.                                 case IRcode_TypeRCA:
  26.                                 {
  27.                                         Nokia5110_Printf(2,0,"Rev:",RCAcode_Original,Hex);//打印出未进行解析的原始红外RCA数据       
  28.                                         Nokia5110_WriteString(3,0,"CodeType: RCA");
  29.                                         Nokia5110_Printf(4,0,"SysCode : ",IRcode[0],Hex);
  30.                                         Nokia5110_Printf(5,0,"UserCode: ",IRcode[1],Hex);
  31.                                         break;
  32.                                  }
  33.                                 case IRcode_TypeNEC8:
  34.                                 {
  35.                                         Nokia5110_Printf(2,0,"Rev:",NECcode_Original,Hex);//打印出未进行解析的原始红外NEC数据       
  36.                                         Nokia5110_WriteString(3,0,"CodeType: NEC8");
  37.                                         Nokia5110_Printf(4,0,"SysCode : ",IRcode[0],Hex);
  38.                                         Nokia5110_Printf(5,0,"UserCode: ",IRcode[1],Hex);
  39.                                         break;
  40.                                  }
  41.                                 case IRcode_TypeNEC16:
  42.                                 {
  43.                                         Nokia5110_Printf(2,0,"Rev:",NECcode_Original,Hex);//打印出未进行解析的原始红外NEC数据       
  44.                                         Nokia5110_WriteString(3,0,"CodeType:NEC16");
  45.                                         Nokia5110_Printf(4,0,"SysCode:",IRcode[0],Hex);
  46.                                         Nokia5110_Printf(5,0,"UserCode:",IRcode[1],Hex);
  47.                                         break;
  48.                                  }
  49.                                 default:{break;}
  50.                          }
  51.                         IRcode_Type = IRcode_TypeNone;
  52.                         Buzzer_Speak();//解码成功,蜂鸣器响
  53.                  }
  54.    }
  55. }
复制代码
  1. #include "Nokia5110.h"
  2. #include "ASII_Font.h"
  3. #include "IR_Receive.h"

  4. uint8_t Dex_Hex_Buffer[Length_Max];//数据缓冲区
  5. extern uint8_t  IRcode_Type;//定义收到的红外数据类型

  6. /*************************************************************************************
  7. 函数:void Divide_Dex_Hex(uint32_t Num,uint8_t Format)
  8. 功能:数据分离,储存在缓冲中数组中,低位~高位=[0]~[Length_Max-1],返回数据位数
  9. *************************************************************************************/
  10. uint8_t Divide_Dex_Hex(uint32_t Num,uint8_t Format)
  11. {
  12.         signed char i=0;
  13.         uint8_t Num_Cnt = 0;

  14.         for(i=0;i<Length_Max;i++) //缓冲清零
  15.         {
  16.                 Dex_Hex_Buffer[i] = '0';
  17.          }

  18.   if(Num == 0)//Num = 0处理
  19.         {
  20.                 if(Format == Dex)return 1;
  21.                 if(Format == Hex)return 2;
  22.          }

  23.         else if(Format == Dex)//把数据分离成十进制数
  24.         {
  25.                 i = 0;
  26.                 while(Num)
  27.                 {
  28.                         Dex_Hex_Buffer[i] = Num%10+'0';//处理成ASIIC码
  29.                         Num /= 10;
  30.                         Num_Cnt++;
  31.                         i++;
  32.                  }       
  33.          }

  34.         else if(Format == Hex)//把数据分离成十六进制数
  35.         {
  36.                 i = 0;
  37.                 while(Num)
  38.                 {
  39.                         Dex_Hex_Buffer[i] = Num%16;
  40.                         Num /= 16;
  41.                         Num_Cnt++;
  42.                         i++;
  43.                  }
  44.                 for(i=Num_Cnt-1;i>=0;i--)        //把分离出来的十六进制数据处理成ASIIC码
  45.                 {
  46.                         if(Dex_Hex_Buffer[i]<10)
  47.                         {
  48.                                  Dex_Hex_Buffer[i] += 0x30;
  49.                          }
  50.                         else
  51.                         {
  52.                                 Dex_Hex_Buffer[i] = Dex_Hex_Buffer[i]-0x0A+0x41;
  53.                          }
  54.                  }
  55.                 if(Num_Cnt%2)Num_Cnt+=1;  //十六进制返回的位数强制为偶数                 
  56.          }

  57.         return Num_Cnt;//返回数据十进制或十六进制位数
  58. }

  59. /*******************************************************
  60. 函数:void Nokia5110_Write(uint8_t dat,bit data_cmd);
  61. 功能:向Nokia5110中写入数据或命令;
  62. *******************************************************/
  63. void Nokia5110_Write(uint8_t dat,bit data_cmd)
  64. {  
  65.   uint8_t i;
  66.   LCD_CE = 0;                              /*使能5110*/
  67.   LCD_DC = data_cmd;                /*DC=1,写入数据;DC=0,写入命令*/
  68.   for(i=0;i<8;i++)
  69.   {
  70.    if(dat&0x80)
  71.          {
  72.            LCD_DIN = 1;                 
  73.                 }
  74.          else
  75.          {
  76.                  LCD_DIN = 0;
  77.                 }
  78.          LCD_CLK = 0;
  79.          dat<<=1;
  80.          LCD_CLK = 1;
  81.    }
  82.   LCD_CE  = 1;                          /*关闭5110*/
  83. }
  84. /************************************************************************************************
  85. 函数:void Nokia5110_Clear(uint8_t Y_Start, uint8_t Y_End);
  86. 功能:对Nokia5110选择性区域进行清屏;
  87. ***********************************************************************************************/
  88. void Nokia5110_Clear(uint8_t Y_Start, uint8_t Y_End)
  89. {  
  90.   uint16_t i;
  91.         uint16_t AreaSize = 0;
  92.        
  93.   Nokia5110_Write(0x80|0x00,CMD);
  94.         Nokia5110_Write(0x40|Y_Start,CMD);
  95.        
  96.         AreaSize = 84*(Y_End-Y_Start+1);
  97.   for(i=0;i<AreaSize;i++)
  98.         {
  99.                 Nokia5110_Write(0x00,DATA);               
  100.          }
  101. }
  102. /*******************************************************
  103. 函数:void Nokia5110_Init();
  104. 功能:对Nokia5110进行初始化;
  105. *******************************************************/
  106. void Nokia5110_Init(void)
  107. {
  108.   delay_us(10);
  109.   LCD_RST = 0;
  110.         delay_us(10);
  111.   LCD_RST = 1;                                   //RST=1  复位,开始写数据
  112.   Nokia5110_Write(0x21,CMD);  //使用扩展指令集,水平寻址
  113.   Nokia5110_Write(0xC5,CMD);        //写Vop到寄存器
  114.   Nokia5110_Write(0x07,CMD);        //温度系数3
  115.   Nokia5110_Write(0x13,CMD);        //偏置值1:48
  116.   Nokia5110_Write(0x20,CMD);  //使用基本指令集,水平寻址
  117.   Nokia5110_Write(0x0C,CMD);  //选择普通模式
  118.   Nokia5110_Clear(0,5);                         //清屏
  119. }

  120. /*******************************************************
  121. 函数:void Nokia5110_SetRC(uint8_t line,uint8_t lie);
  122. 功能:显示屏坐标设定,R:line=0~5,C:lie=0~13;
  123. *******************************************************/
  124. void Nokia5110_SetRC(uint8_t line,uint8_t lie)       
  125. {
  126.   lie*=6;
  127.   Nokia5110_Write(0x40|line,CMD);
  128.         Nokia5110_Write(0x80|lie, CMD);
  129. }
  130. /*******************************************************
  131. 函数:void Nokia5110_WriteChar(uint8_t Char);
  132. 功能:向5110液晶屏中写入一个字节;
  133. *******************************************************/
  134. void Nokia5110_WriteChar(uint8_t Char)
  135. {
  136.   uint8_t i,j;
  137.         i = Char-0x20;
  138.         for(j=0;j<6;j++)
  139.         {
  140.                 Nokia5110_Write(ASII_Font[i][j],DATA);
  141.          }
  142. }
  143. /*************************************************************************************
  144. 函数:void Nokia5110_WriteString(uint8_t line,uint8_t lie,uint8_t *pString);
  145. 功能:向5110液晶屏指定地址开始写入字符串;
  146. ************************************************************************************/
  147. void Nokia5110_WriteString(uint8_t line,uint8_t lie,uint8_t *pString)
  148. {
  149.         Nokia5110_SetRC(line,lie);
  150.        
  151.         while(*pString != '\0')
  152.         {
  153.                 Nokia5110_WriteChar(*pString);
  154.                 pString++;
  155.          }
  156. }
  157. /*************************************************************************************
  158. 函数:void Nokia5110_ClearData(uint8_t line,uint8_t lie,uint8_t Length);
  159. 功能:清除指定坐标中的指定长度数据
  160. ************************************************************************************/
  161. void Nokia5110_ClearData(uint8_t line,uint8_t lie,uint8_t Length)
  162. {
  163.         uint8_t i=0;
  164.         Nokia5110_SetRC(line,lie);
  165.         for(i=0;i<Length;i++)
  166.         {
  167.                 Nokia5110_WriteChar(' ');
  168.          }
  169. }
  170. /***************************************************************************************************
  171. 函数:void Nokia5110_Printf(uint8_t hang,uint8_t,lie,uint8_t *String,uint32_t Value,uint8_t Format);
  172. 功能:以十进制或者十六进制往5110液晶屏中写ASIIC数据;
  173. **************************************************************************************************/
  174. void Nokia5110_Printf(uint8_t hang,uint8_t lie,uint8_t *pString,uint32_t Value,uint8_t Format)
  175. {
  176.         uint8_t i;
  177.         static uint8_t SysCode4Bit_Flag = 0;//系统码为4位标志位,用于显示NEC16系统码高八位为0
  178.         uint8_t Num_Cnt = 0;

  179.         Num_Cnt = Divide_Dex_Hex(Value,Format);
  180.        
  181.         if((IRcode_Type==IRcode_TypeRCA)&&(Num_Cnt==4))//处理RCA系统码为0的情况,原码需要把00显示出来
  182.         {
  183.                 Num_Cnt = 6;
  184.    }
  185.         if((IRcode_Type==IRcode_TypeNEC8)&&(Num_Cnt==6))//处理NEC8系统码为0的情况,原码需要把00显示出来
  186.         {
  187.                 Num_Cnt = 8;
  188.    }
  189.         if((IRcode_Type==IRcode_TypeNEC16)&&(Num_Cnt==6))//处理NEC16系统码高八位为0的情况,原码需要把00显示出来
  190.         {
  191.                 Num_Cnt = 8;
  192.                 SysCode4Bit_Flag = 1;
  193.    }
  194.         if((SysCode4Bit_Flag==1)&&(Num_Cnt==2))//处理NEC16系统码高八位为0的情况,系统码需要把00显示出来
  195.         {
  196.                 SysCode4Bit_Flag = 0;
  197.                 Num_Cnt = 4;
  198.    }
  199.                
  200.         Nokia5110_WriteString(hang,lie,pString);
  201.         if(Format==Hex)
  202.         {
  203.                 Nokia5110_WriteChar('0');
  204.                 Nokia5110_WriteChar('x');
  205.          }

  206.         for(i=0;i<Num_Cnt;i++)
  207.         {
  208.                 Nokia5110_WriteChar(Dex_Hex_Buffer[(Num_Cnt-1)-i]);
  209.          }
  210. }
复制代码

  1. #include "STC89Cx_it.h"
  2. #include "IR_Receive.h"

  3. //红外解码原理:把红外中的载波解调成低电平,把红外中的低电平解调成高电平输出
  4. //识别原理:识别一个完整周期的高低电平总时间来识别头码和"0"或"1"的值

  5. #define Rev_Header      0x00          //数据接收状态:接收头码0xAA或oxAB
  6. #define Rev_Length      0x01          //数据接收状态:接收头码数据包长度
  7. #define Rev_DataPackage 0x02         //数据接收状态:接收数据包

  8. extern uint8_t IRcode_Type;                          //声明收到的红外数据类型
  9. extern uint8_t IRdataReceive_Flag;//声明接收红外数据状态,等待or接收中or接收完毕
  10. extern uint32_t IRcode_Buffer;                //红外数据缓存
  11. uint8_t CycleTime = 0;                                 //存储完整周期时间(高电平+低电平)
  12. /**********************************************
  13. 函数:void INT0_Handler(void);
  14. 功能:外部中断0中断处理函数;
  15. ***********************************************/
  16. void INT0_Handler(void) interrupt 0
  17. {
  18. }

  19. /**********************************************
  20. 函数:void TIME0_Handler(void);
  21. 功能:定时器0中断处理函数;
  22. ***********************************************/
  23. void TIME0_Handler(void) interrupt 1
  24. {
  25.         CycleTime++;
  26.         if(CycleTime==255)CycleTime=0;         
  27. }

  28. /**********************************************
  29. 函数:void INT1_Handler(void);
  30. 功能:外部中断1中断处理函数;
  31. ***********************************************/
  32. void INT1_Handler(void) interrupt 2
  33. {
  34.         static uint8_t EnterINT0_CNT = 0;//存储进入外部中断次数
  35.         static uint8_t Rev_State = Rev_Header;//定义接收状态
  36.         uint8_t CycleTime_Buffer=0;                         //周期时间缓冲变量
  37.        
  38.         EnterINT0_CNT++;                                                                 //每进入中断一次加1
  39.         //第一次进入中断周期清零,打开定时器0准备计时
  40.         if(EnterINT0_CNT==1)
  41.         {
  42.                 CycleTime=0;
  43.                 IRcode_Buffer=0;
  44.                 TR0=1;
  45.          }
  46.         else//之后先读时间,再进行清零
  47.         {
  48.                 CycleTime_Buffer=CycleTime;
  49.                 CycleTime = 0;
  50.          }
  51.          
  52.          //开始识别头码
  53.         if((Rev_State==Rev_Header)&&(EnterINT0_CNT==2))         
  54.         {
  55.                 Rev_State = Rev_DataPackage;
  56.                 if((CycleTime_Buffer>60)&&(CycleTime_Buffer<100))                         //头码时间位于6.0ms~10ms则为RCA码(标准8ms)
  57.                 {
  58.                         IRcode_Type = IRcode_TypeRCA;
  59.                  }
  60.                 else if((CycleTime_Buffer>110)&&(CycleTime_Buffer<160))//头码时间位于11ms~16ms(必须是大于11ms)则为NEC码(标准13.5ms)
  61.                 {
  62.                         IRcode_Type = IRcode_TypeNEC8;
  63.                  }
  64.                 else//如果都不是,则认为没有收到头码
  65.                 {
  66.                         TR0=0;
  67.                         IRcode_Buffer = 0;
  68.                         EnterINT0_CNT = 0;
  69.                         Rev_State = Rev_Header;
  70.                  }
  71.          }
  72.          
  73.         if((Rev_State==Rev_DataPackage)&&(EnterINT0_CNT>2))//开始解码
  74.         {
  75.                 IRcode_Buffer <<= 1;
  76.                 switch(IRcode_Type)
  77.                 {
  78.                         case IRcode_TypeRCA:
  79.                         {
  80.                                 if((CycleTime_Buffer>10)&&(CycleTime_Buffer<20))//码值时间位于1.0ms~2.0ms则为RCA'1'(标准1.5ms)
  81.                                 {
  82.                                         IRcode_Buffer |= (uint32_t)0x01;
  83.                                  }
  84.                                 else if((CycleTime_Buffer>20)&&(CycleTime_Buffer<30))//码值时间位于1.0ms~2.0ms则为RCA'0'(标准2.5ms)
  85.                                 {
  86.                                         IRcode_Buffer |= (uint32_t)0x00;
  87.                                  }
  88.                                 else
  89.                                 {
  90.                                         TR0=0;
  91.                                         IRcode_Buffer = 0;
  92.                                         EnterINT0_CNT = 0;
  93.                                         Rev_State = Rev_Header;
  94.                                  }
  95.                                 break;
  96.                          }
  97.                         case IRcode_TypeNEC8:
  98.                         {
  99.                                 if((CycleTime_Buffer>6)&&(CycleTime_Buffer<16))//码值时间位于0.6ms~1.6ms则为NEC'0'(标准1.124ms)
  100.                                 {
  101.                                         IRcode_Buffer |= (uint32_t)0x00;
  102.                                  }
  103.                                 else if((CycleTime_Buffer>16)&&(CycleTime_Buffer<28))//码值时间位于1.6ms~2.8ms则为NEC'1'(标准2.25ms)
  104.                                 {
  105.                                         IRcode_Buffer |= (uint32_t)0x01;
  106.                                  }
  107.                                 else
  108.                                 {
  109.                                         TR0=0;
  110.                                         IRcode_Buffer = 0;
  111.                                         EnterINT0_CNT = 0;
  112.                                         Rev_State = Rev_Header;
  113.                            }
  114.                                 break;
  115.                          }
  116.                  }
  117.                  
  118.                 if(((EnterINT0_CNT==26)&&((IRcode_Type==IRcode_TypeRCA)))||((EnterINT0_CNT==34)&&((IRcode_Type==IRcode_TypeNEC8))))//RCA码加头码25,NEC码加头码33位,解码进入中断次数分别为26和34
  119.                 {
  120.                         TR0=0;//解码完毕关闭定时器
  121.                         EnterINT0_CNT=0;
  122.                         IRdataReceive_Flag=IRdataReceive_Success;
  123.                         Rev_State = Rev_Header;//准备下一次接收
  124.                  }
  125.          }
  126. }
  127. /**********************************************
  128. 函数:void TIME1_Handler(void);
  129. 功能:定时器1中断处理函数;
  130. ***********************************************/
  131. void TIME1_Handler(void) interrupt 3
  132. {
  133. }

  134. /**********************************************
  135. 函数:void USART_Handler(void);
  136. 功能:串口中断处理函数;
  137. ***********************************************/
  138. void USART_Handler(void) interrupt 4
  139. {

  140. }

  141. /**********************************************
  142. 函数:void TIME2_Handler(void);
  143. 功能:定时器2中断处理函数;
  144. ***********************************************/
  145. void TIME2_Handler(void) interrupt 5
  146. {
  147.          
  148. }
复制代码




评分

参与人数 1黑币 +2 收起 理由
tstzyk + 2

查看全部评分

回复

使用道具 举报

ID:79544 发表于 2018-3-28 17:08 | 显示全部楼层
没有试验不知道好用不。还得感谢分享!!赞
回复

使用道具 举报

ID:299539 发表于 2018-3-30 17:11 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:342790 发表于 2018-6-13 20:21 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:791490 发表于 2020-6-28 16:53 | 显示全部楼层
这个有带仿真原理图吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表