OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4532|回复: 1

STM32单片机解码NEC红外控制器C语言程序

[复制链接]

221

主题

221

帖子

0

精华

高级会员

Rank: 4

积分
762
金钱
762
注册时间
2021-5-18
在线时间
28 小时
发表于 2021-7-15 17:46:00 | 显示全部楼层 |阅读模式
简介:红外遥控器发射码值的协议有很多种,在百度文库里搜“史上最全的红外遥控器编码协议”,可以看到是有43种,但是我们今天是解码NEC红外协议的,几乎所有的开发板带的小遥控器都是这个协议的,我是用的定时器配合外部中断写的解码程序。
#include "ir_exti.h"
//利用外部中断和定时器进行红外解码
//在51上学习的
u8 irtime;//定时器时间累加
u8 irflag;//接收到第一个下降沿的标志
u8 irdate;//接收下降沿次数的累加
u8 irtable[33];//装每一次下降沿的时间
//u8 irdateok;
u8 irtable2[4];//解码出地址和数据 地址 地址反码 数据 数据反码
u8 irdatewokeok;//解出正确的数据就把此标志位置1
u8 repeat=0;//按住不放标志位
void TIMER2_INIT(u16 psc,u16 arr);
//战舰板子上面的红外信号端链接在PB9上面,我们把外部中断映射到PB9上即可
void IR_EXTI_INIT()
{
RCC->APB2ENR|=1<<3;//打开PB口时钟
GPIOB->CRH&=0XFFFFFF0F;//清除PB9的原有状态
GPIOB->CRH|=0X00000080;//设置PB9为输入
GPIOB->ODR|=1<<9; //设置PB9输出高电平,上拉
Ex_NVIC_Config(GPIO_B,9,1);//TRIM:触发模式,1,下降沿;2,上升沿;3,任意电平触发
MY_NVIC_Init(1,0,EXTI9_5_IRQChannel,2);
TIMER2_INIT(71,99);//产生0.1ms的中断
}
//定时器2初始化函数
//psc预分频系数,arr自动重装载寄存器
//APB1=36M 则TIM3=72M
//Tout= ((arr+1)*(psc+1))/Tclk
void TIMER2_INIT(u16 psc,u16 arr)
{
RCC->APB1ENR|=1<<0;//开启定时器2的时钟
TIM2->ARR=arr;
TIM2->PSC=psc;
TIM2->DIER|=1<<0;//允许更新中断
//默认是向上计数
TIM2->CR1|=1<<0;//使能计数器
MY_NVIC_Init(1,0,TIM2_IRQChannel,2);
}
void TIM2_IRQHandler(void)
{
static u16 i=0;
if(TIM2->SR&0X0001)
{
irtime++;
//i*10=1(ms) 110ms:i=1100
if(repeat&&(i>1500))//当时间超时了,就把按住不放次数清零
{
i++;
if(i>1500)
{
i=0;
repeat=0;
}
}
}
TIM2->SR&=~(1<<0);
}
//IR解码
void irdatewoke(void)
{
u8 k,value,i,j;
k=1;
for(j=0;j<4;j++)
{
for(i=0;i<8;i++)
{
value=value>>1;
if(irtable[k]>=17)//这个17随着定时器中断时间而改变
{
value=value|0x80;
}
k++;
}
irtable2[j]=value;
}
if(irtable2[0]==(u8)(~irtable2[1]))
{
if(irtable2[2]==(u8)(~irtable2[3]))
irdatewokeok=1;
}
//irdatewokeok=1;
}
//显示测试函数
void diswoke(void)
{
printf("%d %d %d %drn",irtable2[0],irtable2[1],irtable2[2],irtable2[3]);
}
void EXTI9_5_IRQHandler(void)
{
if(irflag)
{
if(irtime>90)//这个90随着中断时间而改变
{
if(irdate==1)
{
repeat++;
irflag=0;
printf("%drn",repeat);
}
else
{
repeat=0;
}
irdate=0;
}
irtable[irdate]=irtime;
irtime=0;
irdate++;
if(irdate==33)
{
irdate=0;
irflag=0;
irdatewoke();
if(irdatewokeok==1)
diswoke();//发送到串口小助手上
irdatewokeok=0;
}
}
else
{
irflag=1;
irtime=0;
}
EXTI->PR=1<<9; //清除 LINE0 上的中断标志位
}
//我得到的键值,左到右、上到下
原文链接:https://www.yunduoketang.com/article/liywangluoxx.html

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2016-11-16
在线时间
30 小时
发表于 2021-8-11 10:45:59 | 显示全部楼层
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-26 03:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表