欢迎光临~啄木鸟电子科技

软件设计

NEC 红外发射原理 例程

参考文献:https://blog.csdn.net/feilusia/article/details/53305956?ops_request_misc=&request_id=f1c3093fcd1c45cfa3f1834e367508cf&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~koosearch~default-2-53305956-null-null.268^v1^control&utm_term=%E7%BA%A2%E5%A4%96&spm=1018.2226.3001.4450

载波 对 载波时,输出为 低电平;


/**********************************************************************
* 函数: U8 Conversion_Num(u8 data)
* 功能: // 数据调整,调整发射(由 低到 高 位) 
* 输入: 有
* 输出: 有 
***********************************************************************/
u8 Conversion_Num(u8 data)
{
	u8 data_1 = 0;
	u8 data_2 = 0;
	
	for (u8 i = 0; i < 8; i++)
	{
		data_1 = data; 
		data_1 &= 0x01;  // 取 最末位;		 
		data_2 += data_1;
		
		if(i == 7)
		{
			return data_2;
		}
          	
		data = data >> 1; // 向右移1位,与运算,取最末位;
		data_2 = data_2 << 1;  // 向左移1位,末尾补0,加运算,数据连起
	}
	return data_2; 
}


/**********************************************************************
* 函数: Xor(u8 x_data, u8 y_xor)
* 功能: 数据 异或 取反码 
* 输入: 有
* 输出: 有 
***********************************************************************/
u8 Xor(u8 x_data, u8 y_xor)
{
	u8 a;
	u8 b;
	u8 c;
	
	a = x_data;
	b = y_xor;
	
	c = a ^ b;
	
	return c; 	        
}

/**********************************************************************
* 函数: Send_Date(u8 x_address, y_code)
* 功能: 数据调整;(发送数据) 
* 输入: 有
* 输出: 有
将 4 组数据组成 32位 码,4段(8位字节)由 低 到 高 发射出去 
***********************************************************************/
u32 Send_Date(u8 x_address, u8 y_code)
{
	u32 data = 0;
	
	u8 num_1; 
	u8 num_2; 
	u8 num_3;
	u8 num_4;

	num_1 = Conversion_Num(x_address);
	num_2 = Conversion_Num(Xor(x_address, 0xFF));
	num_3 = Conversion_Num(y_code);
	num_4 = Conversion_Num(Xor(y_code, 0xFF));
	
	data |= num_1;
	data = data << 8;
	data |= num_2;
	data = data << 8;
	data |= num_3;
	data = data << 8;
	data |= num_4;
	
	return data;

}


/**********************************************************************
* 函数: 红外发送驱动 数据 
* 功能:  
* 输入:  无;
* 输出:  无

引导码:9ms 载波 + 4.5ms 空闲 
比特值  0:560us 载波 + 560us 空闲  ( 1拍 载波 + 1拍 空闲 ) 
比特值  1:560us 载波 + 1.68ms 空闲 ( 1拍 载波 + 3 拍 空闲 ) 

1. 使用定时器 产生一个 13us 的定时中断(当13us翻转一次 IO,产生的就是38K的频率) 
2. 发送红外键值时,按 NEC时序 依次发送:( 引导码、用户码、用户反码、键码反码,停止位 (1拍 载波) )
***********************************************************************/
void Ir_Send(u32 data)
{
	u8 i = 0;
	ir_flag = 0; 				// 初始化红外,默认为 关
	
	// 9ms 起始信号,低电平, 683*13us = 8.879 ms ( 后面的 *3/4 为实际的校准3值 ) 
//	ir_count = 683 *3/4;
	ir_count = 645;
	ir_flag = 1;  				// 红外 发射 打开 
	while(ir_count);  			// 在此期间,输出 38KHz 方波 脉冲; 
	
	// 4.5ms 起始信号,高电平, 341*13us = 4.433 ms ( 后面的 *3/4 为实际的校准3值 ) 
//	ir_count = 341 *3/4;
	ir_count = 320;
	ir_flag = 0; 
	while(ir_count);   			// 在此期间,停止 输出 38KHz 方波 脉冲;
	
	// 循环发送 32bit 的数据 4 * 8 = 32 位 数据  (用户码、用户反码、键值码,键值反码) 
	for(i = 0; i < 32; i++)
	{
		//通用 0.56ms 低电平, 42 * 13us = 0.546 ms ( 后面的 *3/4 为实际的校准3值 ) 
//		ir_count = 42 * 3 / 4;
		ir_count = 42;
		ir_flag = 1;			// 红外 发射 打开 
		while(ir_count);		// 在此期间,输出 38KHz 方波 脉冲;
		
		// 数值 0
		if((data & 0x80000000) == 0)
		{
			// 0.56ms 高电平, 43 * 13us = 0.559 ms ( 后面的 *3/4 为实际的校准3值 ) 
			// 比特值 0:560us 载波 + 560us 空闲
//			ir_count = 43 * 3/4;  // 控制 打开的 时间长短   与 定时器 同行程 
			ir_count = 43;
		} 
		else
		{
			// 1.69ms 高电平, 128 * 13us = 1.664 ms ( 后面的 *3/4 为实际的校准3值 ) 
			// 比特值 1:560us 载波 + 1.68ms 空闲 
//			ir_count = 128 * 3/4; // 控制 关闭的 时间长短   与 定时器 同行程 
			ir_count = 116;  // 1.68 ms 
		} 
		
		// 执行 高 电平 
		ir_flag = 0;
		while(ir_count);
		
		data <<= 1;  // 数据向 左移 1 位,补0 
			
	} 
	
	// 停止位 1拍 发射信号 时长控制 
	ir_count = 43;
	ir_flag = 1;
	while(ir_count);
	
	// 关闭红外
	ir_flag = 0;	
} 


/**********************************************************************
* 函数:	Init_TIM4(void)
* 功能: 定时器 4  初始化 
* 输入: 无;
* 输出: 无
向上 自动计数 每 13us 中断一次;让 端口 翻转; 
//f = 38KHz -> T(周期) = 26.32 所以 单个翻转在 13us;(方波) 
***********************************************************************/

void Init_TIM4(void)
{
	TIM4_CR1 = 0x00;	// 关闭计数器
	TIM4_PSCR_PSC = 4;	// 主时钟 16MHz, TIM  采用 2……4 = 16 分频 = 1MHZ(1us);  每次计数 为 1us;  
	// TIM4_PSCR = 4;	//分频值
	// TIM4_IER=0x00;
	TIM4_IER = 0x01;	//更新中断使能
	TIM4_EGR = 0x01;

//	TIM4_CNTR = 255;	//计数器值
	TIM4_ARR =  13;		// 自动重装的值 每 13us 定时中断一次 	

//	TIM4_CR1 = 0x01;//使能计数器
	TIM4_CR1_CEN = 1; 	// 使能计数器

}


/**********************************************************************
* 函数: TIM4 中断 
* 功能:  
* 输入:  无;
* 输出:  无
在 批定 时间内 发送 38K Hz 载波 
***********************************************************************/ 
#pragma vector = 25  // TIM2 更新/上溢 
__interrupt void Inter_TIM4(void)
{ 
//	TIM4_SR = ( ~0x01 );    	//清除更新中断标志
	TIM4_SR = 0x00;
//	TIM4_SR_UIF = 0;        // 清除更新中断标志	
	// 输出一个反转信号;
	if( ir_count > 0)
	{
		ir_count --; 
	} 
	
//	计数值 计算 

	if(ir_flag == 1) // 有 输出 发射
	{
		if(ir_count > 0)
		{
			IR_T = !IR_T; // 输出 方波 
		}		
	} 
		
} 





上一个:功放类别 没有下一个

联系我们

联系人:客服在线

手机:全工:13903011251

电话:李R:13530006400

邮箱:729986191@qq.com

地址: GUANGDONG PROVINCE

用手机扫描二维码关闭
二维码