这里没有解析红外的函数,毕竟考虑到学习的红外有几种协议(如:NEC)。同时代码存在一些问题(有部分遥控是学习不了的(如:空调、DVD))。
红外数据接收:定时器捕获红外信号(还有一个是通过外部中断的,这里不列出)
红外数据发射:使用PWM输出
下面直接上代码
remote.c
/*remote.c*/
#include “remote.h”
#include “delay.h”
#include “usart.h”
/**
发射:PA7-TIM3-CH2
接收:PC8-TIM8-CH3
TIM8:
下面代码中捕获中断和定时中断分开,不在同一中断函数,所以需要配置两次中断优先级(应该可以合在一起配置)
*/
/**
* @name void Remote_Init(void)
* @description 红外遥控初始化 设置IO以及定时器8的输入捕获
* Infrared remote initializer sets IO and timer 8 input capture
* @notice
*/
void Remote_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE); //使能PORTB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM8 时钟使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PC8 输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_8); //初始化GPIOC.8
TIM_TimeBaseStructure.TIM_Period = 9999; //设定计数器自动重装值 最大10ms溢出
TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //预分频器,1M的计数频率,1us加1.
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; // 选择输入端 IC4映射到TI4上
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM_ICInitStructure.TIM_ICFilter = 0x03; //IC4F=0011 配置输入滤波器 8个定时器时钟周期滤波
TIM_ICInit(TIM8, &TIM_ICInitStructure); //初始化定时器输入捕获通道
TIM_Cmd(TIM8,ENABLE ); //使能定时器4
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn; //TIM8TIM8捕获比较中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ITConfig( TIM8,TIM_IT_CC3,ENABLE); //允许更新中断 ,允许CC4IE捕获中断
NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ITConfig( TIM8,TIM_IT_Update,ENABLE); //允许更新中断 ,允许CC4IE捕获中断
}
/**
* @name void TIM3_PWM_Init(u16 arr,u16 psc)
* @description 初始化定时器3的设置,将定时器3用于PWM调制,PWM输出口为 PA.7
* @param arr -- u16,定时器重装值
psc -- u16,定时器分频值
* @return
* @notice PWM频率 = 72M/((arr+1)*(psc+1)),这里用作红外发射的载波,需要生成38kHz的方波,故取arr = 1895,psc = 0。
*/
void TIM3_PWM_Init(u16 arr,u16 psc)
{
/* 初始化结构体定义 */
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定时器基本设置
TIM_OCInitTypeDef TIM_OCInitStructure; //定时器比较输出配置
/* 使能相应端口的时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设时钟
/* GPIOA.7初始化 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; // TIM3 CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // PA.7 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_7);
/* TIM3 初始化*/
TIM_TimeBaseInitStructure.TIM_Period = arr; //下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseInitStructure.TIM_Prescaler = psc; //作为TIMx时钟频率除数的预分频值
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0; //时钟分割:TDTS = Tck_tim
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
/* 定时器TIM3 Ch2 PWM模式初始化 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM PWM1 TIM_OCMode_PWM1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = (arr+1)/3; //占空比1:3 (arr+1)/10 3
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OCPolarity_High
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
/* 使能TIM3在CCR1上的预装载寄存器 */
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
}
u8 RmtSta=0; //红外学习上升或下降标志位
u16 Dval; //上升沿、下降沿的计数器的值
u8 RmtCnt=0; //定时器红外学习计数超时标志位
u8 PulseTabCnt=0; //上升沿下降沿计数器的值
u16 PulseTab[MAX_PULSE_LEN]={0}; //红外学习存储数据
u8 Flag_LearnState = 0; //红外学习标志位
/**
*@name void TIM8_UP_IRQHandler(void)
*@brief TIM8的定时计数中断函数
* The timing count interrupt function of TIM8
*@note
*/
void TIM8_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM8,TIM_IT_Update)!=RESET)
{
if(RmtCnt++》50)
{
RmtCnt = 0;
if(RmtSta)
{
RmtSta = 0;
Flag_LearnState = 1;
}
}
}
TIM_ClearITPendingBit(TIM8,TIM_IT_Update);
}
/**
*@name void TIM8_CC_IRQHandler(void)
*@brief 捕获红外载波的高低电平宽度,记录到数组PulseTab
* Capture the high and low level width of the infrared carrier and record it to the array PulseTab
*@note
*/
void TIM8_CC_IRQHandler(void)
{
if(TIM_GetITStatus(TIM8,TIM_IT_CC3)!=RESET) //获取上升沿或下降沿状态
{
if(RDATA) //上升沿捕获
{
Dval=TIM_GetCapture3(TIM8); //读取CCR4也可以清CC4IF标志位
TIM_OC3PolarityConfig(TIM8,TIM_ICPolarity_Falling); //CC4P=1 设置为下降沿捕获
TIM_SetCounter(TIM8,0); //清空定时器值
if(RmtSta&0X01)
{
PulseTab[PulseTabCnt++] = Dval;
RmtSta = 0x10;
}
else
{
RmtSta = 0X10; //标记上升沿已经被捕获
}
}
else //下降沿捕获
{
Dval=TIM_GetCapture3(TIM8); //读取CCR4也可以清CC4IF标志位
TIM_OC3PolarityConfig(TIM8,TIM_ICPolarity_Rising); //CC4P=0 设置为上升沿捕获
TIM_SetCounter(TIM8,0); //清空定时器值
if(RmtSta&0X10) //完成一次高电平捕获
{
PulseTab[PulseTabCnt++] = Dval;
RmtSta = 0x01;
}
else
{
RmtSta = 0x01;
}
}
}
TIM_ClearITPendingBit(TIM8,TIM_IT_CC3);
}
/**
*@name void Infrared_Send_IR1(u16 *irdata,u32 irlen)
*@description 红外信号发射函数
*@param irdata -- u16,红外数据
irlen -- u32,红外数据长度
*@return
*@notice
*/
void Infrared_Send(u16 *irdata,u32 irlen)
{
u32 i; //用于下面的for循环
for(i=0; i《irlen && irdata[i]!=0xffff; i++) //循环,从i=0开始,当i《irlen 并且 irdata[i] != 0xffff 时成立,当其中一个不成立,退出循环
{
if(i%2 == 0) //偶数的下标的数组成员延时拉高电平
{
TIM_Cmd(TIM3,ENABLE);
delay_us(irdata[i]);
TIM_Cmd(TIM3,DISABLE);
GPIO_SetBits(GPIOA,GPIO_Pin_7);
}
else
{
GPIO_SetBits(GPIOA,GPIO_Pin_7);
delay_us(irdata[i]);
}
}
delay_us(555);
GPIO_ResetBits(GPIOA,GPIO_Pin_7);
return ;
}
remote.h
/*remote.h*/
#ifndef __RED_H
#define __RED_H
#include “sys.h”
#define RDATA PCin(8) //红外数据输入脚
//红外遥控识别码(ID),每款遥控器的该值基本都不一样,但也有一样的。
//我们选用的遥控器识别码为0
#define REMOTE_ID 0
#define MAX_PULSE_LEN 400 //500 300
extern u8 RmtCnt; //按键按下的次数
extern u16 PulseTab[MAX_PULSE_LEN];
extern u8 Flag_LearnState ;
extern u8 PulseTabCnt;//上升沿下降沿计数器的值
void Remote_Init(void); //红外传感器接收头引脚初始化
void TIM3_PWM_Init(u16 arr,u16 psc);
void Infrared_Send(u16 *irdata,u32 irlen);
#endif
main.c
/*main.c*/
#include “delay.h”
#include “sys.h”
#include “usart.h”
#include “remote.h”
#include “string.h”
/**
*@name int main(void)
*@brief
*@retval return 0
*@note
*/
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
Remote_Init(); //红外接收初始化
TIM3_PWM_Init(1895,0); //tim3 pwm initialize
printf(“init okrn”);
while(1)
{
if(Flag_LearnState)
{
printf(“%srn”,(char *)PulseTab);
Infrared_Send(PulseTab,PulseTabCnt);
PulseTabCnt = 0;
Flag_LearnState=0;
memset((void *)PulseTab,0,MAX_PULSE_LEN);
}
}
}
最后
实验现象:
本实验开机之后,即进入等待红外触发,如过接收到正确的红外信号,则500ms后自动从红外发射棒发射红外,同时通过串口1,将接受的红外信号以16进制打印出来。
注意事项:
1,可以用最小开发板调试,红外接收头和发射棒可以外接。
2,当使用的接收或发射引脚不一样是,注意将定时器修改。
3,本实验为万能学习红外遥控器,属于半成品,未做存储处理,需要储存需使用芯片的flash或外接eeprom。
这里没有解析红外的函数,毕竟考虑到学习的红外有几种协议(如:NEC)。同时代码存在一些问题(有部分遥控是学习不了的(如:空调、DVD))。
红外数据接收:定时器捕获红外信号(还有一个是通过外部中断的,这里不列出)
红外数据发射:使用PWM输出
下面直接上代码
remote.c
/*remote.c*/
#include “remote.h”
#include “delay.h”
#include “usart.h”
/**
发射:PA7-TIM3-CH2
接收:PC8-TIM8-CH3
TIM8:
下面代码中捕获中断和定时中断分开,不在同一中断函数,所以需要配置两次中断优先级(应该可以合在一起配置)
*/
/**
* @name void Remote_Init(void)
* @description 红外遥控初始化 设置IO以及定时器8的输入捕获
* Infrared remote initializer sets IO and timer 8 input capture
* @notice
*/
void Remote_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE); //使能PORTB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM8 时钟使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PC8 输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_8); //初始化GPIOC.8
TIM_TimeBaseStructure.TIM_Period = 9999; //设定计数器自动重装值 最大10ms溢出
TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //预分频器,1M的计数频率,1us加1.
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; // 选择输入端 IC4映射到TI4上
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM_ICInitStructure.TIM_ICFilter = 0x03; //IC4F=0011 配置输入滤波器 8个定时器时钟周期滤波
TIM_ICInit(TIM8, &TIM_ICInitStructure); //初始化定时器输入捕获通道
TIM_Cmd(TIM8,ENABLE ); //使能定时器4
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn; //TIM8TIM8捕获比较中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ITConfig( TIM8,TIM_IT_CC3,ENABLE); //允许更新中断 ,允许CC4IE捕获中断
NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ITConfig( TIM8,TIM_IT_Update,ENABLE); //允许更新中断 ,允许CC4IE捕获中断
}
/**
* @name void TIM3_PWM_Init(u16 arr,u16 psc)
* @description 初始化定时器3的设置,将定时器3用于PWM调制,PWM输出口为 PA.7
* @param arr -- u16,定时器重装值
psc -- u16,定时器分频值
* @return
* @notice PWM频率 = 72M/((arr+1)*(psc+1)),这里用作红外发射的载波,需要生成38kHz的方波,故取arr = 1895,psc = 0。
*/
void TIM3_PWM_Init(u16 arr,u16 psc)
{
/* 初始化结构体定义 */
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定时器基本设置
TIM_OCInitTypeDef TIM_OCInitStructure; //定时器比较输出配置
/* 使能相应端口的时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设时钟
/* GPIOA.7初始化 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; // TIM3 CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // PA.7 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_7);
/* TIM3 初始化*/
TIM_TimeBaseInitStructure.TIM_Period = arr; //下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseInitStructure.TIM_Prescaler = psc; //作为TIMx时钟频率除数的预分频值
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0; //时钟分割:TDTS = Tck_tim
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
/* 定时器TIM3 Ch2 PWM模式初始化 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM PWM1 TIM_OCMode_PWM1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = (arr+1)/3; //占空比1:3 (arr+1)/10 3
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OCPolarity_High
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
/* 使能TIM3在CCR1上的预装载寄存器 */
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
}
u8 RmtSta=0; //红外学习上升或下降标志位
u16 Dval; //上升沿、下降沿的计数器的值
u8 RmtCnt=0; //定时器红外学习计数超时标志位
u8 PulseTabCnt=0; //上升沿下降沿计数器的值
u16 PulseTab[MAX_PULSE_LEN]={0}; //红外学习存储数据
u8 Flag_LearnState = 0; //红外学习标志位
/**
*@name void TIM8_UP_IRQHandler(void)
*@brief TIM8的定时计数中断函数
* The timing count interrupt function of TIM8
*@note
*/
void TIM8_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM8,TIM_IT_Update)!=RESET)
{
if(RmtCnt++》50)
{
RmtCnt = 0;
if(RmtSta)
{
RmtSta = 0;
Flag_LearnState = 1;
}
}
}
TIM_ClearITPendingBit(TIM8,TIM_IT_Update);
}
/**
*@name void TIM8_CC_IRQHandler(void)
*@brief 捕获红外载波的高低电平宽度,记录到数组PulseTab
* Capture the high and low level width of the infrared carrier and record it to the array PulseTab
*@note
*/
void TIM8_CC_IRQHandler(void)
{
if(TIM_GetITStatus(TIM8,TIM_IT_CC3)!=RESET) //获取上升沿或下降沿状态
{
if(RDATA) //上升沿捕获
{
Dval=TIM_GetCapture3(TIM8); //读取CCR4也可以清CC4IF标志位
TIM_OC3PolarityConfig(TIM8,TIM_ICPolarity_Falling); //CC4P=1 设置为下降沿捕获
TIM_SetCounter(TIM8,0); //清空定时器值
if(RmtSta&0X01)
{
PulseTab[PulseTabCnt++] = Dval;
RmtSta = 0x10;
}
else
{
RmtSta = 0X10; //标记上升沿已经被捕获
}
}
else //下降沿捕获
{
Dval=TIM_GetCapture3(TIM8); //读取CCR4也可以清CC4IF标志位
TIM_OC3PolarityConfig(TIM8,TIM_ICPolarity_Rising); //CC4P=0 设置为上升沿捕获
TIM_SetCounter(TIM8,0); //清空定时器值
if(RmtSta&0X10) //完成一次高电平捕获
{
PulseTab[PulseTabCnt++] = Dval;
RmtSta = 0x01;
}
else
{
RmtSta = 0x01;
}
}
}
TIM_ClearITPendingBit(TIM8,TIM_IT_CC3);
}
/**
*@name void Infrared_Send_IR1(u16 *irdata,u32 irlen)
*@description 红外信号发射函数
*@param irdata -- u16,红外数据
irlen -- u32,红外数据长度
*@return
*@notice
*/
void Infrared_Send(u16 *irdata,u32 irlen)
{
u32 i; //用于下面的for循环
for(i=0; i《irlen && irdata[i]!=0xffff; i++) //循环,从i=0开始,当i《irlen 并且 irdata[i] != 0xffff 时成立,当其中一个不成立,退出循环
{
if(i%2 == 0) //偶数的下标的数组成员延时拉高电平
{
TIM_Cmd(TIM3,ENABLE);
delay_us(irdata[i]);
TIM_Cmd(TIM3,DISABLE);
GPIO_SetBits(GPIOA,GPIO_Pin_7);
}
else
{
GPIO_SetBits(GPIOA,GPIO_Pin_7);
delay_us(irdata[i]);
}
}
delay_us(555);
GPIO_ResetBits(GPIOA,GPIO_Pin_7);
return ;
}
remote.h
/*remote.h*/
#ifndef __RED_H
#define __RED_H
#include “sys.h”
#define RDATA PCin(8) //红外数据输入脚
//红外遥控识别码(ID),每款遥控器的该值基本都不一样,但也有一样的。
//我们选用的遥控器识别码为0
#define REMOTE_ID 0
#define MAX_PULSE_LEN 400 //500 300
extern u8 RmtCnt; //按键按下的次数
extern u16 PulseTab[MAX_PULSE_LEN];
extern u8 Flag_LearnState ;
extern u8 PulseTabCnt;//上升沿下降沿计数器的值
void Remote_Init(void); //红外传感器接收头引脚初始化
void TIM3_PWM_Init(u16 arr,u16 psc);
void Infrared_Send(u16 *irdata,u32 irlen);
#endif
main.c
/*main.c*/
#include “delay.h”
#include “sys.h”
#include “usart.h”
#include “remote.h”
#include “string.h”
/**
*@name int main(void)
*@brief
*@retval return 0
*@note
*/
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
Remote_Init(); //红外接收初始化
TIM3_PWM_Init(1895,0); //tim3 pwm initialize
printf(“init okrn”);
while(1)
{
if(Flag_LearnState)
{
printf(“%srn”,(char *)PulseTab);
Infrared_Send(PulseTab,PulseTabCnt);
PulseTabCnt = 0;
Flag_LearnState=0;
memset((void *)PulseTab,0,MAX_PULSE_LEN);
}
}
}
最后
实验现象:
本实验开机之后,即进入等待红外触发,如过接收到正确的红外信号,则500ms后自动从红外发射棒发射红外,同时通过串口1,将接受的红外信号以16进制打印出来。
注意事项:
1,可以用最小开发板调试,红外接收头和发射棒可以外接。
2,当使用的接收或发射引脚不一样是,注意将定时器修改。
3,本实验为万能学习红外遥控器,属于半成品,未做存储处理,需要储存需使用芯片的flash或外接eeprom。
举报