STM32学习笔记之—红外通信

##

概述

首先大家不要觉得红外通信很难,知道原理的话其实也就那么回事儿,而本文讲解的重点不是原理性的内容(原理性的这类比较底层的知识往往比较复杂,交个那些大佬慢慢研究吧),本文主要是教大家如何使用红外通信,希望大家看了本教程之后能够进行简单的红外通信,做做简单的DIY。_


##

简单的原理

红外通信是一线式通信,也就是只需要一根线就能够通讯,GND接地,VDD接电源,最后一个根接芯片的IO口。具体的使用接线过程图如下图所示:

STM32学习笔记之—红外通信_第1张图片

####你需要知道的是:

  • 红外信息是由不同的红外高低电平脉冲组合而成的

  • 当红外接收头捕获到红外信号后,通讯线会表现为不同的高低电平

  • 芯片的一个IO管脚连接到这根通讯线,通过查询的方式读出这根线上面的高低电平信息

  • 芯片按照根据统一的通讯协议将接收到的高低信号转化为键值(一串数字)

  • 不同的信号具有不同的键值,根据不同的键值就能够区分不同的红外信息

(这只是简单的工作原理,不懂也没关系,不影响后面的编程)


##

程序讲解

程序知道原理之后是比较容易理解的,我将从三个部分讲解主要的代码

###配置阶段
代码

void hwjs_init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	/* 开启GPIO时钟及管脚复用时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15;											//---红外接收配置的管脚为PA15这个管脚,具体可以根据自己需要进行配置
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	/* 设置外部中断的模式 */ 
	EXTI_ClearITPendingBit(EXTI_Line15);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource15);	//选择GPIO管脚用作外部中断线路
	EXTI_InitStructure.EXTI_Line=EXTI_Line15;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_Init(&EXTI_InitStructure); 
	/* 设置NVIC参数 */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;			//打开EXTI15的全局中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	//抢占优先级为0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;				//响应优先级为1
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;						//使能
	NVIC_Init(&NVIC_InitStructure);
}

代码说明

以上是配置过程的代码部分,将A15配置为输入模式,同时打开中断
配置好后中断函数为EXTI15_10_IRQHandler()


###中断函数

代码

void EXTI15_10_IRQHandler(void)	  //红外遥控外部中断
{
	u8 Tim=0,Ok=0,Data,Num=0;
   while(1)
   {
	  if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)==1)
		{
			 Tim=HW_jssj();//获得此次高电平时间
			 if(Tim>=250) break;//不是有用的信号
			 if(Tim>=200 && Tim<250)
			 {
				 Ok=1;//收到起始信号
			 }
			 else if(Tim>=60 && Tim<90)
			 {
				 Data=1;//收到数据 1
			 }
			 else if(Tim>=10 && Tim<50)
			 {
				 Data=0;//收到数据 0
			 }
			 if(Ok==1)
			 {
					hw_jsm<<=1;
					hw_jsm+=Data;

				if(Num>=32)
				{
					hw_jsbz=1;
				  break;
				}
			 }
			 Num++;
		}
   }
   EXTI_ClearITPendingBit(EXTI_Line15);	
}

代码说明

  • HW_jssj()为获得高电平持续时间的函数(具体代码见附录)
  • 当收到信号后,通过不停地查询判断将接收到的信号解析到"hw_jsm"里面同时将标志位"hw_jsbz"置"1"
  • hw_jsbz"置"1"表示成功解析到一个完整地红外信号

###主函数

代码

int main()
{	
  hwjs_init();										//红外接口初始化
	while(1)
	{
		if(hw_jsbz==1)								//如果红外接收到数据了
		{
			if(hw_jsm==0x00FFA25D)			//---当接收到0x00FFA25D这个键值的红外信号时
			{
				/*程序1*/	
			}
			else if(hw_jsm==0x00FF30CF)	//---当接收到0x00FF30CF这个键值的红外信号时
			{
				/*程序2*/
			}	
			hw_jsbz=0;									//清零
			hw_jsm=0;										//接收码清零(存放红外编码数据的地方)
		}			
	}			
}

代码说明

  • 进行初始化操作
  • 当接收到红外信号后就判断红外信号的键值。
  • 根据键值选择去执行哪一段程序。
  • 执行完之后就继续等待。

##

你可能会遇到的问题以及建议解决方法

附录的程序不能够运行?

本程序是Keil4的代码,检查Keil是否破解,路径是否含有中文字符等。

代码不能够下载到芯片里面?

本程序使用的芯片是STM32F103C8T6,打开配置串口("Option for Target’Target1’“或者按快捷键"Alt+F7”)
选择正确的芯片类型
选择正确的烧录工具
选正确的Flash的大小
检查烧录的连线以及供电(一般不会出现这个问题)


如果大家还有什么疑问或者我讲的有什么不对的地方欢迎在评论区留言,一起交流讨论_

附录:

源代码链接:https://pan.baidu.com/s/1jwkEQHB1-QH2mOf3xwYj4A 密码:yh0n

你可能感兴趣的:(STM32)