- 打卡等级:初来乍到
- 打卡总天数:3
- 最近打卡:2024-12-06 08:15:07
已绑定手机
注册会员
- 积分
- 129
|
发表于 2024-12-2 19:56:57
|
显示全部楼层
#include <STC8G.H>
#include "intrins.h"
//引脚定义
sbit LED=P5^4; //指示灯
sbit IR=P5^5; //红外发射
sbit JS_input=P3^3; //接收信号
sbit Output_control=P3^2; //输出信号
//数据定义和声明
unsigned int Lowtime,Hightime;
unsigned char ircode[];
bit ir_read(ircode);
bit ir_flag=0;//一帧数据接收完成的标志位
typedef unsigned char uint8_t;
#define u8 uint8_t
u8 JS_INPUT_code(void);
//定时8.77us
void Timer2_Init(void) //8.77微秒@11.0592MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x9B; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
}
//载波38KHZ
void Send_Ir(unsigned int i) //38KHZ的频率 一个周期26.3us i个周期 发红外光 占空比1/3
{
while(i--)
{
IR=1;
Timer2_Init();
IR=0;
Timer2_Init();
Timer2_Init();
}
}
void No_send_Ir(unsigned int i) // 38KHZ的频率 一个周期26.3us i个周期 不发红外光
{
while(i--)
{
IR=0;
Timer2_Init();
Timer2_Init();
Timer2_Init();
}
}
//发送低电平
void Send_NEC_0(void)//低电平宽度1120us
{
Send_Ir(21);
No_send_Ir(21);
}
//发送高电平
void Send_NEC_1(void)//高电平宽度2240us
{
Send_Ir(21);
No_send_Ir(64);
}
//发送一帧数据
void ir_send_pulse(unsigned int uers_code,unsigned int data_code)//输出高低一个周期的高低脉冲
{
unsigned int i;
unsigned int temp;
Send_Ir(342); //9ms载波的引导码
No_send_Ir(171); //4.5ms
temp = uers_code;
for(i=0;i<16;i++) //16位地址码
{
if(temp & 0x0001)
{Send_NEC_1();}
else
{Send_NEC_0();}
temp >>= 1;
}
temp=data_code;
for(i=0;i<16;i++) //16位数据码
{
if(temp & 0x0001)
{Send_NEC_1();}
else
{Send_NEC_0();}
temp >>= 1;
}
Send_NEC_0();//结束码
}
//延时100ms
void Delay100ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
i = 6;
j = 157;
k = 59;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//外部中断0初始化
void js_out_init(void) //接收信号中断0初始化
{
JS_input=1; //置为高电平
IT0=1; //下降沿触发
EX0=1; //打开外部中断
TMOD &=0xf0;
TMOD |=0x01; //定时器的工作方式 设置定时器0的工作方式1
TR0 = 0;
EA = 1;//开总中断
}
//外部中断0的服务函数
void EX0_ISR() interrupt 0
{
EX0=0;
}
//红外解码函数
u8 JS_INPUT_code(void)
{
TL0 = 0; //定时器初值清零,为定时做准备
TH0 = 0;
TR0=1;//打开定时器,计算引导码低电平的时间
while(JS_input==0);//计时等待
TR0=0;//不计时
Lowtime=TH0*256+TL0;//低电平的时间 us
if(((Lowtime>8500)&&(Lowtime<9500))!=1) //判断时间是不是9ms,合适就计算高电平时间
{
EX0=1;
return;
}
TL0 = 0; //定时器初值清零,为定时做准备
TH0 = 0;
TR0=1;//打开定时器,计算引导码高电平的时间
while(JS_input==1);//计时等待
TR0=0;//不计时
Hightime=TH0*256+TL0;//高电平的时间 us
if((Hightime>4000)&&(Hightime<5000)!=1) //判断时间是不是4.5ms,合适就读数据
{
ir_flag = ir_read(*ircode);
EX0=1;
return;
}
TL0 = 0; //定时器初值清零,为定时做准备
TH0 = 0;
TR0=1;//打开定时器,计算高电平的时间?
while(JS_input==0);//计时等待
TR0=0;//不计时
Lowtime=TH0*256+TL0;//低电平的时间 us
if(((Lowtime>520)&&(Lowtime<620))!=1)
{EX0=0;}
TL0 = 0; //定时器初值清零,为定时做准备
TH0 = 0;
TR0=1;//打开定时器,计算低电平的时间
while(JS_input==1);//计时等待
TR0=0;//不计时
Hightime=TH0*256+TL0;//高电平的时间 us
if((Hightime>520)&&(Hightime<620)!=1)
{EX0=0;}
return 1;
}
bit ir_read(unsigned char *pbuf)
{
unsigned char i,j;
unsigned char temp=0;
for(i=0;i<4;i++) //读取4个字节的数据
{
for(j=0;j<8;j++) //接收一个字节 8个位
{
temp = temp>>1;
TL0 = 0; //定时器初值清零,为定时做准备
TH0 = 0;
TR0=1;//打开定时器
while(JS_input==0);//计时等待
TR0=0;//不计时
Lowtime=TH0*256+TL0;//低电平的时间 us 载波的时间
TL0 = 0; //定时器初值清零,为定时做准备
TH0 = 0;
TR0=1;//打开定时器
while(JS_input==1);//计时等待
TR0=0;//不计时
Hightime=TH0*256+TL0;//高电平的时间 us
if((Lowtime<420)||(Lowtime>660))//判断载波时间要在560us
return 0;//退出
if((Hightime>500)&&(Hightime<620))//判断高电平的时间 认为是0 bit
temp=temp &0x7f; //0111 1111 //从低位先出
if((Hightime>1500)&&(Hightime<1720))//认为是1 bit
temp=temp | 0x80; //1000 0000
}
pbuf[i]=temp;
temp=0;
}
return ir_flag;
}
//主函数
void main(void)
{
P3M0 &= ~0x0f;
P3M1 &= ~0x0f; //P3.0-3.3引脚为准双向口模式
P5M0 |=0x30; //P5.4 P5.5引脚为推挽输出模式
P5M1 &= ~0x30;
LED=0;
js_out_init();
JS_input=1;
Output_control=0;
IR=1;
Delay100ms();
while(1)
{
IR=1;
ir_send_pulse();
Delay100ms();
if(JS_INPUT_code()==ir_send_pulse)//判断有没有接收到红外信号 并且接收成功
Output_control=1; //输出高电平
LED=1; //开灯
}
}
编译后还是有7个警告。请大家帮忙指正一下。返回用CY也不行试了一下。要求引导码+地址码+数据码(返回到这个位置)+校验码
|
|