STM32F407ZET6的红外遥控实验中遇到自动获取红外信号的问题
时间:10-02
整理:3721RD
点击:
STM32F407ZET6的红外遥控实验中,我的红外遥控器还没有按下,LCD已经开始显示按键值了,而且按键值还会快速变化,我都不知道红外接收头从哪里接收到的信号,遥控器遥控不了,就是按下遥控器后,LCD上的按键值还是飞快的变化,编译没有问题,下面是我写的程序,求大神指点。
/***********************main.c*******************************/
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "remote.h"
#include "lcd.h"
int main(void)
{
u8 t,temp,*str=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
LED_Init();
LCD_Init();
remote_init(10000,167);//10ms溢出
POINT_COLOR=RED;
LCD_ShowString(30,110,200,16,16,"2016-7-29");
LCD_ShowString(30,130,200,16,16,"KEYVAL:");
LCD_ShowString(30,150,200,16,16,"KEYCNT:");
LCD_ShowString(30,170,200,16,16,"SYMBOL:");
while(1)
{
temp=remote_scan();
if(temp)
{
LCD_ShowNum(86,130,temp,3,16);
LCD_ShowNum(86,150,reccnt,3,16);
switch(temp)
{
case 0: str="ERROR"; break;
case 162: str="POWER"; break;
case 98: str="UP"; break;
case 2: str="PLAY"; break;
case 226: str="ALIENTEK"; break;
case 194: str="RIGHT"; break;
case 34: str="LEFT"; break;
case 224: str="VOL-"; break;
case 168: str="DOWN"; break;
case 144: str="VOL+"; break;
case 104: str="1"; break;
case 152: str="2"; break;
case 176: str="3"; break;
case 48: str="4"; break;
case 24: str="5"; break;
case 122: str="6"; break;
case 16: str="7"; break;
case 56: str="8"; break;
case 90: str="9"; break;
case 66: str="0"; break;
case 82: str="DELETE"; break;
}
LCD_Fill(86,170,116+8*8,170+16,WHITE);
LCD_ShowString(86,170,200,16,16,str);
}
delay_ms(10);
t++;
if(t==100)
{
t=0;
LED0=!LED0;
}
}
}
/*****************************remote.h************************/
#ifndef __remote_H
#define __remote_H
#include "sys.h"
#define REMOTR_ID 0
#define shangshengyan PAin(8)
extern u8 reccnt;
void remote_init(u16 arr,u16 psc);
u8 remote_scan(void);
#endif
/******************************remote.c*****************************/
#include"remote.h"
#include"sys.h"
#include"led.h"
void remote_init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBseInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitSructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
//配置I/O
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_TIM1);
//配置TIM1
TIM_TimeBseInitStructure.TIM_ClockDivision=TIM_CKD_div1;
TIM_TimeBseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBseInitStructure.TIM_Period=arr;
TIM_TimeBseInitStructure.TIM_Prescaler=psc;
TIM_TimeBaseInit(TIM1,&TIM_TimeBseInitStructure);
//配置捕获通道1
TIM_ICInitStructure.TIM_Channel=TIM_Channel_1 ;
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;
TIM_ICInit(TIM1,&TIM_ICInitStructure);
NVIC_InitSructure.NVIC_IRQChannel=TIM1_UP_TIM10_IRQn;
NVIC_InitSructure. NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitSructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitSructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitSructure);
NVIC_InitSructure.NVIC_IRQChannel=TIM1_CC_IRQn;
NVIC_InitSructure. NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitSructure.NVIC_IRQChannelSubPriority=3;
NVIC_InitSructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitSructure);
//TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE ?÷ê?3?ê1?ü
//TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1?¤×°??ê1?ü
//TIM_ARRPreloadConfig(TIM1, ENABLE); //ê1?üTIMx?úARRé?μ??¤×°????′??÷
TIM_ITConfig(TIM1,TIM_IT_Update|TIM_IT_CC1,ENABLE);
TIM_Cmd(TIM1,ENABLE);
}
u8 sta=0;
//[7]:1,标记已经接收到同步码;0,标记还没接收到同步码
//[6]:1, 标记已经完成一次红外信号采集;0,标记还没完成一次红外信号采集
//[5]:1, 标记已经捕获到上升沿;0,标记还没捕获到上升沿
//[4-0]: 定时器TIM1的溢出次数
u8 reccnt=0;//按键连按的次数
u32 recval=0;//红外接收到的值
u16 capture=0;//下降沿时定时器的值
void TIM1_CC_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_CC1)==SET)
{
if(shangshengyan)//如果捕获到上升沿
{
sta|=0x20; //sta|=1<<5; 标记已经捕获到上升沿
TIM_SetCounter(TIM1,0);
TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Falling);
}
else
{
TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Rising);
capture=TIM_GetCapture1(TIM1);
if(sta&0x20)//如果之前已经捕获到上升沿
{
if(sta&0x80)//判断是否已经接收到同步码
{
if(capture>360&&capture<760)//560为标准值,560us
{
recval<<=1;
recval|=0;
}
if(capture>1480&&capture<1880)//1680为标准值,1680us
{
recval<<=1;
recval|=1;
}
if(capture>2200&&capture<2700)//得到按键键值增加的信息,2500为标准值,2.5ms
{
reccnt++;
}
}
else
if(capture>4200&&capture<4700)
{
sta|=0x80;//标记已经接收到同步码
reccnt=0;清空按键连按的次数
sta&=0xb0;
}
}
sta&=~0x20;
}
}
TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);
}
void TIM1_UP_TIM10_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET)
{
if(sta&0x80)
{
sta&=~1<<5;//取消上升沿已经被捕获标记
if(sta&0x1f==0) sta|=0x40; //如果第一次溢出,则标记已经完成一次红外信号的采集
if((sta&0x1f)<11) sta++;
else //如果定时器溢出次数过多,即长时间没有按键按下
{
sta&=0x7f;//清空同步码标记
sta&=0xe0;//清空溢出次数
}
}
}
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
}
u8 remote_scan(void)
{
u8 key;
u8 t1,t2;
if(sta&0x40)//判断是否已经完成一次红外信号采集
{
t1=recval>>24;
t2=(recval>>16)&0xff;
if(t1==(u8)~t2&&t1==REMOTR_ID)//如果地址码匹配的话
{
t1=recval>>8;
t2=recval;
if(t1==(u8)~t2) key=t1;
}
if(key==0||(sta&0x80)==0)//如果按键数据错误或者遥控已经没有按下了
{
sta&=~0x40;
}
}
return key;
}
/***********************main.c*******************************/
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "remote.h"
#include "lcd.h"
int main(void)
{
u8 t,temp,*str=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
LED_Init();
LCD_Init();
remote_init(10000,167);//10ms溢出
POINT_COLOR=RED;
LCD_ShowString(30,110,200,16,16,"2016-7-29");
LCD_ShowString(30,130,200,16,16,"KEYVAL:");
LCD_ShowString(30,150,200,16,16,"KEYCNT:");
LCD_ShowString(30,170,200,16,16,"SYMBOL:");
while(1)
{
temp=remote_scan();
if(temp)
{
LCD_ShowNum(86,130,temp,3,16);
LCD_ShowNum(86,150,reccnt,3,16);
switch(temp)
{
case 0: str="ERROR"; break;
case 162: str="POWER"; break;
case 98: str="UP"; break;
case 2: str="PLAY"; break;
case 226: str="ALIENTEK"; break;
case 194: str="RIGHT"; break;
case 34: str="LEFT"; break;
case 224: str="VOL-"; break;
case 168: str="DOWN"; break;
case 144: str="VOL+"; break;
case 104: str="1"; break;
case 152: str="2"; break;
case 176: str="3"; break;
case 48: str="4"; break;
case 24: str="5"; break;
case 122: str="6"; break;
case 16: str="7"; break;
case 56: str="8"; break;
case 90: str="9"; break;
case 66: str="0"; break;
case 82: str="DELETE"; break;
}
LCD_Fill(86,170,116+8*8,170+16,WHITE);
LCD_ShowString(86,170,200,16,16,str);
}
delay_ms(10);
t++;
if(t==100)
{
t=0;
LED0=!LED0;
}
}
}
/*****************************remote.h************************/
#ifndef __remote_H
#define __remote_H
#include "sys.h"
#define REMOTR_ID 0
#define shangshengyan PAin(8)
extern u8 reccnt;
void remote_init(u16 arr,u16 psc);
u8 remote_scan(void);
#endif
/******************************remote.c*****************************/
#include"remote.h"
#include"sys.h"
#include"led.h"
void remote_init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBseInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitSructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
//配置I/O
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_TIM1);
//配置TIM1
TIM_TimeBseInitStructure.TIM_ClockDivision=TIM_CKD_div1;
TIM_TimeBseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBseInitStructure.TIM_Period=arr;
TIM_TimeBseInitStructure.TIM_Prescaler=psc;
TIM_TimeBaseInit(TIM1,&TIM_TimeBseInitStructure);
//配置捕获通道1
TIM_ICInitStructure.TIM_Channel=TIM_Channel_1 ;
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;
TIM_ICInit(TIM1,&TIM_ICInitStructure);
NVIC_InitSructure.NVIC_IRQChannel=TIM1_UP_TIM10_IRQn;
NVIC_InitSructure. NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitSructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitSructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitSructure);
NVIC_InitSructure.NVIC_IRQChannel=TIM1_CC_IRQn;
NVIC_InitSructure. NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitSructure.NVIC_IRQChannelSubPriority=3;
NVIC_InitSructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitSructure);
//TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE ?÷ê?3?ê1?ü
//TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1?¤×°??ê1?ü
//TIM_ARRPreloadConfig(TIM1, ENABLE); //ê1?üTIMx?úARRé?μ??¤×°????′??÷
TIM_ITConfig(TIM1,TIM_IT_Update|TIM_IT_CC1,ENABLE);
TIM_Cmd(TIM1,ENABLE);
}
u8 sta=0;
//[7]:1,标记已经接收到同步码;0,标记还没接收到同步码
//[6]:1, 标记已经完成一次红外信号采集;0,标记还没完成一次红外信号采集
//[5]:1, 标记已经捕获到上升沿;0,标记还没捕获到上升沿
//[4-0]: 定时器TIM1的溢出次数
u8 reccnt=0;//按键连按的次数
u32 recval=0;//红外接收到的值
u16 capture=0;//下降沿时定时器的值
void TIM1_CC_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_CC1)==SET)
{
if(shangshengyan)//如果捕获到上升沿
{
sta|=0x20; //sta|=1<<5; 标记已经捕获到上升沿
TIM_SetCounter(TIM1,0);
TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Falling);
}
else
{
TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Rising);
capture=TIM_GetCapture1(TIM1);
if(sta&0x20)//如果之前已经捕获到上升沿
{
if(sta&0x80)//判断是否已经接收到同步码
{
if(capture>360&&capture<760)//560为标准值,560us
{
recval<<=1;
recval|=0;
}
if(capture>1480&&capture<1880)//1680为标准值,1680us
{
recval<<=1;
recval|=1;
}
if(capture>2200&&capture<2700)//得到按键键值增加的信息,2500为标准值,2.5ms
{
reccnt++;
}
}
else
if(capture>4200&&capture<4700)
{
sta|=0x80;//标记已经接收到同步码
reccnt=0;清空按键连按的次数
sta&=0xb0;
}
}
sta&=~0x20;
}
}
TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);
}
void TIM1_UP_TIM10_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET)
{
if(sta&0x80)
{
sta&=~1<<5;//取消上升沿已经被捕获标记
if(sta&0x1f==0) sta|=0x40; //如果第一次溢出,则标记已经完成一次红外信号的采集
if((sta&0x1f)<11) sta++;
else //如果定时器溢出次数过多,即长时间没有按键按下
{
sta&=0x7f;//清空同步码标记
sta&=0xe0;//清空溢出次数
}
}
}
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
}
u8 remote_scan(void)
{
u8 key;
u8 t1,t2;
if(sta&0x40)//判断是否已经完成一次红外信号采集
{
t1=recval>>24;
t2=(recval>>16)&0xff;
if(t1==(u8)~t2&&t1==REMOTR_ID)//如果地址码匹配的话
{
t1=recval>>8;
t2=recval;
if(t1==(u8)~t2) key=t1;
}
if(key==0||(sta&0x80)==0)//如果按键数据错误或者遥控已经没有按下了
{
sta&=~0x40;
}
}
return key;
}
学习一下,一起进步!