STM32使用C语言解码NEC32协议的38KHz红外信号,不需要处理重复码;
时间: 2024-02-15 10:01:55 浏览: 131
以下是一个基于STM32的C语言程序,用于解码NEC32协议的38KHz红外信号,不处理重复码:
```c
#include "stm32f10x.h"
#define IR_PIN GPIO_Pin_0 //红外接收器连接的引脚
#define IR_PORT GPIOA //红外接收器连接的端口
#define IR_THRESHOLD 200 //红外信号的阈值
#define NEC_REPEAT_CODE 0xFFFFFFFF //重复码的值
uint32_t irCode = 0; //存储接收到的红外码
uint32_t lastIrCode = 0; //存储上一次接收到的红外码
void delay_us(uint32_t us) {
uint32_t startTick = SysTick->VAL;
uint32_t ticks = us * (SystemCoreClock / 1000000);
while (ticks > 0) {
uint32_t currentTick = SysTick->VAL;
if (currentTick < startTick) {
ticks -= (startTick - currentTick);
} else {
ticks -= (startTick + SysTick->LOAD - currentTick);
}
startTick = currentTick;
}
}
void EXTI0_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line0) != RESET) { //检测到红外信号的上升沿
EXTI_ClearITPendingBit(EXTI_Line0);
irCode = 0;
for (int i = 0; i < 32; i++) { //接收32位红外码
while (GPIO_ReadInputDataBit(IR_PORT, IR_PIN) == RESET); //等待信号变成高电平
uint32_t highTime = SysTick->VAL;
while (GPIO_ReadInputDataBit(IR_PORT, IR_PIN) != RESET); //等待信号变成低电平
uint32_t lowTime = SysTick->VAL;
if (highTime - lowTime > IR_THRESHOLD) { //检测到信号的高电平
irCode |= (1UL << i); //将第i位设置为1
}
}
if (irCode != NEC_REPEAT_CODE && irCode == ~lastIrCode) { //检查红外码是否有效
lastIrCode = irCode; //保存上一次接收到的红外码
uint8_t address = (irCode >> 24) & 0xFF; //解析出地址码
uint8_t command = (irCode >> 16) & 0xFF; //解析出命令码
printf("Address: %02X, Command: %02X\n", address, command); //将解析结果输出到串口
}
}
}
int main(void) {
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//配置红外接收器的引脚为输入模式,上拉输入
GPIO_InitStructure.GPIO_Pin = IR_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(IR_PORT, &GPIO_InitStructure);
//配置外部中断线0,用于检测红外信号的上升沿
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
//配置外部中断线0的中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//配置系统滴答定时器,用于微秒级延时
SysTick_Config(SystemCoreClock / 1000000);
while (1) {
//程序主循环
}
}
```
该程序使用STM32F10x系列的微控制器,连接一个红外接收器到PA0上,通过读取红外接收器的电平值来接收红外信号。当检测到红外信号的上升沿时,程序会接收32位红外码,并解析出地址码和命令码。程序使用printf函数将解析结果输出到串口。需要注意的是,该程序不处理重复码,因此在接收到重复码时不会进行解码。
阅读全文