38KHz,NEC红外模拟发送和接收程序
/*************************************************************************************************/
//38k NEC 编码接收和模拟发射
//完整的信号构成:引导码+8位的客户码+8位客户码的补码+8位的按键值+8位按键值的补码+结束码
//接收使用外部中断0,发射管低电平触发
//STC15F104W@24MHz
//
//为了尽可能的简化代码量,没有引入按键,程序运行起来为每250ms一个周期,每250ms通过红外发射管发射一次数据,同
//时若检测到接收管接收到了完整的数据则把这个数据通过串口发出
//
//由于发送和接收数据肯定无法同时在一片单片机上完成,所以若需测试代码的完整功能应准备两个单片机或者其他设备。
//
//网上能找到的模拟红外发射的代码多为通过定时器实现,本代码则统统使用软件延时实现。一来使用定时器太浪费资源,二
//来对于1T单片机来说,用软件延时马马虎虎输出38K的波形还是挺简单的(这都0202年了,估计以后很难由机会再用到12T
//的51单片机了吧)
/*************************************************************************************************/ #include "config.h"
#include "delay.h"
#include "suart.h" sbit IRIN =P3^2; //红外接收端口
sbit IROUT=P3^3; //红外发射端口
unsigned char IrValue[4]; //红外键值.四个数据分别为用户码、用户补码、键值、键值补码
bit flag_Ir; //红外接收完成标志位
void Ir_Init(void); //红外初始化(外部中断0和发送接收端口初始化)
void Ir_Out(unsigned char u, unsigned char x); //发送数据,两个参数分别为用户码和键值
void Ir_Out_Frame(unsigned char y); //发送一帧数据,由 Ir_Out() 函数调用
void Delay7us(); //7us延时 @24.000MHz_STC-Y5
void Delay19us(); //19us延时@24.000MHz_STC-Y5
void Delay100us(); //100us延时@24.000MHz_STC-Y5 /**************************************************************************************************
* 主函数
*/
void main(void)
{
Ir_Init(); //红外初始化
SUART_INIT(); //串口初始化
TxString("38KHz NEC 红外接收测试程序\r\n");
while (1)
{
delay_ms(250); //每250ms通过红外发送一个数据
Ir_Out(0x42,0x5A); //参数为用户码、键值 if(flag_Ir) //如果接收到完整数据,则把数据通过串口打印出来
{
flag_Ir=0; //必须清空接收完成标志
TxByte(IrValue[0]);
TxByte(IrValue[1]);
TxByte(IrValue[2]);
TxByte(IrValue[3]);
}
}
} /**************************************************************************************************
* 红外接收初始化
*/
void Ir_Init(void)
{
IT0 = 1; //下降沿触发
EX0 = 1; //打开中断0允许
EA = 1; //打开总中断
IRIN = 1; //初始化端口
IROUT = 1;
flag_Ir = 0; //初始化接收完成标志位
} /**************************************************************************************************
* 延时7us @ 24MHz STC-Y5
* 生成38k波使用,占空比在1/3时效果最好。i的取值供参考,使用时视波形表现调整。
*/
void Delay7us() //@24.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 38;
while (--i);
}
/**************************************************************************************************
* 延时19us @ 24MHz STC-Y5
* 生成38k波使用,占空比在1/3时效果最好。i的取值供参考,使用时视波形表现调整。
*/
void Delay19us() //@24.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 105;
while (--i);
}
/**************************************************************************************************
* 延时100us @ 24MHz STC-Y5
*/
void Delay100us() //@24.000MHz
{
unsigned char i, j;
i = 3;
j = 82;
do
{
while (--j);
} while (--i);
} /**************************************************************************************************
* 红外发射程序
*/
void Ir_Out(unsigned char u, unsigned char x)
{
int tt;
EA=0; //关闭所有中断 /*发送引导码*/
tt=350; //输出9ms 1(有38k信号输出表示 1. 38k每个周期约26us,9ms大概tt个周期,视实际情况调整)
do {IROUT=0; Delay19us(); IROUT=1; Delay7us();} while(--tt);
tt=45; //输出4.5ms 0 (无38k信号输出表示 0. 同样,tt的取值看实际情况调整)
do {IROUT=1; Delay100us();} while(--tt); /*发送用户码和用户补码*/
Ir_Out_Frame(u);
Ir_Out_Frame(~u); /*发送键值和键值补码*/
Ir_Out_Frame(x);
Ir_Out_Frame(~x); /*发送结束码*/
tt=25; //输出0.65ms 1
do {IROUT=0; Delay19us(); IROUT=1; Delay7us();} while(--tt);
tt=5; //输出40ms 0
do {IROUT=1; Delay100us();} while(--tt); /*重复码*/
//9ms 1
//2.25ms 0
//0.56ms 1
//40ms 0
//56ms 0 EA=1; // 打开中断
}
/**************************************************************************************************
* 红外单帧发射程序
*/
void Ir_Out_Frame(unsigned char y)
{
char num;
int tt;
for (num=0; num<8; num++) //循环8次移位
{
tt=25; //输出0.65ms 1
do {IROUT=0; Delay19us(); IROUT=1; Delay7us();} while(--tt);
if(y&0x01) //if为1
{
tt=16; //输出1.65ms 0
do {IROUT=1; Delay100us();} while(--tt);
}
else //否则
{
tt=5; //输出0.56ms 0
do {IROUT=1; Delay100us();} while(--tt);
}
y >>= 1; //右移一位
}
} /**************************************************************************************************
* 读取红发外值
* 外部中断的服务程序
*/
void ReadIr() interrupt 0
{
unsigned int err;
unsigned int tt;
unsigned char Time;
unsigned char j, k;
EA=0; //关闭总中断
Time=0;
tt=80; //延时8ms去干扰,引导码为9ms的低电平和4.5ms的高电平
do { Delay100us(); } while(--tt);
if(IRIN==0) //确认是否真的接收到正确的信号
{
err=500; //超时判断
while((IRIN==0)&&(err>0)) //等待高电平,最多等待50ms
{
Delay100us();
err--;
}
if(IRIN==1) //收到高电平
{
err=500; //超市判断
while((IRIN==1)&&(err>0)) //等待4.5ms的高电平过去
{
Delay100us();
err--;
}
for(k=0; k<4; k++) //开始接收数据,共有4个数据
{
for(j=0; j<8; j++) //每个8位
{
err=60;
while((IRIN==0)&&(err>0)) //等待信号前面的560us低电平过去
{
Delay100us();
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //计算高电平的时间长度。
{
Delay100us();
Time++;
err--;
if(Time>50) //超过5ms说明接收到重复码。重复码:9ms高电平+2.25ms低电平+560us高电平
{
EA=1; //打开总中断
return; //退出函数
}
}
IrValue[k]>>=1; //k表示第几组数据
if(Time>=8) //若高电平出现大于0.8ms,为1(1.65ms为1,0.56ms为0,这里取中间值)
IrValue[k]|=0x80;
Time=0; //用完时间要重新赋值
}
}
}
if(IrValue[2]=~IrValue[3]) //这里一般只判断键值而不判断用户码,因为对于一些用户码是0的遥控无论怎样都是0
{
flag_Ir = 1; //如果按键值与按键值的补码的取反相同,则接收完成标志置位
}
}
EA=1; //打开总中断
}
38KHz,NEC红外模拟发送和接收程序的更多相关文章
- 使用httperrequest,模拟发送及接收Json请求
使用httpreques\Json-Handle\tcpdump\wireshark工具进行,抓取手机访问网络的包,分析request及response请求,通过httprequester来实现模拟发 ...
- 使用firefox插件httperrequest,模拟发送及接收Json请求 【转】
转自[http://blog.csdn.net/feixue1232/article/details/8535212] 目标:使用httpreques\Json-Handle\tcpdump\wire ...
- 使用HttpRequester模拟发送及接收Json请求
1.开发人员在火狐浏览器里经常使用的工具有Firebug,httprequester,restclient......火狐浏览器有一些强大的插件供开发人员使用!需要的可以在附加组件中扩展. 2.htt ...
- C# Socket模拟发送接收
Socket简介 通过TCP/IP与仪器或设备通讯,在C#语言中,我们通常采用Socket.本项目是一个简单的Socket建立服务监听与Socket作为客户端请求的一个示例. 项目结构 客户端项目 S ...
- 在C#程序中模拟发送键盘按键消息
using System.Runtime.InteropServices; 引入键盘事件函数 [DllImport("user32.dll")]public static exte ...
- nodejs 数据库操作,消息的发送和接收,模拟同步
var deasync = require('deasync'); //导入模板 var mysql=require('mysql'); var Stomp = require('stompjs'); ...
- udp网络程序-发送、接收数据
1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8from socket im ...
- 管道通信实例(A程序作为服务器,不断从B程序接收数据,并发送到C程序中)
A程序作为服务器,不断从B程序接收数据,并发送到C程序中:#include <stdio.h>#include <conio.h> #include <tchar.h&g ...
- DICOM医学图像处理:DIMSE消息发送与接收“大同小异”之DCMTK fo-dicom mDCM
背景: 从DICOM网络传输一文开始,相继介绍了C-ECHO.C-FIND.C-STORE.C-MOVE等DIMSE-C服务的简单实现,博文中的代码给出的实例都是基于fo-dicom库来实现的,原因只 ...
随机推荐
- springboot项目出现Whitelabel Error Page的问题
springboot项目出现Whitelabel Error Page的问题 大概就是这种情况,然而昨天还是没问题的,通过对比就发现,是自己手欠了 简单来说解决办法就是将springboot的启动项目 ...
- SQL injection : UNION attacks
当应用程序易受SQL注入攻击并且查询结果在应用程序的响应中返回时,可以使用UNION关键字从数据库中的其他表检索数据.这将导致SQL注入联合攻击. UNION关键字允许您执行一个或多个附加的SELEC ...
- SSRF详解
上一篇说了XSS的防御与绕过的思路,这次来谈一下SSRF的防御,绕过,利用及危害 0x01 前置知识梳理 前置知识涉及理解此漏洞的方方面面,所以这部分要说的内容比较多 SSRF(Server-Side ...
- 关于phpmyadmin getshell
思考一个问题:如何在获得一个PHP MySQL 搭建网站的phpmyadmin界面后(无论用什么办法,进到phpmyadmin里),进行一个getshell的操作? ...... 0x01山重水复 当 ...
- SSH以及ROS远程登录设置保姆级教程
本文用来实现在同一局域网内的两台计算机之间的相互通信,实现一台计算机登录到另一台计算机,本文基于SSH来实现. 1.SSH简介 Secure Shell(SSH)是由 IETF(The Interne ...
- @Profile-根据不同环境注入bean
介绍 @Profile元注解是在不同的生产环境中,@Bean创建的SpringBean根据spring.profiles.active指定的环境不同创建不同环境的bean对象 一.@Profile元注 ...
- 【linux】vim常用命令
转自:https://www.runoob.com/linux/linux-vim.html vi/vim 的使用 基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode),输 ...
- vue去掉一些烦人的校验规则
例如:括号前没有加空格报错,很难受 如何处理呢,故意犯错,然后打开页面出现错误信息,如下图复制错误 space-before-function-paren 找到项目中的.eslintrc.js 添加一 ...
- 刷题-力扣-剑指 Offer 42. 连续子数组的最大和
剑指 Offer 42. 连续子数组的最大和 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de ...
- 刷题-力扣-1011. 在 D 天内送达包裹的能力
1011. 在 D 天内送达包裹的能力 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/capacity-to-ship-packag ...