STM32红外遥控的控制代码
时间: 2024-06-17 17:05:14 浏览: 151
基于stm32红外控制代码
STM32红外遥控的控制代码一般分为两部分:红外解码和遥控控制。下面是一个简单的例子,可以帮助您快速入门:
红外解码部分:
```c
#include "stm32f10x.h"
#include "ir_decode.h"
uint16_t ir_time_buf[50]; //存储每个脉冲的时间
uint8_t ir_time_buf_len; //存储脉冲数量
//红外解码中断处理函数
void EXTI0_IRQHandler(void)
{
static uint8_t idx = 0; //当前处理的脉冲序号
static uint8_t ir_status = 0; //红外解码状态
static uint16_t last_time = 0; //上一次脉冲的时间
uint16_t this_time; //本次脉冲的时间
if (EXTI_GetITStatus(EXTI_Line0) != RESET) //检查是否有中断发生
{
this_time = TIM_GetCounter(TIM2); //获取当前计数器的值
TIM_SetCounter(TIM2, 0); //清零计数器
EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位
if (ir_status == 0) //如果当前状态为未开始
{
if (this_time > 8000 && this_time < 10000) //接收到起始位
{
ir_status = 1; //状态转为已接收到起始位
idx = 0; //脉冲序号清零
}
}
else if (ir_status == 1) //如果当前状态为已接收到起始位
{
if (this_time > 3500 && this_time < 4500) //接收到逻辑位“0”的脉冲
{
ir_time_buf[idx++] = this_time - last_time; //计算脉冲时间并存储
last_time = this_time; //更新上一次脉冲的时间
}
else if (this_time > 7000 && this_time < 8000) //接收到逻辑位“1”的脉冲
{
ir_time_buf[idx++] = this_time - last_time; //计算脉冲时间并存储
last_time = this_time; //更新上一次脉冲的时间
}
else if (this_time > 13000 && this_time < 14000) //接收到重复码
{
ir_status = 2; //状态转为已接收到重复码
ir_time_buf_len = idx; //记录脉冲数量
idx = 0; //脉冲序号清零
}
else //接收到错误码,重置状态
{
ir_status = 0;
idx = 0;
}
}
else if (ir_status == 2) //如果当前状态为已接收到重复码
{
if (this_time > 3500 && this_time < 4500) //接收到逻辑位“0”的脉冲
{
if (idx >= ir_time_buf_len) //如果已经发送完所有的脉冲,则重新发送起始位
{
idx = 0;
ir_status = 1;
return;
}
TIM_SetCompare1(TIM3, TIM_GetCapture1(TIM3) + ir_time_buf[idx++]); //设置PWM输出时间长度
}
else if (this_time > 7000 && this_time < 8000) //接收到逻辑位“1”的脉冲
{
if (idx >= ir_time_buf_len) //如果已经发送完所有的脉冲,则重新发送起始位
{
idx = 0;
ir_status = 1;
return;
}
TIM_SetCompare1(TIM3, TIM_GetCapture1(TIM3) + ir_time_buf[idx++]); //设置PWM输出时间长度
}
else //接收到错误码,重置状态
{
ir_status = 0;
idx = 0;
}
}
}
}
```
遥控控制部分:
```c
#include "stm32f10x.h"
#include "ir_decode.h"
//初始化红外解码模块
void IR_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //使能GPIOA时钟和复用功能时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE); //使能TIM2和TIM3时钟
/* 配置GPIOA.0为中断输入 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 配置TIM2 */
TIM_TimeBaseStructure.TIM_Period = 65535; //计数器最大值
TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 1000000) - 1; //预分频系数,时钟频率为1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频因子,不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_Cmd(TIM2, ENABLE); //使能TIM2
/* 配置TIM3 */
TIM_TimeBaseStructure.TIM_Period = 840 - 1; //计数器最大值,时钟频率为84MHz,PWM周期为20ms(50Hz)
TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 840000) - 1; //预分频系数,时钟频率为100kHz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频因子,不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* 配置TIM3通道1为PWM输出 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM模式1,逆变器输出高电平占空比为70%
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能PWM输出
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //设置输出极性为高电平有效
TIM_OCInitStructure.TIM_Pulse = (840 * 7) / 10 - 1; //设置PWM输出初始值,时钟频率为84MHz,逆变器输出高电平占空比为70%
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能PWM输出预装载
/* 配置中断 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
```
请注意,这只是一个简单的例子。实际应用中,您需要根据具体遥控器的编码格式进行修改和扩展。同时,您还需要根据具体硬件平台进行调整。
阅读全文