uchar irdata[];
uchar a[4]={0x00,0xff,0x11,0x11}; //储存引导码高低电平宽度、用户码、用户反码与键数据码、键数据反码
uint LowTime,HighTime; //储存高、低电平的宽度
u8 OP; //红外发射管的亮灭
uint count; //延时计数器
uint endcount; //终止延时计数
uchar flag; //红外发送标志
void SendIRdata();
void delay();
void DeCodestudy();
void TIM1_Confing(void)
{
TIM1_DeInit();
TIM1_TimeBaseInit(16, TIM1_COUNTERMODE_UP, 26, 0x00);
TIM1_ClearFlag(TIM1_FLAG_UPDATE);
TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
TIM1_Cmd(DISABLE);
TIM1_SetCounter(0);
}
void TIM2_Confing()
{
TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_PRESCALER_16, 0x0000);
TIM2_Cmd(DISABLE);
}
void TIM1_Interrupt()
{
if(TIM1_GetITStatus(TIM1_IT_UPDATE)!=RESET)
TIM1_ClearITPendingBit(TIM1_IT_UPDATE);
count++;
if (flag==1)
{
OP=~OP;
GPIO_WriteReverse(GPIOF, GPIO_PIN_4);
}
else
{
OP = 0;
GPIO_WriteLow(GPIOF, GPIO_PIN_4);
}
}
void main(void)
{
disableInterrupts();
CLK_Config();
GPIO_Config();
TIM1_Confing();
count = 0 ;
flag = 0;
OP = 0;
GPIO_WriteLow(GPIOF, GPIO_PIN_4);
GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_IN_PU_IT);
EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB, EXTI_SENSITIVITY_FALL_LOW);
enableInterrupts();
do
{
delay();
SendIRdata();
}
while(1);
} //定时器0中断处理
void SendIRdata()
{
int i;
char irdata; //发送9ms的起始码
endcount=223;
flag=1;
count=0;
TIM1_Cmd(ENABLE);
do{}
while(count<endcount); //发送4.5ms的结果码
TIM1_Cmd(DISABLE);
endcount=117 ;
flag=0;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount); //发送十六位地址的前八位
TIM1_Cmd(DISABLE);
irdata=a[0];
for(i=0;i<8;i++) //先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
{
endcount=10;
flag=1;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount); //停止发送红外信号(即编码中的高电平)
TIM1_Cmd(DISABLE);
if(irdata-(irdata/2)*2) //判断二进制数个位为1还是0
{
endcount=41; //1为宽的高电平
}
else
{
endcount=15; //0为窄的高电平
}
flag=0;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount);
TIM1_Cmd(DISABLE);
irdata=irdata>>1;
} //发送十六位地址的后八位
irdata=a[1];
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount);
TIM1_Cmd(DISABLE);
if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount);
TIM1_Cmd(DISABLE);
irdata=irdata>>1;
} //发送八位数据
irdata=a[2];
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount);
TIM1_Cmd(DISABLE);
if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount);
TIM1_Cmd(DISABLE);
irdata=irdata>>1;
} //发送八位数据的反码
irdata=~a[2];
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount);
TIM1_Cmd(DISABLE);
if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount);
TIM1_Cmd(DISABLE);
irdata=irdata>>1;
}
endcount=10;
flag=1;
count=0;
TIM1_SetCounter(0);
TIM1_Cmd(ENABLE);
do{}
while(count<endcount);
TIM1_Cmd(DISABLE);
flag=0;
}
void delay()
{
int i,j;
for(i=0;i<400;i++)
{
for(j=0;j<100;j++)
{
}
}
}
/************************************************************
函数功能:对4个字节的用户码和键数据码进行解码
说明:解码正确,返回1,否则返回0
出口参数:dat
/****************************************************************************/
void DeCodestudy()
{
uchar i,j,k;
uchar temp; //储存解码出的数据
GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_IN_PU_NO_IT);
while(GPIO_ReadInputPin(GPIOB, GPIO_PIN_5)== SET);
TIM2_SetCounter(0x00);
TIM2_Cmd(ENABLE);
while(GPIO_ReadInputPin(GPIOB, GPIO_PIN_5)==RESET); //如果是低电平就等待,给引导码低电平计时
TIM2_Cmd(DISABLE); //关闭定时器T0
LowTime= TIM2_GetCounter(); //保存低电平时间
TIM2_SetCounter(0x00);
TIM2_Cmd(ENABLE);
while(GPIO_ReadInputPin(GPIOB, GPIO_PIN_5)== SET); //如果是高电平就等待,给引导码高电平计时
TIM2_Cmd(ENABLE); //关闭定时器T0
HighTime=TIM2_GetCounter(); //保存引导码的高电平长度
TIM2_SetCounter(0x00);
if((LowTime>8500)&&(LowTime<9500)&&(HighTime>4020)&&(HighTime<5000))
{
//如果是引导码,就开始解码,否则放弃,引导码的低电平计时
//次数=9000us/0.9995=9004, 判断区间:9004-500=8504,9004+500=9504.
for(i=0;i<4;i++) //连续读取4个用户码和键数据码
{
for(j=0;j<8;j++) //每个码有8位数字
{
temp=temp>>1; //temp中的各数据位右移一位,因为先读出的是高位数据
TIM2_SetCounter(0x00);
TIM2_Cmd(ENABLE); //开启定时器T0
while(GPIO_ReadInputPin(GPIOB, GPIO_PIN_5)== RESET); //如果是低电平就等待
TIM2_Cmd(DISABLE);
LowTime=TIM2_GetCounter();
TIM2_SetCounter(0x00);
TIM2_Cmd(ENABLE);
while(GPIO_ReadInputPin(GPIOB, GPIO_PIN_5)== SET); //如果是高电平就等待
TIM2_Cmd(DISABLE); //关闭定时器T0
HighTime=TIM2_GetCounter(); //保存高电平宽度
if((LowTime<400)||(LowTime>700))
k=0;
return ; //如果低电平长度不在合理范围,则认为出错,停止解码
if((HighTime>460)&&(HighTime<660)) //如果高电平时间在560微秒左右,即计数560/0.9995=560次
temp=temp&0x7f; //(560-100=460, 560+100=660),则该位是0
if((HighTime>1400)&&(HighTime<1900)) //如果高电平时间在1680微秒左右,即计数1680/0.9995=1700次
temp=temp|0x80; //(1700-250=1450,1700+250=1950),则该位是1
}
ir_data[i]=temp; //将解码出的字节值储存在a
}
}
if(ir_data[2]]==~ir_data[3]) //验证键数据码和其反码是否相等,一般情况下不必验证用户码
k=1;
return ; //解码正确,返回1
if(k==1)
{
GPIO_WriteReverse(GPIOB, GPIO_PIN_0);
};
}
此帖出自
小平头技术问答
一周热门 更多>