专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
51单片机
为什么我的红外接收程序在STC15F104E上用遥控按几次就不行了,有时候能按几十次??求大神指导
2019-07-15 16:09
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
51单片机
6717
6
1056
为什么我的红外接收程序在STC15F104E上用遥控按几次就不行了,有时候能按几十次??
程序.zip
下载积分: 积分 -1 分
28.75 KB, 下载次数: 50, 下载积分: 积分 -1 分
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
无量寿经
1楼-- · 2019-07-15 16:37
《51单片机轻松入门-基于STC15W4K系列》第18章那个红外通信例子很好用,可定义任意引脚进行接收,程序自适应5-35M时钟频率。 最佳答案
加载中...
elecfans跑堂
2楼-- · 2019-07-15 19:25
请将详细的程序内容复制出来 方便查看回答
加载中...
DHTDHT
3楼-- · 2019-07-16 00:47
elecfans跑堂 发表于 2015-9-7 14:02
请将详细的程序内容复制出来 方便查看回答
#include<reg51.h>
#include <intrins.h>
sbit LSA = P3^5;
sbit IRIN = P3^2;
unsigned char DisplayData[8]; //用来存放要显示的8位数的值
unsigned char IrValue[6]; //用来存放读取到的红外值
unsigned char Time;
//--声明全局函数--//
void DigDisplay(); //动态显示函数
void IrInit();
void DelayMs(unsigned int );
/*******************************************************************************
* 函数名 : DelayMs()
* 函数功能 : 延时
* 输入 : x
* 输出 : 无
*******************************************************************************/
void DelayMs(unsigned int x) //0.14ms误差 0us
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++)
{}
}
}
void Delay140us() //@11.0592MHz
{
unsigned char i, j;
i = 2;
j = 126;
do
{
while (--j);
} while (--i);
}
/*******************************************************************************
* 函数名 : IrInit()
* 函数功能 : 初始化红外线接收
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void IrInit()
{
IT0=1;//下降沿触发
EX0=1;//打开中断0允许
EA=1; //打开总中断
IRIN=1;//初始化端口
}
/*******************************************************************************
* 函数名 : ReadIr()
* 函数功能 : 读取红外数值的中断函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void ReadIr() interrupt 0
{
unsigned char j,k;
unsigned int err;
Time=0;
DelayMs(70);
if(IRIN==0) //确认是否真的接收到正确的信号
{
err=1000; //1000*10us=10ms,超过说明接收到错误的信号
/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
侯,程序死在这里*/
while((IRIN==0)&&(err>0)) //等待前面9ms的低电平过去
{
Delay140us();
err--;
}
if(IRIN==1) //如果正确等到9ms低电平
{
err=470;
while((IRIN==1)&&(err>0)) //等待4.5ms的起始高电平过去
{
Delay140us();
err--;
}
for(k=0;k<4;k++) //共有4组数据
{
for(j=0;j<8;j++) //接收一组数据
{
err=60;
while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
{
Delay140us();
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //计算高电平的时间长度。
{
Delay140us();//0.14ms
Time++;
err--;
if(Time>30)
{
EX0=1;
return;
}
}
IrValue[k]>>=1; //k表示第几组数据
if(Time>=8) //如果高电平出现大于565us,那么是1
{
IrValue[k]|=0x80;
}
Time=0; //用完时间要重新赋值
}
}
}
if(IrValue[2]!=~IrValue[3])
{
return;
}
}
}
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 使用数码管显示
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DigDisplay()
{
switch(IrValue[2])
{
case 0x45:{
LSA=0;
}break;
case 0x46:{
LSA=1;
}break;
default:break;
}
}
void main()
{
IrInit();
while(1)
{
IrValue[4]=IrValue[2]>>4; //高位
IrValue[5]=IrValue[2]&0x0f; //低位
DigDisplay();
}
}
加载中...
无量寿经
4楼-- · 2019-07-16 01:31
以下程序来源于《51单片机轻松入门-基于STC15W4K系列》,
使用时重点关注2行代码,其它代码尽量不要修改。
#define MAIN_Fosc 22.1184
sbit Ir_Pin = P3^6; // 定义红外接收输入端口
///************* 功能说明 **************
//红外接收程序。适用于市场上用量最大的HT6121/6122及其兼容IC的编码。
//当遥控器用户码与程序定义的用户码不同时,程序会将遥控器的用户码一起从串口输出。
//使用模拟串口发送用户码与键码,波特率9600,接收端要求使用字符格式显示。
/******************************************/
#include "STC15W4K.H"
#define MAIN_Fosc 22.1184 // 定义主时钟, 红外接收会自动适应,5~36MHZ,但模拟串口输出部分不能自动适应。
#define User_code 0xFD02 // 定义红外接收用户码
sbit Ir_Pin = P3^6; // 定义红外接收输入端口
sbit TXD1 = P3^1; // 定义模拟串口发送脚
/************* 用户系统配置 **************/
#define TIME 125 // 选择定时器时间125us, 红外接收要求在60us~250us之间
/************* 以下宏定义用户请勿修改 **************/
#define Timer0_Reload (unsigned int)(65536 - (TIME * MAIN_Fosc /12.0)) // 定时器初值
/************* 本地变量声明 **************/
unsigned char IR_SampleCnt; // 采样次数计数器,通用定时器对红外口检测次数累加记录
unsigned char IR_BitCnt; // 记录位数
unsigned char IR_UserH; // 用户码(地址)高字节
unsigned char IR_UserL; // 用户码(地址)低字节
unsigned char IR_data; // 键原码
unsigned char IR_DataShit; // 键反码
unsigned char IR_code; // 红外键码
bit Ir_Pin_temp; // 记录红外引脚电平的临时变量
bit IR_Sync; // 同步标志(1——已收到同步信号,0——没收到)
bit IrUserErr; // 用户码错误标志
bit IR_OK; // 完成一帧红外数据接收的标志(0,未收到,1,收到一帧完整数据)
/******************** 红外采样时间宏定义, 用户不要随意修改 *******************/
//数据格式: Synchro,AddressH,AddressL,data,/data, (total 32 bit).
#if ((TIME <= 250) && (TIME >= 60)) // TIME决定测量误差,TIME太大防错能力降低,TIME太小会干扰其它中断函数执行。
#define IR_sample TIME // 定义采样时间,在60us~250us之间,
#endif
#define IR_SYNC_MAX (15000/IR_sample) // 同步信号SYNC 最大时间 15ms(标准值9+4.5=13.5ms)
#define IR_SYNC_MIN (9700 /IR_sample) // 同步信号SYNC 最小时间 9.5ms,(连发信号标准值9+2.25=11.25ms)
#define IR_SYNC_DIVIDE (12375/IR_sample) // 区分13.5ms同步信号与11.25ms连发信号,11.25+(13.5-11.25)/2=12.375ms
#define IR_DATA_MAX (3000 /IR_sample) // 数据最大时间3ms (标准值2.25 ms)
#define IR_DATA_MIN (600 /IR_sample) // 数据最小时,0.6ms (标准值1.12 ms)
#define IR_DATA_DIVIDE (1687 /IR_sample) // 区分数据 0与1,1.12+ (2.25-1.12)/2 =1.685ms
#define IR_BIT_NUMBER 32 // 32位数据
//**************************** 红外接收模块 ********************************************
// 信号第1个下降沿时刻清零计数器并让计数器从0开始计数,第2个下降沿时刻计算计数器运行时间
// 因此检测的是每个信号从低电平开始到高电平结束这段时间,也就是脉冲周期。
void IR_RX_HT6121(void)
{
unsigned char SampleTime; // 信号周期
IR_SampleCnt++; // 定时器对红外口检测次数
F0 = Ir_Pin_temp; // 保存前一次此程序扫描到的红外端口电平
Ir_Pin_temp = Ir_Pin; // 读取当前红外接收输入端口电平
if(F0 && !Ir_Pin_temp) // 前一次采样高电平并且当前采样低电平,说明出现了下降沿
{
SampleTime = IR_SampleCnt; // 脉冲周期
IR_SampleCnt = 0; // 出现了下降沿则清零计数器
//******************* 接收同步信号 **********************************
if(SampleTime > IR_SYNC_MAX) IR_Sync = 0; // 超出最大同步时间, 错误信息。
else if(SampleTime >= IR_SYNC_MIN) // SYNC
{
if(SampleTime >= IR_SYNC_DIVIDE) // 区分13.5ms同步信号与11.25ms连发信号
{
IR_Sync = 1; // 收到同步信号 SYNC
IR_BitCnt = IR_BIT_NUMBER; // 赋值32(32位有用信号)
}
}
//********************************************************************
else if(IR_Sync) // 已收到同步信号 SYNC
{
if((SampleTime < IR_DATA_MIN)|(SampleTime > IR_DATA_MAX)) IR_Sync=0; // 数据周期过短或过长,错误
else
{
IR_DataShit >>= 1; // 键反码右移1位(发送端是低位在前,高位在后的格式)
if(SampleTime >= IR_DATA_DIVIDE) IR_DataShit |= 0x80; // 区别是数据 0还是1
//*********************** 32位数据接收完毕 ****************************************
if(--IR_BitCnt == 0)
{
IR_Sync = 0; // 清除同步信号标志
if(~IR_DataShit == IR_data) // 判断数据正反码
{
if((IR_UserH == (User_code / 256)) && IR_UserL == (User_code % 256))
{
IrUserErr = 0; // 用户码正确
}
else IrUserErr = 1; // 用户码错误
IR_code = IR_data; // 键码值
IR_OK = 1; // 数据有效
}
}
// 格式: 用户码L —— 用户码H —— 键码 —— 键反码
// 功能: 将 “用户码L —— 用户码H —— 键码”通过3次接收交换后存入对应字节,
// 这样写代码可以节省内存RAM占用,但是不如用数组保存好理解。
// 键反码前面部分代码已保存好了 :IR_DataShit |= 0x80;
//**************************** 将接收的************************************************
else if((IR_BitCnt & 7)== 0) // 1个字节接收完成
{
IR_UserL = IR_UserH; // 保存用户码高字节
IR_UserH = IR_data; // 保存用户码低字节
IR_data = IR_DataShit; // 保存当前红外字节
}
}
}
}
}
/**************** Timer0初始化函数 ******************************/
void InitTimer0(void)
{
TMOD = 0x01; // 16位计数方式.
TH0 = Timer0_Reload / 256;
TL0 = Timer0_Reload % 256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
/********************** Timer0中断函数************************/
void timer0 (void) interrupt 1
{
IR_RX_HT6121();
TH0 = Timer0_Reload / 256; // 重装定时器初值
TL0 = Timer0_Reload % 256; // 重装定时器初值
}
/********************** 模拟串口相关函数************************/
void delay104us(void)
{
unsigned char i,j,k;
for(i=1;i>0;i--) // 注意后面没分号
for(j=3;j>0;j--) // 注意后面没分号
for(k=189;k>0;k--); // 注意后面有分号 101
}
//模拟串口发送
void Tx1Send(unsigned char dat) //9600,N,8,1 发送一个字节
{
unsigned char i;
EA = 0;
TXD1 = 0;
delay104us();
for(i=0; i<8; i++)
{
if(dat & 1) TXD1 = 1;
else TXD1 = 0;
dat >>= 1;
delay104us();
}
TXD1 = 1;
EA = 1;
delay104us();
delay104us();
}
void PrintString(unsigned char code *puts) // 发送一串字符串
{
for (; *puts != 0; puts++) Tx1Send(*puts); // 遇到停止符0结束
}
/********************* 十六进制转ASCII函数 *************************/
unsigned char HEX2ASCII(unsigned char dat)
{
dat &= 0x0f;
if(dat <= 9) return (dat + '0'); //数字0~9
return (dat - 10 + 'A'); //字母A~F
}
/********************* 主函数 *************************/
void main(void)
{
InitTimer0(); // 初始化Timer0
PrintString("定时器0初始化完毕 "); // 上电后串口发送一条提示信息
while(1)
{
if(IR_OK) // 接收到一帧完整的红外数据
{
PrintString("红外键码: 0x"); // 提示红外键码
Tx1Send(HEX2ASCII(IR_code >> 4)); // 键码高半字节
Tx1Send(HEX2ASCII(IR_code)); // 键码低半字节
if(IrUserErr) // 用户码错误,则发送用户码
{
Tx1Send(' '); // 发空格
Tx1Send(' '); // 发空格
PrintString("用户码: 0x"); // 提示用户码
Tx1Send(HEX2ASCII(IR_UserH >> 4)); // 用户码高字节的高半字节
Tx1Send(HEX2ASCII(IR_UserH)); // 用户码高字节的低半字节
Tx1Send(HEX2ASCII(IR_UserL >> 4)); // 用户码低字节的高半字节
Tx1Send(HEX2ASCII(IR_UserL)); // 用户码低字节的低半字节
}
Tx1Send(0x0d); // 发回车
Tx1Send(0x0a); // 发回车
IR_OK = 0; // 清除IR键按下标志
}
}
}
加载中...
无量寿经
5楼-- · 2019-07-16 03:58
精彩回答 2 元偷偷看……
加载中...
toothpick001
6楼-- · 2019-07-16 07:22
谢谢 分享
加载中...
一周热门
更多
>
相关问题
【东软载波ESF0654 PDS开发板活动】开箱
1 个回答
东软载波ESF0654 PDS开发板外部中断
1 个回答
东软载波ESF0654 PDS开发板高级控制定时器AD16C4T
1 个回答
用串口调试助手为什么只能在hex模式接收发送而在文本模式不行
9 个回答
触摸芯片SC02B/SC04B在地砖灯的设计方案
1 个回答
东软载波ESF0654 PDS开发板串口USART0代码分享
1 个回答
普通32位单片机使用linux的应用代码
5 个回答
东软载波ESF0654 PDS开发板AT24C04的调试
9 个回答
相关文章
51单片机与蓝牙模块连接
0个评论
51单片机的硬件结构
0个评论
基于51单片机的无线遥控器制作
0个评论
51单片机 AD转换
0个评论
51单片机数码管递增显示
0个评论
如何实现对单片机寄存器的访问
0个评论
基于51单片机的指纹密码锁
0个评论
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
51单片机
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
#include<reg51.h>
#include <intrins.h>
sbit LSA = P3^5;
sbit IRIN = P3^2;
unsigned char DisplayData[8]; //用来存放要显示的8位数的值
unsigned char IrValue[6]; //用来存放读取到的红外值
unsigned char Time;
//--声明全局函数--//
void DigDisplay(); //动态显示函数
void IrInit();
void DelayMs(unsigned int );
/*******************************************************************************
* 函数名 : DelayMs()
* 函数功能 : 延时
* 输入 : x
* 输出 : 无
*******************************************************************************/
void DelayMs(unsigned int x) //0.14ms误差 0us
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++)
{}
}
}
void Delay140us() //@11.0592MHz
{
unsigned char i, j;
i = 2;
j = 126;
do
{
while (--j);
} while (--i);
}
/*******************************************************************************
* 函数名 : IrInit()
* 函数功能 : 初始化红外线接收
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void IrInit()
{
IT0=1;//下降沿触发
EX0=1;//打开中断0允许
EA=1; //打开总中断
IRIN=1;//初始化端口
}
/*******************************************************************************
* 函数名 : ReadIr()
* 函数功能 : 读取红外数值的中断函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void ReadIr() interrupt 0
{
unsigned char j,k;
unsigned int err;
Time=0;
DelayMs(70);
if(IRIN==0) //确认是否真的接收到正确的信号
{
err=1000; //1000*10us=10ms,超过说明接收到错误的信号
/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
侯,程序死在这里*/
while((IRIN==0)&&(err>0)) //等待前面9ms的低电平过去
{
Delay140us();
err--;
}
if(IRIN==1) //如果正确等到9ms低电平
{
err=470;
while((IRIN==1)&&(err>0)) //等待4.5ms的起始高电平过去
{
Delay140us();
err--;
}
for(k=0;k<4;k++) //共有4组数据
{
for(j=0;j<8;j++) //接收一组数据
{
err=60;
while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
{
Delay140us();
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //计算高电平的时间长度。
{
Delay140us();//0.14ms
Time++;
err--;
if(Time>30)
{
EX0=1;
return;
}
}
IrValue[k]>>=1; //k表示第几组数据
if(Time>=8) //如果高电平出现大于565us,那么是1
{
IrValue[k]|=0x80;
}
Time=0; //用完时间要重新赋值
}
}
}
if(IrValue[2]!=~IrValue[3])
{
return;
}
}
}
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 使用数码管显示
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DigDisplay()
{
switch(IrValue[2])
{
case 0x45:{
LSA=0;
}break;
case 0x46:{
LSA=1;
}break;
default:break;
}
}
void main()
{
IrInit();
while(1)
{
IrValue[4]=IrValue[2]>>4; //高位
IrValue[5]=IrValue[2]&0x0f; //低位
DigDisplay();
}
}
以下程序来源于《51单片机轻松入门-基于STC15W4K系列》,
使用时重点关注2行代码,其它代码尽量不要修改。
#define MAIN_Fosc 22.1184
sbit Ir_Pin = P3^6; // 定义红外接收输入端口
///************* 功能说明 **************
//红外接收程序。适用于市场上用量最大的HT6121/6122及其兼容IC的编码。
//当遥控器用户码与程序定义的用户码不同时,程序会将遥控器的用户码一起从串口输出。
//使用模拟串口发送用户码与键码,波特率9600,接收端要求使用字符格式显示。
/******************************************/
#include "STC15W4K.H"
#define MAIN_Fosc 22.1184 // 定义主时钟, 红外接收会自动适应,5~36MHZ,但模拟串口输出部分不能自动适应。
#define User_code 0xFD02 // 定义红外接收用户码
sbit Ir_Pin = P3^6; // 定义红外接收输入端口
sbit TXD1 = P3^1; // 定义模拟串口发送脚
/************* 用户系统配置 **************/
#define TIME 125 // 选择定时器时间125us, 红外接收要求在60us~250us之间
/************* 以下宏定义用户请勿修改 **************/
#define Timer0_Reload (unsigned int)(65536 - (TIME * MAIN_Fosc /12.0)) // 定时器初值
/************* 本地变量声明 **************/
unsigned char IR_SampleCnt; // 采样次数计数器,通用定时器对红外口检测次数累加记录
unsigned char IR_BitCnt; // 记录位数
unsigned char IR_UserH; // 用户码(地址)高字节
unsigned char IR_UserL; // 用户码(地址)低字节
unsigned char IR_data; // 键原码
unsigned char IR_DataShit; // 键反码
unsigned char IR_code; // 红外键码
bit Ir_Pin_temp; // 记录红外引脚电平的临时变量
bit IR_Sync; // 同步标志(1——已收到同步信号,0——没收到)
bit IrUserErr; // 用户码错误标志
bit IR_OK; // 完成一帧红外数据接收的标志(0,未收到,1,收到一帧完整数据)
/******************** 红外采样时间宏定义, 用户不要随意修改 *******************/
//数据格式: Synchro,AddressH,AddressL,data,/data, (total 32 bit).
#if ((TIME <= 250) && (TIME >= 60)) // TIME决定测量误差,TIME太大防错能力降低,TIME太小会干扰其它中断函数执行。
#define IR_sample TIME // 定义采样时间,在60us~250us之间,
#endif
#define IR_SYNC_MAX (15000/IR_sample) // 同步信号SYNC 最大时间 15ms(标准值9+4.5=13.5ms)
#define IR_SYNC_MIN (9700 /IR_sample) // 同步信号SYNC 最小时间 9.5ms,(连发信号标准值9+2.25=11.25ms)
#define IR_SYNC_DIVIDE (12375/IR_sample) // 区分13.5ms同步信号与11.25ms连发信号,11.25+(13.5-11.25)/2=12.375ms
#define IR_DATA_MAX (3000 /IR_sample) // 数据最大时间3ms (标准值2.25 ms)
#define IR_DATA_MIN (600 /IR_sample) // 数据最小时,0.6ms (标准值1.12 ms)
#define IR_DATA_DIVIDE (1687 /IR_sample) // 区分数据 0与1,1.12+ (2.25-1.12)/2 =1.685ms
#define IR_BIT_NUMBER 32 // 32位数据
//**************************** 红外接收模块 ********************************************
// 信号第1个下降沿时刻清零计数器并让计数器从0开始计数,第2个下降沿时刻计算计数器运行时间
// 因此检测的是每个信号从低电平开始到高电平结束这段时间,也就是脉冲周期。
void IR_RX_HT6121(void)
{
unsigned char SampleTime; // 信号周期
IR_SampleCnt++; // 定时器对红外口检测次数
F0 = Ir_Pin_temp; // 保存前一次此程序扫描到的红外端口电平
Ir_Pin_temp = Ir_Pin; // 读取当前红外接收输入端口电平
if(F0 && !Ir_Pin_temp) // 前一次采样高电平并且当前采样低电平,说明出现了下降沿
{
SampleTime = IR_SampleCnt; // 脉冲周期
IR_SampleCnt = 0; // 出现了下降沿则清零计数器
//******************* 接收同步信号 **********************************
if(SampleTime > IR_SYNC_MAX) IR_Sync = 0; // 超出最大同步时间, 错误信息。
else if(SampleTime >= IR_SYNC_MIN) // SYNC
{
if(SampleTime >= IR_SYNC_DIVIDE) // 区分13.5ms同步信号与11.25ms连发信号
{
IR_Sync = 1; // 收到同步信号 SYNC
IR_BitCnt = IR_BIT_NUMBER; // 赋值32(32位有用信号)
}
}
//********************************************************************
else if(IR_Sync) // 已收到同步信号 SYNC
{
if((SampleTime < IR_DATA_MIN)|(SampleTime > IR_DATA_MAX)) IR_Sync=0; // 数据周期过短或过长,错误
else
{
IR_DataShit >>= 1; // 键反码右移1位(发送端是低位在前,高位在后的格式)
if(SampleTime >= IR_DATA_DIVIDE) IR_DataShit |= 0x80; // 区别是数据 0还是1
//*********************** 32位数据接收完毕 ****************************************
if(--IR_BitCnt == 0)
{
IR_Sync = 0; // 清除同步信号标志
if(~IR_DataShit == IR_data) // 判断数据正反码
{
if((IR_UserH == (User_code / 256)) && IR_UserL == (User_code % 256))
{
IrUserErr = 0; // 用户码正确
}
else IrUserErr = 1; // 用户码错误
IR_code = IR_data; // 键码值
IR_OK = 1; // 数据有效
}
}
// 格式: 用户码L —— 用户码H —— 键码 —— 键反码
// 功能: 将 “用户码L —— 用户码H —— 键码”通过3次接收交换后存入对应字节,
// 这样写代码可以节省内存RAM占用,但是不如用数组保存好理解。
// 键反码前面部分代码已保存好了 :IR_DataShit |= 0x80;
//**************************** 将接收的************************************************
else if((IR_BitCnt & 7)== 0) // 1个字节接收完成
{
IR_UserL = IR_UserH; // 保存用户码高字节
IR_UserH = IR_data; // 保存用户码低字节
IR_data = IR_DataShit; // 保存当前红外字节
}
}
}
}
}
/**************** Timer0初始化函数 ******************************/
void InitTimer0(void)
{
TMOD = 0x01; // 16位计数方式.
TH0 = Timer0_Reload / 256;
TL0 = Timer0_Reload % 256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
/********************** Timer0中断函数************************/
void timer0 (void) interrupt 1
{
IR_RX_HT6121();
TH0 = Timer0_Reload / 256; // 重装定时器初值
TL0 = Timer0_Reload % 256; // 重装定时器初值
}
/********************** 模拟串口相关函数************************/
void delay104us(void)
{
unsigned char i,j,k;
for(i=1;i>0;i--) // 注意后面没分号
for(j=3;j>0;j--) // 注意后面没分号
for(k=189;k>0;k--); // 注意后面有分号 101
}
//模拟串口发送
void Tx1Send(unsigned char dat) //9600,N,8,1 发送一个字节
{
unsigned char i;
EA = 0;
TXD1 = 0;
delay104us();
for(i=0; i<8; i++)
{
if(dat & 1) TXD1 = 1;
else TXD1 = 0;
dat >>= 1;
delay104us();
}
TXD1 = 1;
EA = 1;
delay104us();
delay104us();
}
void PrintString(unsigned char code *puts) // 发送一串字符串
{
for (; *puts != 0; puts++) Tx1Send(*puts); // 遇到停止符0结束
}
/********************* 十六进制转ASCII函数 *************************/
unsigned char HEX2ASCII(unsigned char dat)
{
dat &= 0x0f;
if(dat <= 9) return (dat + '0'); //数字0~9
return (dat - 10 + 'A'); //字母A~F
}
/********************* 主函数 *************************/
void main(void)
{
InitTimer0(); // 初始化Timer0
PrintString("定时器0初始化完毕 "); // 上电后串口发送一条提示信息
while(1)
{
if(IR_OK) // 接收到一帧完整的红外数据
{
PrintString("红外键码: 0x"); // 提示红外键码
Tx1Send(HEX2ASCII(IR_code >> 4)); // 键码高半字节
Tx1Send(HEX2ASCII(IR_code)); // 键码低半字节
if(IrUserErr) // 用户码错误,则发送用户码
{
Tx1Send(' '); // 发空格
Tx1Send(' '); // 发空格
PrintString("用户码: 0x"); // 提示用户码
Tx1Send(HEX2ASCII(IR_UserH >> 4)); // 用户码高字节的高半字节
Tx1Send(HEX2ASCII(IR_UserH)); // 用户码高字节的低半字节
Tx1Send(HEX2ASCII(IR_UserL >> 4)); // 用户码低字节的高半字节
Tx1Send(HEX2ASCII(IR_UserL)); // 用户码低字节的低半字节
}
Tx1Send(0x0d); // 发回车
Tx1Send(0x0a); // 发回车
IR_OK = 0; // 清除IR键按下标志
}
}
}
一周热门 更多>