STM32单片机学习(12) 红外信号接收解码(外部中断)

发布者:Quail最新更新时间:2016-05-12 来源: eefocus关键字:STM32  红外信号  接收解码  外部中断 手机看文章 扫描二维码
随时随地手机看文章
本程序主要利用外部中断,实现红外遥控器信号接收解码,并利用串口通信把编码传至计算机显示

注:STM32单片机学习(12) 红外信号接收解码(外部中断)
请用质量好点的遥控器实验STM32单片机学习(12) 红外信号接收解码(外部中断)
用了劣质遥控器浪费了一天时间,数据位接收总是不完整,后来用宿舍空调遥控器就解码成功了STM32单片机学习(12) 红外信号接收解码(外部中断)

相关资料

STM32单片机学习(2) 外部中断 http://blog.csdn.net/leytton/article/details/38063335 

STM32单片机学习(3) 串口中断通信  http://blog.csdn.net/leytton/article/details/38393553 

STM32单片机学习(7) 串口通信printf重定向 http://blog.csdn.net/leytton/article/details/38393967

STM32-外设篇 视频教程(Cortex-M3)-主讲人:刘洋   http://yun.baidu.com/pcloud/album/info?uk=2853967793&album_id=5492137931588632574

 

效果如图:格力空调遥控器红外信号接收解码,很多复合按键编码,不同编码实现不同空调功能

STM32单片机学习(12) 红外信号接收解码(外部中断)
 

贴代码:

 

/*
*	
* 软件功能:	 红外线接收
* 
*/
#include "stm32f10x.h"
#include 
#include "delay.h"
  
void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART1_Configuration(void);
void Uart1_PutChar(u8 ch);
void Uart1_PutString(u8* buf , u8 len);
int fputc(int ch, FILE *f);

void NVIC_Configuration(void);
void EXTI_Configuration(void);

u8 HW_ReceiveTime(void);
							
/*
函数: int main(void)
功能: main主函数
参数: 无
返回: 无
/
int main(void)
{
  RCC_Configuration();
  GPIO_Configuration();
  
  delay_init(72);
  USART1_Configuration();
  NVIC_Configuration();
  EXTI_Configuration();
  printf("start\n");
  GPIO_ResetBits(GPIOA,GPIO_Pin_0);//灭	 
  while(1);
}

/*
函数: void RCC_Configuration(void)
功能: 复位和时钟控制 配置
参数: 无
返回: 无
/
void RCC_Configuration(void)
{
  ErrorStatus HSEStartUpStatus;                    //定义外部高速晶体启动状态枚举变量
  RCC_DeInit();                                    //复位RCC外部设备寄存器到默认值
  RCC_HSEConfig(RCC_HSE_ON);                       //打开外部高速晶振
  HSEStartUpStatus = RCC_WaitForHSEStartUp();      //等待外部高速时钟准备好
  if(HSEStartUpStatus == SUCCESS)                  //外部高速时钟已经准别好
  {
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法.位置:RCC初始化子函数里面,时钟起振之后
    FLASH_SetLatency(FLASH_Latency_2);                    //flash操作的延时
      	
    RCC_HCLKConfig(RCC_SYSCLK_Div1);               //配置AHB(HCLK)时钟等于==SYSCLK
    RCC_PCLK2Config(RCC_HCLK_Div1);                //配置APB2(PCLK2)钟==AHB时钟
    RCC_PCLK1Config(RCC_HCLK_Div2);                //配置APB1(PCLK1)钟==AHB1/2时钟
         
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  //配置PLL时钟 == 外部高速晶体时钟 * 9 = 72MHz
    RCC_PLLCmd(ENABLE);                                   //使能PLL时钟
   
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)    //等待PLL时钟就绪
    {
    }
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);            //配置系统时钟 = PLL时钟
    while(RCC_GetSYSCLKSource() != 0x08)                  //检查PLL时钟是否作为系统时钟
    {
    }
  }
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);  //允许 GPIOA、USART1、AFIO时钟
}

/*
函数: void GPIO_Configuration(void)
功能: GPIO配置
参数: 无
返回: 无
/
void GPIO_Configuration(void)
{
  
  GPIO_InitTypeDef GPIO_InitStructure;        //定义GPIO初始化结构体

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复合推挽输出 	 
  GPIO_Init(GPIOA, &GPIO_InitStructure); 	   //PA9串口输出


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;	  //红外接收
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //配置成上拉输入; 
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  
}


/*
	函数名:USART1_Configuration
	输  入:
	输  出:
	功能说明:
	初始化串口硬件设备,启用中断
	配置步骤:
	(1)打开GPIO和USART1的时钟
	(2)设置USART1两个管脚GPIO模式
	(3)配置USART1数据格式、波特率等参数
	(4)使能USART1接收中断功能
	(5)最后使能USART1功能
*/
void USART1_Configuration(void)	  //串口配置   详见《STM32的函数说明(中文).pdf》P346
{
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate=9600;   //波特率为9600
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;  //数据位为8
	USART_InitStructure.USART_StopBits=USART_StopBits_1; //在帧结尾传输 1 个停止位
	USART_InitStructure.USART_Parity=USART_Parity_No; //校验模式:奇偶失能
	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //硬件流控制失能
	USART_InitStructure.USART_Mode=USART_Mode_Tx | USART_Mode_Rx; //USART_Mode 指定了使能或者失能发送和接收模式:发送使能|接收失能
	USART_Init(USART1, &USART_InitStructure);	  //初始化配置

	USART_Cmd(USART1,ENABLE);	//使能或者失能 USART 外设
	USART_ClearFlag(USART1, USART_FLAG_TC);//清除传输完成标志位,否则可能会丢失第1个字节的数据.USART_FLAG_TC为发送完成标志位
}


