STM32(三十三)NEC紅外遙控


一、紅外遙控簡介

                                 

     

  • 紅外遙控是一種無線、非接觸控制技術,
  • 具有抗干擾能力強,信息傳輸可靠,功耗低,成本低,易實現等顯著優點,
  • 同類產品的紅外線遙控器,可以有相同的遙控頻率或編碼,而不會出現遙控信號“串門”的情況。
  • 紅外遙控的編碼目前廣泛使用的是: NEC Protocol的PWM(脈沖寬度調制)和Philips的RC-5 Protocol的PPM(脈沖位置調制)。

 二、NEC協議特征

  • 8位地址和8位指令長度;
  • 地址和命令2次傳輸(確保可靠性)
  • PWM脈沖位置調制,以發射紅外載波的占空比代表“0”和“1”;
  • 載波頻率為38Khz;
  • 位時間為1.125ms或2.25ms ( 高電平持續時間來區分);

1、NEC碼的位定義:

  • 一個脈沖對應560us的連續載波,一個邏輯1傳輸需要2.25ms ( 560us脈沖+1680us低電平),一個邏輯0的傳輸需要1.125ms ( 560us脈沖+560us低電平)。
  • 遙控接收頭在收到脈沖的時候為低電平,在沒有脈沖的時候為高電平,這樣,我們在接收頭端收到的信號為:邏輯1應該是560us低+1680us高,邏輯0應該是560us低+560us高。

                                                 

 

 

                                                         遙控器發送                                                         接收頭收到的

 

 

 

  通過原理圖可知檢測REMOTE_IN上的信號可以收到遙控發過來的信號,檢測到1680us的高電平就是數據1,檢測到560us的高電平就是0;

2、NEC遙控器指令格式

  NEC遙控指令的數據格式為:同步碼頭、地址碼、地址反碼、控制碼、控制反碼同步碼由一個9ms的低電平和一個4.5ms的高電平組成,地址碼、地址反碼、控制碼、控制反碼均是8位數據格式。按照低位在前高位在后的順序發送。采用反碼是為了增加傳輸的可靠性(可用於校驗)                       

                     

 

 

                                                                                                      

 

 

 3、實驗:遙控實現蜂鳴器開關

#include "infrared.h"

void Infrared_Init(void)
{
    GPIO_InitTypeDef	GPIO_InitStruct;    
	EXTI_InitTypeDef    EXTI_InitStruct;
	NVIC_InitTypeDef 	NVIC_InitStruct;
	
	//使能SYSCFG時鍾
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

	//使能GPIOA
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	GPIO_InitStruct.GPIO_Pin	=	GPIO_Pin_8; 	//引腳
	GPIO_InitStruct.GPIO_Mode	=   GPIO_Mode_IN; 	//輸入模式
	GPIO_InitStruct.GPIO_PuPd	=	GPIO_PuPd_UP;	//上拉
	GPIO_InitStruct.GPIO_Speed	=   GPIO_Speed_50MHz; //速度50MHZ

	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	//設置IO口與中斷線的映射關系,必須分開寫      
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource8);

	EXTI_InitStruct.EXTI_Mode		=	EXTI_Mode_Interrupt; //中斷
	EXTI_InitStruct.EXTI_Line		=	EXTI_Line8;  //中斷線8  因為是PA8,所以選擇line8
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿 下降沿觸發是因為REMOTE_IN在沒有按遙控時一直處於高電平,當按下遙控時,同步碼頭先過來,拉低,代表數據傳輸開始
EXTI_InitStruct.EXTI_LineCmd = ENABLE; //中斷線使能 //初始化線上中斷,設置觸發條件等。 EXTI_Init(&EXTI_InitStruct); NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn; //中斷號 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0x02; //搶占優先級 NVIC_InitStruct.NVIC_IRQChannelSubPriority =0x02; //響應優先級 NVIC_Init(&NVIC_InitStruct); } //計算高電平時間 t*20us u32 ir_pluse_high_time(void) { u32 t=0; while(PAin(8)) { t++; delay_us(20);//20微秒 if(t > 250)//大於5ms數據異常 break; } return t; } void EXTI9_5_IRQHandler(void) { u32 t=0; u32 ir_bit=0; u8 ir_valed=0; u32 ir_data = 0; u8 ir_cunt=0; //判斷是否中斷線8 if(EXTI_GetITStatus(EXTI_Line8) == SET) { //清除中斷標志位 EXTI_ClearITPendingBit(EXTI_Line8); while(1) { if(PAin(8))//等待到高電平,過濾低電平 { t = ir_pluse_high_time(); if(t>=250)//收到高電平數據異常 break; if(t>200 && t<250)//高電平時間為 4000 - 5000內也就是4ms - 5ms { ir_valed = 1;//有效的同步碼頭 continue; } //若高電平持續時間為200~1000us內則為數據位為0: 560us在 200-1000us之間 else if(t>10 && t<50) { ir_bit = 0; } //若高電平持續時間為1200~1800us內則為數據位為1: else if(t>60 && t<90) { ir_bit = 1; } if(ir_valed) { //將位數據移到到ir_data ir_data |=ir_bit<<ir_cunt; ir_cunt++; if(ir_cunt >= 32) { printf("ir_data = %x\n",ir_data); if(ir_data == 0XBC43FF00) //遙控上的暫停播放鍵 { PFout(8)^=1; //開關蜂鳴器 } break; } } } } } }

  

 

 

 

 

 

 

 

 

  下降沿觸發是因為REMOTE_IN在沒有按遙控時一直處於高電平,當按下遙控時,同步碼頭先過來,拉低,代表數據傳輸開始


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM