基于ATM32F103C8T6写一个NEC红外遥控程序,PB9为信号接收引脚,
时间: 2024-01-22 07:18:31 浏览: 22
好的,以下是ATM32F103C8T6上的NEC红外遥控程序示例:
```c
#include "stm32f10x.h"
#define IR_PIN GPIO_Pin_9
#define IR_GPIO GPIOB
volatile uint16_t irBuffer[32];
volatile uint8_t irData[4];
void IR_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = IR_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(IR_GPIO, &GPIO_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line9;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void EXTI9_5_IRQHandler(void)
{
static uint8_t flag = 0;
static uint8_t dataCount = 0;
static uint16_t lastValue = 0;
uint16_t irValue = TIM2->CNT;
if (flag == 0) {
if (irValue < 8000 || irValue > 12000) {
return;
}
flag = 1;
} else if (flag == 1) {
if (irValue < 3500 || irValue > 4500) {
flag = 0;
return;
}
flag = 2;
} else if (flag == 2) {
if (irValue < 500 || irValue > 1500) {
flag = 0;
return;
}
lastValue = irValue;
flag = 3;
} else if (flag == 3) {
if (irValue < 500 || irValue > 1500) {
flag = 0;
return;
}
irBuffer[dataCount++] = (irValue + lastValue) / 2;
lastValue = irValue;
if (dataCount >= 32) {
flag = 4;
}
} else if (flag == 4) {
if (irValue < 500 || irValue > 1500) {
flag = 0;
dataCount = 0;
return;
}
irBuffer[dataCount++] = (irValue + lastValue) / 2;
lastValue = irValue;
if (dataCount >= 32) {
for (int i = 0; i < 4; i++) {
uint8_t byte = 0;
for (int j = 0; j < 8; j++) {
if (irBuffer[i * 8 + j + 1] > 1000) {
byte |= (1 << (7 - j));
}
}
irData[i] = byte;
}
flag = 0;
dataCount = 0;
}
}
EXTI_ClearITPendingBit(EXTI_Line9);
}
int main(void)
{
IR_Init();
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_Cmd(TIM2, ENABLE);
while (1) {
// 等待中断处理
}
}
```
代码的主要思路是使用外部中断来捕获红外信号,然后解码得到红外数据。在初始化中,我们使用`EXTI`和`TIM2`来设置PB9引脚的中断和计时器。在中断处理程序中,我们按照NEC红外协议对红外信号进行解码,得到4个字节的红外数据。最后,在主循环中等待中断处理程序对红外数据进行处理。
需要注意的是,在使用该代码时,需要将PB9引脚连接到红外接收器的信号引脚上。并且,由于ATM32F103C8T6没有内置的USB转串口芯片,因此需要使用外部的USB转串口模块来输出数据。