//发送一个字符
void Uart1_PutChar(u8 ch)
{
    USART_SendData(USART1, (u8) ch);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送完成
}

//发送一个字符串 Input : buf为发送数据的地址 , len为发送字符的个数
void Uart1_PutString(u8* buf , u8 len)
{   
	u8 i;
    for(i=0;i=250) return t;//超时溢出
	}

	return t;
}

/*
                中断服务程序
/
void EXTI9_5_IRQHandler()	  
{
	 u8 time=0,startSignal=0,Data=0,Count=0;
	 u32 HW_ReceivedData=0;
	 //printf("1\n");
	 if(EXTI_GetITStatus(EXTI_Line8) == SET)//检查指定的EXTI线路触发请求发生与否,返回一个EXTI_Line新状态
      {
           	//printf("5\n"); 
	 		//if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0))  GPIO_SetBits(GPIOA,GPIO_Pin_0);//点亮LED
			//else  GPIO_ResetBits(GPIOA,GPIO_Pin_0);//灭
			while(1)
			{
					if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)==1)
					{
						 time = HW_ReceiveTime();
						  
						 if(time>=250)
						 {
						 	//printf("VoverTime:%x\n",time); 
							startSignal=0;
							HW_ReceivedData=0;
							Count=0;
							break;
						 } 
						 else if(time>=200 && time<250)
						 {
						 	  startSignal=1;//收到起始信号
							  HW_ReceivedData=0;
							  Count=0;
							  continue;
						 } 
						 else if(time>=60 && time<90)  Data=1;//收到数据 1
						 else if(time>=10 && time<50)  Data=0;//收到数据 0
						 //printf("%x ",Data);
						 if(startSignal==1)
						  {
							 	HW_ReceivedData<<=1;
								HW_ReceivedData+=Data;
								Count++;
								if(Count>=32)
								{
									//printf("received:%x\n",HW_ReceivedData);
									if(HW_ReceivedData==0x1090000a)  printf("红外编码:0x%8X,指令:打开空调\n",HW_ReceivedData);
									else if(HW_ReceivedData==0x90000a)  printf("红外编码:0x%08X,指令:关闭空调\n",HW_ReceivedData);
									else   printf("红外编码:0x%08X,指令:未知\n",HW_ReceivedData);
									HW_ReceivedData=0;
									Count=0;
									startSignal=0;
									break;
								} 
								
						  }	  
					}
			}
			
          	EXTI_ClearITPendingBit(EXTI_Line8);//清除线路挂起位
            EXTI_ClearFlag(EXTI_Line8);//清除中断挂起位 
     } 
}

关键字:STM32  红外信号  接收解码  外部中断 引用地址:STM32单片机学习(12) 红外信号接收解码(外部中断)

上一篇:STM32单片机学习(2) 外部中断
下一篇:STM32外部中断学习笔记

推荐阅读最新更新时间:2024-03-16 14:53

STM32控制GPIO讲解
一。GPIO简介 STM32的IO口有8中配置方式: 输入 浮空输入GPIO_IN_FLOATING ——浮空输入,可以做KEY识别,RX1 带上拉输入GPIO_IPU——IO内部上拉电阻输入 带下拉输入GPIO_IPD—— IO内部下拉电阻输入 模拟输入GPIO_AIN ——应用ADC模拟输入,或者低功耗下省电 输出 开漏输出GPIO_OUT_OD ——IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。 推挽输出GPIO_OUT_PP ——IO输出0-接GND, IO输出1 -接VCC,读输入值是未知的 复用功能的推挽输出GPIO_AF_PP ——片内外设功能(I2C的SCL,SDA) 复用功能的开
[单片机]
使用Ulink2的JTAG与SWD 调试stm32 区别
一、硬件连接 我调试stm32F407使用的ULINK2,Ulink2内部实物图如下。 1.1 JTAG interface 标准20pin JTAG引脚中,JTAG调试只使用8pin,定义如下: 1)NTRST ---------------Test ReSeT/ pin — Use 100K Ohm pull-up resistor to VCC. 必须有该引脚 2)TDI -----------------Test Data In pin — Use 100K Ohm pull-up resistor to VCC.数据输入 必须有该引脚 3)TMS/SW
[单片机]
使用Ulink2的JTAG与SWD 调试<font color='red'>stm32</font> 区别
STM32 BOOT模式配置以及作用
一、三种BOOT模式介绍 所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。 Main Flash memory 是STM32内置的Flash,一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。 System memory 从系统存储器启动,这种模式启动的程序功能是由厂家设置的。一般来说,这种启动方式用的比较少。系统存储器是芯片内部一块特定的区域,STM32在出厂时,由ST在这个区域内部预置了一段BootLoader, 也就是我们常说的ISP程序, 这是一
[单片机]
<font color='red'>STM32</font> BOOT模式配置以及作用
STM32堆栈学习
STM32里面 STACK 和 HEAP ,前者为堆,后者为栈。 今天在调试一段向Server发送程序的时候:出现一个奇怪的现象: fun(){ fun1( ); //初始化 fun2( ); //链接远程服务器 fun3( ); //发送数据 } 整体运行的时候,运行到fun3( );的地方就出现HaltFault!注释掉fun3( ),然后运行fun1( )和fun2( );可以运行。再注释掉fun1( )和fun2( )(此时已经链接上),单独运行fun3( );也能运行。吃午饭是和同事说明这一情况,他提醒说是不是因为堆栈的问题,后来回来查看MAP文件情况。 ===================
[单片机]
stm32驱动SST25VF程序
main.c: #include stm32f10x_lib.h #include hw_conf.h #include SST25V.h void delay(int d); u8 Tx_Buffer = {0x72,0x62,0x02,0x78,0x60,0x96,0x86,0x79,0x85,0x24,0x36,0x48,0x56,0x68,0x70,0x75,0x88,0x24}; u8 Rx_Buffer ; u8 DataByte=0; int main(void) { #ifdef DEBUG debug(); #endif Setup_System(); //系统启动 SST25V_Init(); //
[单片机]
STM32入门学习笔记之温湿度采集实验1
11.1 实验简介 11.1.1 温度采集方案概述 本实验采用三种方式来获取温湿度值,一种是STM32芯片内部自带的温度传感器,一种是基于单总线协议的DS18B20温度传感器,还有一种就是温湿度传感器DHT11或者DHT22,但是在成本上DHT22比较高,所以实验仅使用DHT11,DS18B20和内部温度传感器进行。 11.1.2 单线协议 单总线协议是美国的达拉斯公司推出的一款总线通信协议,所谓单线协议,就是通过一根线传输所有的数据,通俗地讲就是根据低电平的时间来判断总线上的数据是0还是1,比如拉低总线10us,就认为发送的是1,拉低总线50us,就认为发送的是0,单总线协议中,有3种时序,即写时序,读时序和检测时序。我们在
[单片机]
<font color='red'>STM32</font>入门学习笔记之温湿度采集实验1
STM32 F4 从bootloader跳转用户代码遇到的问题
代码跳转后运行用户程序遇到的问题: DMA2_Stream3_IRQHandler DMA2_Stream4_IRQHandler ETH_IRQHandler ETH_WKUP_IRQHandler CAN2_TX_IRQHandler CAN2_RX0_IRQHandler CAN2_RX1_IRQHandler
[单片机]
如何有效地使用串口通讯接收数据
引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口中断,在中断中读取数据就行了! 中断就是打断程序正常运行,怎么能保证高效呢?经常把主程序打断,主程序还要不要运行了? 同学B:串口可以配置成用DMA的方式接收数据,等接收完毕就可以去读取了! 这个同学是对的,我们可以使用DMA去接收数据,不过DMA需要定长才能产生接收中断,如何接收不定长的数据呢? DMA简介 题外话:其实,上面的问题是很有必要思考一下的,不断思考,才能进步。 什么是DMA DMA :全称Direct Memory Access,即直接存储器访问
[单片机]
如何有效地使用串口通讯<font color='red'>接收</font>数据
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved