文章目录

  • 代码

代码

/**************************************************************************************
*                     红外通信实验                                                  *
实现现象:下载程序后,数码管显示红外遥控键值数据
注意事项:    红外遥控器内的电池绝缘片一定要抽掉
***************************************************************************************/#include "reg52.h"             //此文件中定义了单片机的一些特殊功能寄存器
#include <INTRINS.H>
#include <intrins.h>      //因为要用到左右移函数,所以加入这个头文件#define led P2    //将P2口定义为led 后面就可以使用led代替P2口typedef unsigned int u16;      //对数据类型进行声明定义
typedef unsigned char u8;   sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit led_1=P2^0;
sbit Beep=P1^5;sbit IRIN=P3^2;u8 IrValue[6];         //  四组数据
u8 Time;u8 DisplayData[8];    //
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、H的显示码unsigned char n=0;  //n为节拍常数变量
unsigned char code music_tab[] ={
0x18, 0x30, 0x1C , 0x10, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,
0x20, 0x40, 0x1C , 0x10,
0x18, 0x10, 0x20 , 0x10,
0x1C, 0x10, 0x18 , 0x40,
0x1C, 0x20, 0x20 , 0x20,
0x1C, 0x20, 0x18 , 0x20,
0x20, 0x80, 0xFF , 0x20,
0x30, 0x1C, 0x10 , 0x18,
0x20, 0x15, 0x20 , 0x1C,
0x20, 0x20, 0x20 , 0x26,
0x40, 0x20, 0x20 , 0x2B,
0x20, 0x26, 0x20 , 0x20,
0x20, 0x30, 0x80 , 0xFF,
0x20, 0x20, 0x1C , 0x10,
0x18, 0x10, 0x20 , 0x20,
0x26, 0x20, 0x2B , 0x20,
0x30, 0x20, 0x2B , 0x40,
0x20, 0x20, 0x1C , 0x10,
0x18, 0x10, 0x20 , 0x20,
0x26, 0x20, 0x2B , 0x20,
0x30, 0x20, 0x2B , 0x40,
0x20, 0x30, 0x1C , 0x10,
0x18, 0x20, 0x15 , 0x20,
0x1C, 0x20, 0x20 , 0x20,
0x26, 0x40, 0x20 , 0x20,
0x2B, 0x20, 0x26 , 0x20,
0x20, 0x20, 0x30 , 0x80,
0x20, 0x30, 0x1C , 0x10,
0x20, 0x10, 0x1C , 0x10,
0x20, 0x20, 0x26 , 0x20,
0x2B, 0x20, 0x30 , 0x20,
0x2B, 0x40, 0x20 , 0x15,
0x1F, 0x05, 0x20 , 0x10,
0x1C, 0x10, 0x20 , 0x20,
0x26, 0x20, 0x2B , 0x20,
0x30, 0x20, 0x2B , 0x40,
0x20, 0x30, 0x1C , 0x10,
0x18, 0x20, 0x15 , 0x20,
0x1C, 0x20, 0x20 , 0x20,
0x26, 0x40, 0x20 , 0x20,
0x2B, 0x20, 0x26 , 0x20,
0x20, 0x20, 0x30 , 0x30,
0x20, 0x30, 0x1C , 0x10,
0x18, 0x40, 0x1C , 0x20,
0x20, 0x20, 0x26 , 0x40,
0x13, 0x60, 0x18 , 0x20,
0x15, 0x40, 0x13 , 0x40,
0x18, 0x80, 0x00
};
//
void int0()  interrupt 1   //采用中断0 控制节拍
{  TH0=0xd8;   TL0=0xef;   n--;
}
//  void delay_2(u16 i)
{while(i--);
}void delay (unsigned char m)   //控制频率延时
{   unsigned i=3*m;   while(--i);
}
//
void delayms(unsigned char a)  //豪秒延时子程序
{   while(--a);                  //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!
}  /*******************************************************************************
* 函 数 名         : delay
* 函数功能         : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay_1(u16 i)    //时间不准确 运行一步约10us 和内部晶振有关
{while(i--);
}/*******************************************************************************
* 函数名         :DigDisplay()
* 函数功能       :数码管显示函数
* 输入           : 无
* 输出             : 无
*******************************************************************************/
void DigDisplay()
{u8 i;for(i=0;i<3;i++){switch(i)   //位选,选择点亮的数码管,{case(0):LSA=0;LSB=0;LSC=0; break;//显示第0位case(1):LSA=1;LSB=0;LSC=0; break;//显示第1位case(2):LSA=0;LSB=1;LSC=0; break;//显示第2位 }P0=DisplayData[2-i];//发送数据delay(100); //间隔一段时间扫描  P0=0x00;//消隐}
}/*******************************************************************************
* 函数名         : IrInit()
* 函数功能         : 初始化红外线接收
* 输入           : 无
* 输出             : 无
*******************************************************************************/void IrInit()
{IT0=1;//下降沿触发EX0=1;//打开中断0允许EA=1;   //打开总中断IRIN=1;//初始化端口
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/void main()
{   unsigned char p,m;   //m为频率常数变量    unsigned char i=0;   TMOD&=0x0f;   TMOD|=0x01;   TH0=0xd8;TL0=0xef;   IE=0x82; IrInit();while(1){  DisplayData[0] = smgduan[IrValue[2]/16];       //     IrValue2是  第一个 数据码    解码  码中16进制高位   0000~1111 最大为15DisplayData[1] = smgduan[IrValue[2]%16];       //解码   数据 码中16进制低位      0000~1111 最大为15DisplayData[2] = smgduan[16];     //   字符H    如果想接收用户码也可以修改01就行了   遥控器上 0123456789就是内部码就是十六进制,?DigDisplay();                           //你按1就是数码管显示**H(16进制)if((DisplayData[0]==0x06)&&(DisplayData[1]==0x7f)&&(DisplayData[2]==0x76)){led=0x00;}
//      else
//      {//          led=0xFF;
//      }if((DisplayData[0]==0x3f)&&(DisplayData[1]==0x39)&&(DisplayData[2]==0x76)){Beep=~Beep;}else{Beep=0;}if((DisplayData[0]==0x6d)&&(DisplayData[1]==0x79)&&(DisplayData[2]==0x76)){//      unsigned char p,m;   //m为频率常数变量
//      unsigned char i=0;
//      TMOD&=0x0f;
//      TMOD|=0x01;
//      TH0=0xd8;TL0=0xef;
//      IE=0x82;   play:   //   while(1)   //    {   a: p=music_tab[i];   if(p==0x00)       { i=0, delayms(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍    else if(p==0xff)  { i=i+1;delayms(100),TR0=0; goto a;}  //若碰到休止符,延时100ms,继续取下一音符    else         {m=music_tab[i++], n=music_tab[i++];}  //取频率常数 和 节拍常数    TR0=1;                                             //开定时器1    while(n!=0) Beep=~Beep,delay(m);                         //等待节拍完成, 通过P1口输出音频(可多声道哦!)    TR0=0;                                             //关定时器1    //    } }
//  else
//  {// }//9就是显示09H,,可以利用这个起到遥控的作用    你按其他键估计就是别的乱码就是这个道理if((DisplayData[0]==0x3f)&&(DisplayData[1]==0x7f)&&(DisplayData[2]==0x76)){u8 i;led=0xfe;delay_2(50000); //大约延时450ms    /*      for(i=0;i<8;i++){P2=~(0x01<<i);     //将1右移i位,然后将结果取反赋值到P2口delay(50000); //大约延时450ms}*/      for(i=0;i<7;i++)   //将led左移一位{led=_crol_(led,1);delay_2(50000); //大约延时450msif(((DisplayData[0]==0x3f)&&(DisplayData[1]==0x7f)&&(DisplayData[2]==0x76)));elsegoto Loop;}for(i=0;i<7;i++)  //将led右移一位{led=_cror_(led,1);delay_2(50000); //大约延时450ms   if(((DisplayData[0]==0x3f)&&(DisplayData[1]==0x7f)&&(DisplayData[2]==0x76)));elsegoto Loop;}  }
//      else
//      {            break;
//
//      }   Loop:  ;}
}/*******************************************************************************
* 函数名         : ReadIr()
* 函数功能         : 读取红外数值的中断函数
* 输入           : 无
* 输出             : 无
*******************************************************************************/void ReadIr() interrupt 0  //外部中断,自动进入
{u8 j,k;u16 err;Time=0;                     delay_1(700);  //7ms        7MS存在的意义就是保证能够接收起始码信号,本来是9ms,这意思是给你2ms缓冲时间  现在有点理解这个了,先给7ms如果不给,直接接受肯定会出错if(IRIN==0)     //确认是否真的接收到正确的信号                                              而给了就算没到来正好,如果到了基本上准确{   err=1000;             //1000*10us=10ms,超过说明接收到错误的信号/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时    如果出错意思就是接受一异常直接跳出后面还有return侯,程序死在这里*/ while((IRIN==0)&&(err>0))  //等待前面9ms的低电平过去           说实话我不是很明白这个,这不就相当于0.01ms*1000+10ms=20ms了吗  反正到直接跳出给你足够时间反应{          delay_1(1);err--;} if(IRIN==1)            //如果正确等到9ms低电平          这里说明到了,如果是中途直接跳出,而且又给你20ms缓冲时间,再怎么误差也该到了,{err=500;while((IRIN==1)&&(err>0))        //等待4.5ms的起始高电平过去         这个道理一样   还是那个疑问不是9ma吗不过没关系,反正到了直接退出while循环无影响{delay_1(1);err--;}for(k=0;k<4;k++)        //共有4组数据{               for(j=0;j<8;j++)  //接收一组数据{err=60;       while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去            这个明显也是600*2us  不过都没关系,到了直接退出循环进入下一步{delay_1(1);err--;}err=500;while((IRIN==1)&&(err>0))    //计算高电平的时间长度。      {delay_1(10);    //0.1msTime++;err--;if(Time>30)  //  说明总时间达到3ms,其实这时间都好模糊,不精确,不如定时中断准确,如果达到了3ms说明接收异常,直接退出这个中断函数{             //这只是一个普通中断函数,并不是定时或者计数,仅仅是起到中断进入的作用。return;}}IrValue[k]>>=1;    //k表示第几组数据      先进来用户码    进入这个函数说明正常接收   从这里可以得知IrValue[0] 为八位数,也就是八位字节,先进入最高//位然后右移,然后四个然后共四组32位数据,     视频里说是先接收最低位所以右移,读取写入顺序不同if(Time>=8)            //如果高电平出现大于565us,那么是1      0.8ms是平均值,可计算出得到    小于565认为是0,,,,,因为硬件软件误差嘛,这里是0.8ms{IrValue[k]|=0x80;     //这里就是1000 0000  也就是刚刚进来的最高位被或成1 }Time=0;       //用完时间要重新赋值                记得要清零            }}}if(IrValue[2]!=~IrValue[3])    //,互反检查不同说明出错退出函数     01是用户码,23 是数据码{return;}}
}///************************************************************************
//[文件名]  C51音乐程序(八月桂花)
//[功能]    通过单片机演奏音乐
//
///**********************************************************************/
//#include <REG52.H>
//#include <INTRINS.H>
本例采用89C52, 晶振为12MHZ
关于如何编制音乐代码, 其实十分简单,各位可以看以下代码.
频率常数即音乐术语中的音调,而节拍常数即音乐术语中的多少拍;
所以拿出谱子, 试探编吧!    //sbit Beep =  P1^5;
//   //
//void main()
//{ unsigned char p,m;   //m为频率常数变量
//  unsigned char i=0;
//  TMOD&=0x0f;
//  TMOD|=0x01;
//  TH0=0xd8;TL0=0xef;
//  IE=0x82;
//  play:
//   while(1)
//    {
//    a: p=music_tab[i];
//       if(p==0x00)       { i=0, delayms(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍
//       else if(p==0xff)  { i=i+1;delayms(100),TR0=0; goto a;}  //若碰到休止符,延时100ms,继续取下一音符
//            else         {m=music_tab[i++], n=music_tab[i++];}  //取频率常数 和 节拍常数
//             TR0=1;                                             //开定时器1
//           while(n!=0) Beep=~Beep,delay(m);                         //等待节拍完成, 通过P1口输出音频(可多声道哦!)
//       TR0=0;                                             //关定时器1
//    }
//} /*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
//void main()
//{//  u8 i;
//  led=0xfe;
//  delay_2(50000); //大约延时450ms
//  while(1)
//  {
///*        for(i=0;i<8;i++)
//      {//          P2=~(0x01<<i);    //将1右移i位,然后将结果取反赋值到P2口
//          delay(50000); //大约延时450ms
//      }
//*/
//      for(i=0;i<7;i++)   //将led左移一位
//      {//          led=_crol_(led,1);
//          delay_2(50000); //大约延时450ms
//      }
//      for(i=0;i<7;i++)  //将led右移一位
//      {//          led=_cror_(led,1);
//          delay_2(50000); //大约延时450ms
//      }
//  }
//}

单片机,51红外通信代码,详细注释【普中科技】【350行】【原创】相关推荐

  1. 51单片机中断与定时器计数器,基于普中科技HC6800-ESV2.0

    目录 寄存器 置位复位 中断系统 中断概念 中断系统 中断系统构造 外部中断 计时器.定时器中段 串口中断 中断允许控制(控制中断方式) 总中断 各个中断 中断请求标志(控制触发方式) 外部中断触发方 ...

  2. 51单片机中断与定时器计数器,基于普中科技教学视频学习记录

    目录 寄存器 置位复位 中断系统 中断概念 中断系统 中断系统构造 外部中断 计时器.定时器中段 串口中断 中断允许控制(控制中断方式) 总中断 各个中断 中断请求标志(控制触发方式) 外部中断触发方 ...

  3. 普中科技51单片机的ADC采样电位器功能实现以及特点

    ADC模数转换的目的: **单片机能够接受和处理的数据都是离散的数字量,而不是连续的模拟量,**就和机器语言不能和普通语言一样通用,要先转换成单片机能够接受的数据,才能进行对模拟量数据(比如,温度,受 ...

  4. 【Python】python初学者应该知道与其他语言差异化的高效编程技巧(附测试代码+详细注释)

    目录 1. 交换变量 2. 集合去重 3. 列表推导.集合推导和字典推导 4. 统计字符串中各个字符出现的次数 5.优雅地打印JSON数据 6.行内的if语句 6. 符合正常逻辑的数值比较 7. 田忌 ...

  5. 【综合评价分析】熵权算法确定权重 原理+完整MATLAB代码+详细注释+操作实列

    [综合评价分析]熵权算法确定权重 原理+完整MATLAB代码+详细注释+操作实列 文章目录 1. 熵权法确定指标权重 (1)构造评价矩阵 Ymn (2)评价矩阵标准化处理 (3)计算指标信息熵值 Mj ...

  6. 使用普中科技51单片机进行(I^2)C总线操作

    /*C51单片机学习打卡*/ /*观看郭天祥老师教学视频,使用普中科技51单片机开发板进行学习(I^2)C总线操作*/ /*功能:在开发版上进行999秒计时,在单片机掉电情况下可以记录最后一秒的数据* ...

  7. 【综合评价分析】topsis评价 原理+完整MATLAB代码+详细注释+操作实列

    [综合评价分析]topsis评价 原理+完整MATLAB代码+详细注释+操作实列 文章目录 1.TOPSIS法的原理 2.TOPSIS法案例分析 3.建立模型并求解 3.1数据预处理 3.2代码实现数 ...

  8. 手写YOLOv3|代码详细注释

    手写YOLOv3|代码详细注释 一. 数据预处理 一. Yolov3网络 一. Train 一. Detection 源代码:https://github.com/eriklindernoren/Py ...

  9. c语言期中项目实战二—简易扫雷,思路分析加代码详细注释

    c语言期中项目实战二-简易扫雷,思路分析+代码详细注释 游戏介绍 项目步骤 模块化编程 设置菜单 设置棋盘 打印棋盘 布置雷 排查雷 总结及总代码和详细注释 游戏介绍 扫雷这个经典游戏,直到现在仍有很 ...

最新文章

  1. java 关于String
  2. linux启动顺序详解
  3. 【PAT乙级】1071 小赌怡情 (15 分)
  4. ostu进行遥感图像的分割
  5. CodeForces - 850C Arpa and a game with Mojtaba(博弈+sg函数)
  6. [最新下载] 【火车票订票外挂】Go-Home–12306.cn 网上火车票自动订票程序
  7. 【SQL】分组数据,过滤分组-group by , having
  8. NET开发人员应该要知道
  9. 【BZOJ2326】【codevs2314】数学作业,第100篇博文纪念
  10. java零碎要点---struts2中redirect和redirectAction的区别
  11. 【报告分享】中国创新生态发展报告2019-德勤.pdf
  12. VUE 响应式原理源码:带你一步精通 VUE | 原力计划
  13. Java多线程(七)——线程中断
  14. 两平面平行方向向量关系_2017-2018学年高中数学第三章空间向量与立体几何3.2.1直线的方向向量与平面的法向量3.2.2空间线面关系的判定(一)苏教选修2-1.ppt...
  15. 电影整站程序 - webplayer9 p2p视频点播 - 电影整站系统 全部ASP源代码
  16. 读数学建模国赛优秀论文的笔记
  17. [laravel]laravel8自动生成api文档
  18. input tabIndex说明
  19. VS2008运行过程中出现regsvr32问题解决方法记录
  20. tokudb引擎使用

热门文章

  1. 谷歌54亿收购Mandiant:提高谷歌云竞争性
  2. 人工智能导论丁世飞第三版期末考试复习大纲
  3. Surface Pro 4 上市 预订用户专享礼包
  4. 魔兽世界台服被大陆玩家挤爆
  5. Button(按钮)与ImageButton(图像按钮)
  6. 微软服务器系统ssd,免费试用微软2个月Windows 365云桌面,4核心+16G内存+128SSD
  7. 河南工程学院oj答案
  8. 步进控制薄图modbus通讯1200PLC通讯威纶通
  9. iWO联通3G详单及套餐使用情况查询工具)更新至v0.8.3
  10. 仿生蛇类机器人 特点_仿生学又一成就,让机器人更像蛇!