单片机,51红外通信代码,详细注释【普中科技】【350行】【原创】
文章目录
- 代码
代码
/**************************************************************************************
* 红外通信实验 *
实现现象:下载程序后,数码管显示红外遥控键值数据
注意事项: 红外遥控器内的电池绝缘片一定要抽掉
***************************************************************************************/#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行】【原创】相关推荐
- 51单片机中断与定时器计数器,基于普中科技HC6800-ESV2.0
目录 寄存器 置位复位 中断系统 中断概念 中断系统 中断系统构造 外部中断 计时器.定时器中段 串口中断 中断允许控制(控制中断方式) 总中断 各个中断 中断请求标志(控制触发方式) 外部中断触发方 ...
- 51单片机中断与定时器计数器,基于普中科技教学视频学习记录
目录 寄存器 置位复位 中断系统 中断概念 中断系统 中断系统构造 外部中断 计时器.定时器中段 串口中断 中断允许控制(控制中断方式) 总中断 各个中断 中断请求标志(控制触发方式) 外部中断触发方 ...
- 普中科技51单片机的ADC采样电位器功能实现以及特点
ADC模数转换的目的: **单片机能够接受和处理的数据都是离散的数字量,而不是连续的模拟量,**就和机器语言不能和普通语言一样通用,要先转换成单片机能够接受的数据,才能进行对模拟量数据(比如,温度,受 ...
- 【Python】python初学者应该知道与其他语言差异化的高效编程技巧(附测试代码+详细注释)
目录 1. 交换变量 2. 集合去重 3. 列表推导.集合推导和字典推导 4. 统计字符串中各个字符出现的次数 5.优雅地打印JSON数据 6.行内的if语句 6. 符合正常逻辑的数值比较 7. 田忌 ...
- 【综合评价分析】熵权算法确定权重 原理+完整MATLAB代码+详细注释+操作实列
[综合评价分析]熵权算法确定权重 原理+完整MATLAB代码+详细注释+操作实列 文章目录 1. 熵权法确定指标权重 (1)构造评价矩阵 Ymn (2)评价矩阵标准化处理 (3)计算指标信息熵值 Mj ...
- 使用普中科技51单片机进行(I^2)C总线操作
/*C51单片机学习打卡*/ /*观看郭天祥老师教学视频,使用普中科技51单片机开发板进行学习(I^2)C总线操作*/ /*功能:在开发版上进行999秒计时,在单片机掉电情况下可以记录最后一秒的数据* ...
- 【综合评价分析】topsis评价 原理+完整MATLAB代码+详细注释+操作实列
[综合评价分析]topsis评价 原理+完整MATLAB代码+详细注释+操作实列 文章目录 1.TOPSIS法的原理 2.TOPSIS法案例分析 3.建立模型并求解 3.1数据预处理 3.2代码实现数 ...
- 手写YOLOv3|代码详细注释
手写YOLOv3|代码详细注释 一. 数据预处理 一. Yolov3网络 一. Train 一. Detection 源代码:https://github.com/eriklindernoren/Py ...
- c语言期中项目实战二—简易扫雷,思路分析加代码详细注释
c语言期中项目实战二-简易扫雷,思路分析+代码详细注释 游戏介绍 项目步骤 模块化编程 设置菜单 设置棋盘 打印棋盘 布置雷 排查雷 总结及总代码和详细注释 游戏介绍 扫雷这个经典游戏,直到现在仍有很 ...
最新文章
- java 关于String
- linux启动顺序详解
- 【PAT乙级】1071 小赌怡情 (15 分)
- ostu进行遥感图像的分割
- CodeForces - 850C Arpa and a game with Mojtaba(博弈+sg函数)
- [最新下载] 【火车票订票外挂】Go-Home–12306.cn 网上火车票自动订票程序
- 【SQL】分组数据,过滤分组-group by , having
- NET开发人员应该要知道
- 【BZOJ2326】【codevs2314】数学作业,第100篇博文纪念
- java零碎要点---struts2中redirect和redirectAction的区别
- 【报告分享】中国创新生态发展报告2019-德勤.pdf
- VUE 响应式原理源码:带你一步精通 VUE | 原力计划
- Java多线程(七)——线程中断
- 两平面平行方向向量关系_2017-2018学年高中数学第三章空间向量与立体几何3.2.1直线的方向向量与平面的法向量3.2.2空间线面关系的判定(一)苏教选修2-1.ppt...
- 电影整站程序 - webplayer9 p2p视频点播 - 电影整站系统 全部ASP源代码
- 读数学建模国赛优秀论文的笔记
- [laravel]laravel8自动生成api文档
- input tabIndex说明
- VS2008运行过程中出现regsvr32问题解决方法记录
- tokudb引擎使用
热门文章
- 谷歌54亿收购Mandiant:提高谷歌云竞争性
- 人工智能导论丁世飞第三版期末考试复习大纲
- Surface Pro 4 上市 预订用户专享礼包
- 魔兽世界台服被大陆玩家挤爆
- Button(按钮)与ImageButton(图像按钮)
- 微软服务器系统ssd,免费试用微软2个月Windows 365云桌面,4核心+16G内存+128SSD
- 河南工程学院oj答案
- 步进控制薄图modbus通讯1200PLC通讯威纶通
- iWO联通3G详单及套餐使用情况查询工具)更新至v0.8.3
- 仿生蛇类机器人 特点_仿生学又一成就,让机器人更像蛇!