废话不多,直接切入正题,根据需要自行选择标题内容
红外接收原理介绍
红外原理性的东西,就不在这进行介绍了,不懂的可自行百度,会百度也是一种学习能力。
直接介绍红外的两部分,发射和接收。也就是发射机与接收器这两部分属于硬件的设计需要考虑的范围,如果只是单纯的想写好代码,那么就请略过本小节,直接吃透NEC通讯协议。但为了更多人考虑,还是需要介绍一下的。
发射机
通常是个带纽扣电池的手持装置。现在很多低功耗芯片用于红外发射的原因就是可以很灵活的使用,在没有遥控按钮操作时,发射机几乎不会消耗电量,当有按钮操作时会马上唤醒相应红外命令。而通常市面上的发射机都基本采用陶瓷晶振,通过对外红LED控制电流范围来实现控制距离的远近。当然对于这如何进行选择最优解还是需要根据实际情况来判断。
一个简单的晶体三极管放大威廉希尔官方网站
就可以驱动红外LED。
接收器
重点为调制频率和区域可行性。
红外信号由接收器的检波二极管接收,信号通过放大和限幅处理,使信号有稳定的脉冲电平。
不用担心不懂此处的威廉希尔官方网站
部分,因为厂家已经集成到一个接收模块中,此处可作为了解。
NEC通讯协议
这是***重点***内容
特征:
8bit地址码,8bit命令码
完整发射两次地址码和命令码
脉冲时间长短调制方式
38KHz载波频率
位时间1.12ms和2.25ms
NEC协议根据脉冲时间长短解码,每个脉冲为560us长的38KHz载波。逻辑“1”脉冲时间为2.25ms 逻辑“0”脉冲时间为1.12ms
0.56ms的低电平,1.68ms的高电平脉冲 为 1
0.56ms的低电平,0.56ms的高电平脉冲 为 0
完整的协议波形图如下
协议规定低位首先发送。每次发送信息首先是9ms的低电平脉冲,接着是4.5ms的高电平,然后就是地址码和命令码。地址码和命令码发送两次,第二次发送的是反码,用于验证接收信息的准确性。因为每位都发送一次它的反码,所以总体的发送时间是恒定的。
当然,也会有人一直按着一个按键不放,注意,一串信息只能发送一次。如果一直按着同一按键不放,发送的则是以110ms为中期的重复码。
Demo编写
先说明下思维,这种方式为计算脉冲高电平时间来判断是否为逻辑1或0.
通过采用接收器所在GPIO管脚映射到外部事件中断线上,下降沿触发中断
当然还有各种不同的写法,比如通过定时器做的,个人认为芯片外设是少而珍贵的,如果能用数学思维来解决问题是比较好,把外设留给更重要的事件使用。
具体的电器属性配置还需根据自身情况来设定
这是STM32F030芯片,根据公司的产品的威廉希尔官方网站
图所写
切不可直接 ctrl+c+v
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource6);
EXTI_InitStruct.EXTI_Line=EXTI_Line6;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI4_15_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority=2;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
计算高电平时间,有关函数中的延时,会出有关延时的各种写法的文章。此处的延时为精准的20us,不同的芯片所对应的晶振也会不同,导致延时时间不同,需要根据自身情况判断
u8 IR_High_time(void)
{
u8 t=0;
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)==1)
{
t++;
delay_us(2);
if(t>=250)
{
return t; //超时溢出
}
}
return t;
}
解码函数,不严谨的地方在于,在中断中进行了处理,切记不可在中断中处理复杂的事情,另外一个处理版本,不可公布出来。
u8 time=0,ok=0,data,Num=0;
while(1)
{
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)==1)
{
time=IR_High_time();
if(time>=250)
{
break;
}
if(time>=200&&time<250)
{
ok=1;
}
else if(time>=60&&time<90)
{
data=1;
}
else if(time>=10&&time<50)
{
data=0;
}
if(ok==1)
{
IR_Recive_data<<=1;
IR_Recive_data+=data;
if(Num>=32)
{
IR_Recive_flag=1;
break;
}
}
Num++;
}
}
最后还有两个全局变量用于判读和接收
u32 IR_Recive_data;
u8 IR_Recive_flag;
主函数部分,就只展示最简单的通过串口输出已解码的字符
while ( 1 )
{
if(IR_Recive_flag==1)
{
IR_Recive_flag=0;
printf("Recive_data: %xrn",(u16)IR_Recive_data);
}
}
废话不多,直接切入正题,根据需要自行选择标题内容
红外接收原理介绍
红外原理性的东西,就不在这进行介绍了,不懂的可自行百度,会百度也是一种学习能力。
直接介绍红外的两部分,发射和接收。也就是发射机与接收器这两部分属于硬件的设计需要考虑的范围,如果只是单纯的想写好代码,那么就请略过本小节,直接吃透NEC通讯协议。但为了更多人考虑,还是需要介绍一下的。
发射机
通常是个带纽扣电池的手持装置。现在很多低功耗芯片用于红外发射的原因就是可以很灵活的使用,在没有遥控按钮操作时,发射机几乎不会消耗电量,当有按钮操作时会马上唤醒相应红外命令。而通常市面上的发射机都基本采用陶瓷晶振,通过对外红LED控制电流范围来实现控制距离的远近。当然对于这如何进行选择最优解还是需要根据实际情况来判断。
一个简单的晶体三极管放大威廉希尔官方网站
就可以驱动红外LED。
接收器
重点为调制频率和区域可行性。
红外信号由接收器的检波二极管接收,信号通过放大和限幅处理,使信号有稳定的脉冲电平。
不用担心不懂此处的威廉希尔官方网站
部分,因为厂家已经集成到一个接收模块中,此处可作为了解。
NEC通讯协议
这是***重点***内容
特征:
8bit地址码,8bit命令码
完整发射两次地址码和命令码
脉冲时间长短调制方式
38KHz载波频率
位时间1.12ms和2.25ms
NEC协议根据脉冲时间长短解码,每个脉冲为560us长的38KHz载波。逻辑“1”脉冲时间为2.25ms 逻辑“0”脉冲时间为1.12ms
0.56ms的低电平,1.68ms的高电平脉冲 为 1
0.56ms的低电平,0.56ms的高电平脉冲 为 0
完整的协议波形图如下
协议规定低位首先发送。每次发送信息首先是9ms的低电平脉冲,接着是4.5ms的高电平,然后就是地址码和命令码。地址码和命令码发送两次,第二次发送的是反码,用于验证接收信息的准确性。因为每位都发送一次它的反码,所以总体的发送时间是恒定的。
当然,也会有人一直按着一个按键不放,注意,一串信息只能发送一次。如果一直按着同一按键不放,发送的则是以110ms为中期的重复码。
Demo编写
先说明下思维,这种方式为计算脉冲高电平时间来判断是否为逻辑1或0.
通过采用接收器所在GPIO管脚映射到外部事件中断线上,下降沿触发中断
当然还有各种不同的写法,比如通过定时器做的,个人认为芯片外设是少而珍贵的,如果能用数学思维来解决问题是比较好,把外设留给更重要的事件使用。
具体的电器属性配置还需根据自身情况来设定
这是STM32F030芯片,根据公司的产品的威廉希尔官方网站
图所写
切不可直接 ctrl+c+v
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource6);
EXTI_InitStruct.EXTI_Line=EXTI_Line6;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI4_15_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority=2;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
计算高电平时间,有关函数中的延时,会出有关延时的各种写法的文章。此处的延时为精准的20us,不同的芯片所对应的晶振也会不同,导致延时时间不同,需要根据自身情况判断
u8 IR_High_time(void)
{
u8 t=0;
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)==1)
{
t++;
delay_us(2);
if(t>=250)
{
return t; //超时溢出
}
}
return t;
}
解码函数,不严谨的地方在于,在中断中进行了处理,切记不可在中断中处理复杂的事情,另外一个处理版本,不可公布出来。
u8 time=0,ok=0,data,Num=0;
while(1)
{
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)==1)
{
time=IR_High_time();
if(time>=250)
{
break;
}
if(time>=200&&time<250)
{
ok=1;
}
else if(time>=60&&time<90)
{
data=1;
}
else if(time>=10&&time<50)
{
data=0;
}
if(ok==1)
{
IR_Recive_data<<=1;
IR_Recive_data+=data;
if(Num>=32)
{
IR_Recive_flag=1;
break;
}
}
Num++;
}
}
最后还有两个全局变量用于判读和接收
u32 IR_Recive_data;
u8 IR_Recive_flag;
主函数部分,就只展示最简单的通过串口输出已解码的字符
while ( 1 )
{
if(IR_Recive_flag==1)
{
IR_Recive_flag=0;
printf("Recive_data: %xrn",(u16)IR_Recive_data);
}
}
举报