/****************************************
函数功能:定时器写红外
函数说明:定时器使用定时器0,外部中断0
使用环境: 硬件: MCU: ATmega32L
F_CPU = 16000000
外部:16000000
解码遥控器:基地制衣厂版:RC-E16T
编译环境:WinAVR-20080610
显示说明:
包含文件 :time0_init.c
日期:2009年8月9日
作者:杨琦
修改者: (日期: )
*****************************************/
//!!!!!!红外数据读取成功标识,在中断中使用标志位,必须加Volatile,防止编译器对程序进行优化处理!!!!!
volatile uint8_t got_hw = 0 ;
//!!!!!!红外数据读取成功标识,在中断中使用标志位,必须加Volatile,防止编译器对程序进行优化处理!!!!!
uint8_t first_flag_hw = 0 , //第一起始信号到来标识
second_flag_hw= 0 ; //第二起始信号到来标识
uint8_t data_cnt_hw = 0 , //红外数据位数计数清零
addr_cnt_hw = 0 , //红外地址位数计数清零
addr_hw = 0 , //红外地址值清零
data_hw = 0 ; //红外数据值清零
volatile uint32_t cnt_100us = 0 ; //用于计时器0中的 100us计数器 TIME = T * cnt_100us T为记时周期:100us
/****************************************
** 函数名:hw_judge_in_int0(void)
** 功能 :红外数据处理
** 子函数:无
** 变量 :无
** 外部标识:got_hw
****************************************/
void hw_judge_in_int0(void)
{
char cnt = cnt_100us ;
cnt_100us = 0 ;
if( cnt < 7 ) //下降沿间隔低于1.04ms的,则是错误信号
{
//数据位数计数清零
first_flag_hw = 0 ; //第一起始信号清零
second_flag_hw= 0 ; //第二起始信号清零
data_cnt_hw = 0 ; //数据位数计数清零
addr_cnt_hw = 0 ; //地址位数计数清零
addr_hw = 0 ; //地址值清零
data_hw = 0 ; //数据值清零
}
else if( cnt > 8 && cnt < 14 ) // 下降沿间隔1.04ms是'0'信号 //实测值:cnt_100us == 9
{
if( first_flag_hw==1 && second_flag_hw==1 ) //在接收数据的阶段
{
if( data_cnt_hw < 8 )//确保数据值不被移出
{
data_cnt_hw++ ; //数据位数计数自增
data_hw <<= 1 ; //存入'0',从高位接起 最后放入的是低位
if( data_cnt_hw == 8 )
{
got_hw = 1 ;
}
}
}
else if( first_flag_hw==1 && second_flag_hw==0 )//在接收地址的阶段
{
if( addr_cnt_hw < 8 )//确保地址值不被移出
{
addr_cnt_hw++ ; //地址位数计数自增
addr_hw <<= 1 ; //存入'0',从高位接起 最后放入的是低位
}
}
else //否则出错 回到原来状态
{
//数据位数计数清零
first_flag_hw = 0 ; //第一起始信号清零
second_flag_hw= 0 ; //第二起始信号清零
data_cnt_hw = 0 ; //数据位数计数清零
addr_cnt_hw = 0 ; //地址位数计数清零
addr_hw = 0 ; //地址值清零
data_hw = 0 ; //数据值清零
}
}
else if( cnt > 18 && cnt < 23 ) // 下降沿间隔2.12ms是'1'信号 //实测值:cnt_100us == 18(有时候是19)
{
if( first_flag_hw==1 && second_flag_hw==1 ) //在接收数据的阶段
{
if( data_cnt_hw < 8 )//确保数据值不被移出
{
data_cnt_hw++ ; //数据位数计数自增
data_hw <<= 1 ; data_hw |= 0x01 ;//存入'1',从高位接起 最后放入的是低位
if( data_cnt_hw == 8 )
{
got_hw = 1 ;
}
}
}
else if( first_flag_hw==1 && second_flag_hw==0 )//在接收地址的阶段
{
if( addr_cnt_hw < 8 )//确保地址值不被移出
{
addr_cnt_hw++ ; //地址位数计数自增
addr_hw <<= 1 ; addr_hw |= 0x01 ;//存入'1',从高位接起 最后放入的是低位
}
}
else //否则出错 回到原来状态
{
//数据位数计数清零
first_flag_hw = 0 ; //第一起始信号清零
second_flag_hw= 0 ; //第二起始信号清零
data_cnt_hw = 0 ; //数据位数计数清零
addr_cnt_hw = 0 ; //地址位数计数清零
addr_hw = 0 ; //地址值清零
data_hw = 0 ; //数据值清零
}
}
else if( cnt > 45 && cnt < 50 ) // 下降沿间隔4.72ms是第二起始信号 //实测值:cnt_100us == 42
{
if( first_flag_hw == 1)//如果收到过第一起始信号 而且 收到过8位地址 && addr_cnt_hw == 8
{
second_flag_hw= 1 ; //第二起始信号置一
addr_cnt_hw = 0 ; //地址位数计数清零
data_cnt_hw = 0 ; //数据位数计数清零
}
else //否则出错 回到原来状态
{
//数据位数计数清零
first_flag_hw = 0 ; //第一起始信号清零
second_flag_hw= 0 ; //第二起始信号清零
data_cnt_hw = 0 ; //数据位数计数清零
addr_cnt_hw = 0 ; //地址位数计数清零
addr_hw = 0 ; //地址值清零
data_hw = 0 ; //数据值清零
}
}
else if( cnt > 120 && cnt < 130 ) // 下降沿间隔12.6ms是第一起始信号 //实测值:cnt_100us == 112
{
first_flag_hw = 1 ; //第一起始信号置一
second_flag_hw= 0 ; //第二起始信号清零
data_cnt_hw = 0 ; //数据位数计数清零
addr_cnt_hw = 0 ; //地址位数计数清零
}
else //大于12.6ms则不是起始信号 //实测值:cnt_100us == 250
{
//数据位数计数清零
first_flag_hw = 0 ; //第一起始信号清零
second_flag_hw= 0 ; //第二起始信号清零
data_cnt_hw = 0 ; //数据位数计数清零
addr_cnt_hw = 0 ; //地址位数计数清零
addr_hw = 0 ; //地址值清零
data_hw = 0 ; //数据值清零
}
}
转载请注明出处。作者:四极管。广西师范大学 电子工程学院大学生科技创新基地 邮箱: yangxingbo-0311@163.com。
四极管:红外之AVR 红外解码
最新推荐文章于 2020-08-08 10:26:22 发布