STM32Cube红外遥控:输入捕获
红外遥控原理:https://blog.csdn.net/yangyang_1024/article/details/82999694
芯片:stm32f030F4PX
捕获通道:TIM3_CH1
- 使用内部时钟,时,stm32f030F4PX最高时钟频率为48MHz,本次配置时钟频率为48MHz,钟配置如下:
- 配置输入捕获通道,由于选择内部时钟不需要勾选外部时钟Internal Clock,选择通道1Channel1,模式为Inp Captur direct mode。
- 定时器参数配置,48分频,向上计数,预分频65535即0xFFFF,这是16位计数所以最大值为65535。没一个计数单位为1us,使能更新中断。
- 生成代码
- 源代码参考正点原子,代码如下
-1. 开启输入捕获
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);
2.输入捕获处理
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM3)
{
if (RmtSta & 0x80) //上次有数据被接收到了
{
RmtSta &= ~0X10; //取消上升沿已经被捕获标记
if ((RmtSta & 0X0F) == 0X00)
RmtSta |= 1 << 6; //标记已经完成一次按键的键值信息采集
if ((RmtSta & 0X0F) < 14)
RmtSta++;
else
{
RmtSta &= ~(1 << 7); //清空引导标识
RmtSta &= 0XF0; //清空计数器
}
}
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (TIM3 == htim->Instance)
{
if (HAL_TIM_ACTIVE_CHANNEL_1 == htim->Channel)
{
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6))//判断捕获引脚电平
{
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);//下降沿捕获
__HAL_TIM_SET_COUNTER(&htim3, TIM_CHANNEL_1); //设置计数寄存器的值变为0
RmtSta |= 0x10;
}
else
{
Dval = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1);//获取下降沿到上升沿的时间
g_recvIRTime = __HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);//上升沿捕获
if (RmtSta & 0x10)
{
if (RmtSta & 0x80)
{
uint8_t Index = g_recvIndex / 8;
if ((Dval > 300) && (Dval < 800))// 位1
{
if (g_recvIndex != 0)
g_recvBuf[Index] <<= 1;
g_recvBuf[Index] &= 0xfe;
g_recvIndex++;
// g_recvIndex_0 ++;
}
else if ((Dval > 1400) && (Dval < 1800))// 位0
{
g_recvIndex++;
g_recvBuf[Index] <<= 1;
g_recvBuf[Index] |= 1;
}
else if ((Dval > 2000) && (Dval < 2500))
{
RmtCnt++; // 重复码
RmtSta &= 0xf0;
}
}
else if ((Dval > 4200) && (Dval < 4700))
{
RmtSta |= 1 << 7; //表示接收到同步头
RmtCnt = 0; //清零按键次数
RmtRec = 0;
g_recvIndex = 0;
}
}
RmtSta &= ~(1 << 4);
}
}
}
}
void Remote_Scan(void)
{
uint8_t flag, state = 0;
flag = ~g_recvBuf[1];
static int staLCDstate = 0;
staLCDstate = ~staLCDstate;
if (g_recvIndex == 32)//接收完成
{
if (g_recvBuf[0] == flag)//用户吗判断
{
flag = ~g_recvBuf[3];
if (g_recvBuf[2] == flag)//按键码判断
{
switch (g_recvBuf[2])
{
case KEY_POWER:
if (RmtCnt < 12)//长按
{
LCD_ON;
}
else
{
LCD_OFF;
}
break;
default:
break;
}
}
}
}
}
STM32Cube工程和代码连接:https://download.csdn.net/download/jjjjjj0000/15659644?spm=1001.2014.3001.5501