单片机ESP8266智能家居的红外遥控设计 C源代码+原理图+PCB 全设计资料

94 篇文章 88 订阅
3 篇文章 1 订阅

最近有小伙伴私信我,他是学电子信息的,老师让他们做一个关于红外遥控控制智能家居的小项目,没有设计思路,也不知道用啥芯片,自己只会写一些单片机代码,和使用AD-PCB设计软件。
我记得很久以前做过一个类似的项目大概是16年,于是找了大半个下午,终于找出来,现在把它分享出来,供大家参考一下,希望小伙伴们能从中学到东西。

PCB原理图如下,我记得当时还是用protel画的
在这里插入图片描述
电路原理图如下:画图软件同上
在这里插入图片描述
实验参考C语言代码
#include “stc12c2052ad.h”
#include “wifi_IR.h”

#include <intrins.h>

//#define ENABLE_IAP 0x83 //if SYSCLK<20MHz

#define FOSC 11059200UL//12M晶振

#define CMD_IDLE 0 //Stand-By
#define CMD_READ 1 //Byte-Read
#define CMD_PROGRAM 2 //Byte-Program
#define CMD_ERASE 3 //Sector-Erase

uint addr;//EPPROM地址
//uchar cou;
bit study_send_switch,LED_state;

void SaveLevelTimeLength(uint addr);//存储电平时长
void IrSend();//红外发射
void Read_Key();
void IrStudy();
void IapIdle();
void byte_write(uint addr, uchar dat);
void SectorErase(uint sector_addr);
uchar byte_read(uint addr);

void TIMER0_RELOAD(uint addr)//装入定时器
{
TR0=0;
TF0=0;
TH0=byte_read(addr);//从指定的地址读出电平的长度
TL0=byte_read(addr+1);//从指定的地址读出电平的长度
TR0=1;//启动定时器

}
//---------------------------------------------------

void IrSend()//红外发射
{
uchar level_cnt; //电平个数

level_cnt=byte_read(addr);//读出电平个数
addr++;//地址后移一位
while (1)
{
F38_4KHZ_ON();//因为红外码大部分都是起始一段高电平,所以此处一开始就打开。
TIMER0_RELOAD(addr);//时长装入定时器,开始计时
addr+=2;// 地址移到没有取过的地方,TIMER0_RELOAD函数取了两个地址的数据
while (!TF0);//等待定时器0溢出

if(level_cnt–==0)break;//判断是否取完
F38_4KHZ_OFF(); IR_SEND = 1;//停止发射
TIMER0_RELOAD(addr);//时长装入定时器,开始计时
addr+=2;//地址移到没有取过的地方,TIMER0_RELOAD函数取了两个地址的数据
while (!TF0);//等待定时器0溢出
if(level_cnt–==0)break;//电平数是否完毕
}
F38_4KHZ_OFF(); IR_SEND = 1;//停止发射
}
//---------------------------------------------------

void SaveLevelTimeLength(uint addr)//存电平时长
{
TR0=0;
byte_write(addr, ~TH0);
byte_write(addr+1, ~TL0); //电平时长存入eeprom中
TH0=0;//定时器初值归0
TL0=0x65;//查手册知道,编程一个字节需要55us,编程两个字节,所以此处需要110us。
TR0=1;//开始计数
}

void IrStudy()
{
uint level_cnt;
uint addrtmp;

TF0 = 0;
SectorErase(addr);
addrtmp=addr;//记录第一个地址,存储电平个数
addr++;
TR0=0;//停止计数
while (IR_REV);//等待红外接收管脚为低电平
//编码与解码是一对逆过程,不仅在原理上是一对逆过程,在码的发收过程也是互反的,即以前发射端原始信号是高电平,那接收头输出的就是低电平
TH0=0;
TL0=0;
TR0=1;//开启定时器

while (1)
{
while (!IR_REV) //等待高电平,等待超时;超过70MS退出
{
if (TF0)
{
goto StudyFinish;
}

}

SaveLevelTimeLength(addr); //高电平到来,存低电平时长到eeprom}
level_cnt++;
addr += 2;

while (IR_REV) //等待低电平,等待超时;超过70MS退出
{
if (TF0)
{
goto StudyFinish;
}
}
SaveLevelTimeLength(addr);//低电平到来存高电平电平时长
level_cnt++;//存储的电平个数加11
addr+=2;//地址后移两位
}
StudyFinish:
TF0=0;
TR0=0;
byte_write(addrtmp,level_cnt);
level_cnt = 0;

}

void Delay100ms() //@11.0592MHz
{
unsigned char i, j, k;

nop();
nop();
i = 5;
j = 52;
k = 195;
do
{
do
{
while (–k);
} while (–j);
} while (–i);
}

void IapIdle()
{
IAP_CONTR = 0; //Close IAP function
IAP_CMD = 0; //Clear command to standby
IAP_TRIG = 0; //Clear trigger register
IAP_ADDRH = 0x80; //Data ptr point to non-EEPROM area
IAP_ADDRL = 0; //Clear IAP address to prevent misuse
}

/************************************************************************
函数名称:字节写
全局变量:无
参数说明:addr:写入地址, dat:写入数据
************************************************************************/
void byte_write(uint addr,uchar dat)
{
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_DATA = dat; //Write ISP/IAP/EEPROM data
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
nop();
nop();
nop();
nop();
IapIdle();

}

鉴于篇幅限制只能写部分代码
最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,
如果需要完整代码或设计文件,请加QQ分享群,本博客所有代码开源下载,或私信我,看到后会第一时间回复。
谢谢!

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值