/*************************************************************************************************/
//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红外模拟发送和接收程序的更多相关文章

  1. 使用httperrequest,模拟发送及接收Json请求

    使用httpreques\Json-Handle\tcpdump\wireshark工具进行,抓取手机访问网络的包,分析request及response请求,通过httprequester来实现模拟发 ...

  2. 使用firefox插件httperrequest,模拟发送及接收Json请求 【转】

    转自[http://blog.csdn.net/feixue1232/article/details/8535212] 目标:使用httpreques\Json-Handle\tcpdump\wire ...

  3. 使用HttpRequester模拟发送及接收Json请求

    1.开发人员在火狐浏览器里经常使用的工具有Firebug,httprequester,restclient......火狐浏览器有一些强大的插件供开发人员使用!需要的可以在附加组件中扩展. 2.htt ...

  4. C# Socket模拟发送接收

    Socket简介 通过TCP/IP与仪器或设备通讯,在C#语言中,我们通常采用Socket.本项目是一个简单的Socket建立服务监听与Socket作为客户端请求的一个示例. 项目结构 客户端项目 S ...

  5. 在C#程序中模拟发送键盘按键消息

    using System.Runtime.InteropServices; 引入键盘事件函数 [DllImport("user32.dll")]public static exte ...

  6. nodejs 数据库操作,消息的发送和接收,模拟同步

    var deasync = require('deasync'); //导入模板 var mysql=require('mysql'); var Stomp = require('stompjs'); ...

  7. udp网络程序-发送、接收数据

    1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8from socket im ...

  8. 管道通信实例(A程序作为服务器,不断从B程序接收数据,并发送到C程序中)

    A程序作为服务器,不断从B程序接收数据,并发送到C程序中:#include <stdio.h>#include <conio.h> #include <tchar.h&g ...

  9. DICOM医学图像处理:DIMSE消息发送与接收“大同小异”之DCMTK fo-dicom mDCM

    背景: 从DICOM网络传输一文开始,相继介绍了C-ECHO.C-FIND.C-STORE.C-MOVE等DIMSE-C服务的简单实现,博文中的代码给出的实例都是基于fo-dicom库来实现的,原因只 ...

随机推荐

  1. Greenplum 6安装指南(CentOS 7.X)

    一.基本概念 Greenplum是一个面向数据仓库应用的关系型数据库,因为有良好的体系结构,所以 在数据存储.高并发.高可用.线性扩展.反应速度.易用性和性价比等方面有非常 明显的优势.Greenpl ...

  2. git submodule 操作

    git submodule foreach git status 举一反三,对所有子库的操作,都可以使用 git submodule foreach 做前缀 foreach,可以记忆为for each ...

  3. 从零开始的Java RASP实现(二)

    目录 2 RASP-demo 2.1 类加载机制 双亲委派 BootStrap ClassLoader 2.2 Instrumentation介绍 Instrumentation类中常用方法 Inst ...

  4. 计算机课程设计-校园二手书交易系统java二手交易平台代码ssm二手商城购物平台跳蚤市场

    计算机课程设计-校园二手书交易系统java二手交易平台代码ssm二手商城购物平台跳蚤市场 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台框架:SSM(S ...

  5. Git出错:“Please make sure you have the correct access rights and the repository exists.”

    此问题是需要重置ssh密钥 解决步骤如下: 1.重置用户名和邮箱: 打开Git Bash 进入Git命令,输入以下命令 git config --global user.name "你的用户 ...

  6. docker 搭建kafka集群(入门版)

    1.环境 docker, docker-compose 2.zk-kafka.yml version: '3' services: zoo1: image: zookeeper:3.4.14 rest ...

  7. Vulnhub -- DC4靶机渗透

    用nmap扫描ip和端口,发现只开启了22ssh端口和80http端口 打开网页只有一个登录界面 目录爆破没有发现什么有用的,尝试对登录进行弱口令爆破 一开始使用burpsuite,使用一个小字典进行 ...

  8. NOIP 模拟 9 数颜色

    题解 一道裸的数据结构题 正解是排序 \(+\) 二分,但是这怎么能有动态开点线段树好写呢? 于是我就打了暴力,骗了五十分. 对于每种颜色,我们在下标上开一颗线段树,对于交换若颜色相同则跳过,否则直接 ...

  9. noip 模拟4

    咕 题都改不完怎么可能有空写题解啊啊啊

  10. C#与.NET、CLR、CLI是什么关系?什么是.NET框架

    1.C#与.NET.CLR.CLI是什么关系?什么是.NET框架?      这个问题好专业啊!一句话两句话还真不好说清.您听说过C++中有个COM的概念吧?您听说过JAVA里的虚拟机吧?CLR(公共 ...