#include "ev1527.h" // 定时周期 //#define TIME_CYCLE 80 #define TIME_CYCLE PERIOD_VALUE // #define TIME_CYCLE 20 // 定义引导码的最小和最大持续时间(单位:us) #define MIN_LEAD_CODE (5600 / TIME_CYCLE) #define MAX_LEAD_CODE (16000 / TIME_CYCLE) // 定义数据位持续时间的最小和最大范围(单位:us) #define MIN_BIT_DURATION (100 / TIME_CYCLE) #define MAX_BIT_DURATION (2400 / TIME_CYCLE) // 定义功能字节在接收缓冲区中的索引位置 #define FUNCTION_BYTE_INDEX 2 // 定义功能值 #define FUNCTION_1 0x08 #define FUNCTION_2 0x04 #define FUNCTION_3 0x02 #define FUNCTION_4 0X01 #define FUNCTION_5 0X03 #define FUNCTION_6 0X05 #define FUNCTION_7 0X07 #define FUNCTION_8 0X00 // 定义数据解码状态枚举 typedef enum { LEAD_CODE, // 引导码状态 HIGH_BIT, // 高位数据位状态 LOW_BIT, // 低位数据位状态 DATA_PROCESS, // 数据处理状态 FUNCTION_PROCESS // 功能处理状态 } Decode_State_t; // 定义全局变量和缓冲区 #define ARRAY_SIZE 128 static uint32_t Lead_Code_Count = 0; // 引导码计数 static uint32_t High_Bit_Count = 0; // 高位数据位计数 static uint32_t Low_Bit_Count = 0; // 低位数据位计数 static uint32_t High_Bit_Duration = 0; // 高位数据位持续时间 static uint32_t Low_Bit_Duration = 0; // 低位数据位持续时间 static uint8_t Received_Buffer[ARRAY_SIZE] = {0}; // 接收数据缓冲区 static uint8_t lastDataArray[ARRAY_SIZE] = {0}; // 上一次接收数据缓冲区 static uint8_t Received_Byte_Count = 0; // 接收数据字节计数 static uint8_t consecutiveEqualCount = 0; // 数据接收相同计数 static uint8_t Bit_Count = 0; // 接收数据位计数 static uint8_t Received_Data = 0; // 接收到的数据 static Decode_State_t RF_Decode_State = LEAD_CODE; // 数据解码状态 static uint32_t Lead_Code_Count_Start =0; static uint32_t High_Bit_Count_Start =0; static uint32_t Low_Bit_Count_Start =0; void Decode_Data(void); void Execute_Function(void); void Reset_Decode_Parameters(void); /**----------------------------------------------------------------------------------------------** **函数名 :EV1527端口配置 **功能说明:初始化IO口,不同单片机的配置输入模式不一样,自行修改。 **----------------------------------------------------------------------------------------------**/ void EV1527_Init(void) { DATA_433_GPIO_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; // 配置上拉输入 GPIO_InitStruct.Pin = DATA_433_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(DATA_433_GPIO_PORT, &GPIO_InitStruct); } #if 0 /**----------------------------------------------------------------------------------------------** **函数名 :RF信号解码函数 **功能说明:解码从433MHz接收到的信号,并根据解码结果执行相应功能 **调用说明:80us调用一次 **----------------------------------------------------------------------------------------------**/ void RF_Signal_Decode(void) { switch (RF_Decode_State) { case LEAD_CODE: // 引导码 // 判断是否低电平 if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_RESET) { Lead_Code_Count++; } else // 高电平判断范围 { // 判断引导码范围是否合法 if (Lead_Code_Count >= MIN_LEAD_CODE && Lead_Code_Count <= MAX_LEAD_CODE) { Lead_Code_Count = 0; Reset_Decode_Parameters(); // 重置解码参数 RF_Decode_State = HIGH_BIT; // 进入高位数据位判断状态 } else { Reset_Decode_Parameters(); // 引导码范围不合法,重置解码参数 } } break; case HIGH_BIT: // 判断是否高电平 if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_SET) { High_Bit_Count++; } else // 低电平判断范围 { // 判断高位数据位范围是否合法 if (High_Bit_Count >= MIN_BIT_DURATION && High_Bit_Count <= MAX_BIT_DURATION) { High_Bit_Duration = High_Bit_Count; // 保存计数值,用于区分0和1 High_Bit_Count = 0; RF_Decode_State = LOW_BIT; // 进入低位数据位判断状态 } else { Reset_Decode_Parameters(); // 高位数据位范围不合法,重置解码参数 } } break; case LOW_BIT: // 判断是否低电平 if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_RESET) { Low_Bit_Count++; } else // 高电平判断范围 { // 判断低位数据位范围是否合法 if (Low_Bit_Count >= MIN_BIT_DURATION && Low_Bit_Count <= MAX_BIT_DURATION) { Low_Bit_Duration = Low_Bit_Count; // 保存计数值,用于区分0和1 Low_Bit_Count = 0; RF_Decode_State = DATA_PROCESS; // 进入数据处理状态 } else { Reset_Decode_Parameters(); // 低位数据位范围不合法,重置解码参数 } } break; case DATA_PROCESS: Decode_Data(); // 解码数据 if (Received_Byte_Count == 3) { // 接收到全部数据,包括地址和数据 RF_Decode_State = FUNCTION_PROCESS; } else { // 数据没接收完 RF_Decode_State = HIGH_BIT; // 继续解码数据 } break; case FUNCTION_PROCESS: Execute_Function(); // 执行功能 Reset_Decode_Parameters(); // 重置解码参数 break; default: Reset_Decode_Parameters(); // 默认状态,重置解码参数 break; } } #endif #if 1 /**----------------------------------------------------------------------------------------------** **函数名 :RF信号解码函数 **功能说明:解码从433MHz接收到的信号,并根据解码结果执行相应功能 **调用说明:80us调用一次 **----------------------------------------------------------------------------------------------**/ void RF_Signal_Decode(void) { switch (RF_Decode_State) { case LEAD_CODE: // 引导码 // 判断是否低电平 if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_RESET) { Lead_Code_Count++; } else // 高电平判断范围 { // 判断引导码范围是否合法 if (Lead_Code_Count >= MIN_LEAD_CODE && Lead_Code_Count <= MAX_LEAD_CODE) { Lead_Code_Count = 0; Reset_Decode_Parameters(); // 重置解码参数 RF_Decode_State = HIGH_BIT; // 进入高位数据位判断状态 } else { Reset_Decode_Parameters(); // 引导码范围不合法,重置解码参数 } } break; case HIGH_BIT: // 判断是否高电平 if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_SET) { High_Bit_Count++; } else // 低电平判断范围 { // 判断高位数据位范围是否合法 if (High_Bit_Count >= MIN_BIT_DURATION && High_Bit_Count <= MAX_BIT_DURATION) { High_Bit_Duration = High_Bit_Count; // 保存计数值,用于区分0和1 High_Bit_Count = 0; RF_Decode_State = LOW_BIT; // 进入低位数据位判断状态 } else { Reset_Decode_Parameters(); // 高位数据位范围不合法,重置解码参数 } } break; case LOW_BIT: // 判断是否低电平 if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_RESET) { Low_Bit_Count++; } else // 高电平判断范围 { // 判断低位数据位范围是否合法 if (Low_Bit_Count >= MIN_BIT_DURATION && Low_Bit_Count <= MAX_BIT_DURATION) { Low_Bit_Duration = Low_Bit_Count; // 保存计数值,用于区分0和1 Low_Bit_Count = 0; RF_Decode_State = DATA_PROCESS; // 进入数据处理状态 } else { Reset_Decode_Parameters(); // 低位数据位范围不合法,重置解码参数 } } break; case DATA_PROCESS: Decode_Data(); // 解码数据 if (Received_Byte_Count == 3) { // 接收到全部数据,包括地址和数据 RF_Decode_State = FUNCTION_PROCESS; } else { // 数据没接收完 RF_Decode_State = HIGH_BIT; // 继续解码数据 } break; case FUNCTION_PROCESS: Execute_Function(); // 执行功能 Reset_Decode_Parameters(); // 重置解码参数 break; default: Reset_Decode_Parameters(); // 默认状态,重置解码参数 break; } } #endif /**----------------------------------------------------------------------------------------------** **函数名 :Reset_Decode_Parameters **功能说明:重置解码参数,用于开始新的解码周期 **----------------------------------------------------------------------------------------------**/ void Reset_Decode_Parameters(void) { Bit_Count = 0; Received_Data = 0x00; Received_Byte_Count = 0; Lead_Code_Count = 0; High_Bit_Count = 0; Low_Bit_Count = 0; High_Bit_Duration = 0; Low_Bit_Duration = 0; RF_Decode_State = LEAD_CODE; } /**----------------------------------------------------------------------------------------------** **函数名 :Decode_Data **功能说明:解码数据位,将解码后的数据存入相应的缓冲区中 **----------------------------------------------------------------------------------------------**/ void Decode_Data(void) { Received_Data <<= 1; // 根据高低电平持续时间判断0和1,然后将数据移位存入缓冲区 if (High_Bit_Duration > Low_Bit_Duration) { Received_Data |= 0x01; } else { Received_Data &= 0xFE; } Bit_Count++; // 每接收8位数据,存入数据数组 if (Bit_Count == 8) { Received_Buffer[Received_Byte_Count] = Received_Data; Received_Data = 0x00; Bit_Count = 0; Received_Byte_Count++; } } /**----------------------------------------------------------------------------------------------** **函数名 :Execute_Function **功能说明:执行功能,根据解码后的数据进行相应操作 **----------------------------------------------------------------------------------------------**/ void Execute_Function(void) { // 判断解码后的功能字节,并执行相应操作 switch (0x0F&Received_Buffer[FUNCTION_BYTE_INDEX]) { case FUNCTION_1: // 执行功能1 printf("\r\n Function_1 \r\n"); break; case FUNCTION_2: // 执行功能2 printf("\r\n Function_2 \r\n"); break; case FUNCTION_3: // 执行功能3 printf("\r\n Function_3 \r\n"); break; case FUNCTION_4: // 执行功能4 printf("\r\n Function_4 \r\n"); break; case FUNCTION_5: // 执行功能5 printf("\r\n Function_5 \r\n"); break; case FUNCTION_6: // 执行功能6 printf("\r\n Function_6 \r\n"); break; case FUNCTION_7: // 执行功能7 printf("\r\n Function_7 \r\n"); break; case FUNCTION_8: // 执行功能8 printf("\r\n Function_8 \r\n"); break; default: // 默认操作 // printf("\r\n --- code =%02x",Received_Buffer[FUNCTION_BYTE_INDEX]); printf("\r\n ADDR= %02x %02x %02x CMD=%02x",Received_Buffer[0],Received_Buffer[1],Received_Buffer[2], 0x0F&Received_Buffer[FUNCTION_BYTE_INDEX]); break; } } uint8_t bt_auto; //自动设置遥控接收波特率标志 extern uint8_t rf_data[4]; #if 0 #define BIT1_HIGH_US 1000 // duty cycle = #define BIT1_LOW_US 500 // #define BIT0_HIGH_US 400 #define BIT0_LOW_US 1100 #endif #if 1 // RC_PROJECTOR #define BIT1_HIGH_US 1000 // duty cycle = #define BIT1_LOW_US 500 // #define BIT0_HIGH_US 250 #define BIT0_LOW_US 1200 #define ENDING_LOW_US 12000 #define ENDING_HIGH_US 200 #endif #if 0 // SOS BUTTON #define BIT1_HIGH_US 800 // duty cycle = #define BIT1_LOW_US 300 // #define BIT0_HIGH_US 300 #define BIT0_LOW_US 800 #define ENDING_LOW_US 8000 #define ENDING_HIGH_US 245 #endif //#define CNT_SHORT_US 305 // 305 usec #define LEADING_MS 12 // 8 msec void STS_RF_write_send_1(void) { HAL_GPIO_WritePin(RF_Send_GPIO_Port, RF_Send_GPIO_Pin, SET); HAL_Delay_Us(BIT1_HIGH_US); HAL_GPIO_WritePin(RF_Send_GPIO_Port, RF_Send_GPIO_Pin, RESET); HAL_Delay_Us(BIT1_LOW_US); } void STS_RF_write_send_0(void) { HAL_GPIO_WritePin(RF_Send_GPIO_Port, RF_Send_GPIO_Pin, SET); HAL_Delay_Us(BIT0_HIGH_US); HAL_GPIO_WritePin(RF_Send_GPIO_Port, RF_Send_GPIO_Pin, RESET); HAL_Delay_Us(BIT0_LOW_US); } void STS_RF_write_send_leading(void) { HAL_GPIO_WritePin(RF_Send_GPIO_Port, RF_Send_GPIO_Pin, RESET); //HAL_Delay(CNT_LONG_MS); // 8 msec long low level HAL_Delay_Us(LEADING_MS*1000); } void STS_RF_write_send_ending(void) { HAL_GPIO_WritePin(RF_Send_GPIO_Port, RF_Send_GPIO_Pin, SET); HAL_Delay_Us(ENDING_HIGH_US); HAL_GPIO_WritePin(RF_Send_GPIO_Port, RF_Send_GPIO_Pin, RESET); HAL_Delay_Us(ENDING_LOW_US); } void STS_RF_Send_Button_Multi_Times(uint8_t *rf_payload, uint8_t one_button, uint8_t rf_length, uint8_t mt) { // normally, send 5-8 cycles of same address and cmd code uint8_t push_button_cmd = one_button; for (uint8_t i=0; i< mt; i++) { rf_payload[2] |= ((push_button_cmd)); printf("%d : Address=%02X:%02X:%01x CMD=%01X\r\n",i, rf_payload[0], rf_payload[1], rf_payload[2]&0xF0, push_button_cmd); STS_RF_Send_AddressBit_and_CmdBit(rf_payload, rf_length); rf_payload[2] &= 0xF0; // cmd set to 0 } } void STS_RF_Send_Multi_Times(uint8_t *rf_payload, uint8_t rf_length, uint8_t mt) { // normally, send 5-8 cycles of same address and cmd code // uint8_t push_button_cmd = 0x01; for (uint8_t i=0; i< mt; i++) { rf_payload[2] |= ((i+1) <<4); printf("%d : Address=%02X:%02X:%01x CMD=%01X\r\n",i, rf_payload[0],rf_payload[1],rf_payload[2]&0x0F, (rf_payload[2]>>4)&0x0F); STS_RF_Send_AddressBit_and_CmdBit(rf_payload, rf_length); rf_payload[2] &= 0x0F; // cmd set to 0 } } void STS_RF_Send_AddressBit_and_CmdBit(uint8_t *rf_payload, uint8_t rf_length) { // send the combined address code and cmd code // 20 bit address + 4 bit cmd code == 24 bits == 3 bytes // send leading or sync signal for receiver to sync the RX clock // printf("leading sync signal ...\r\n"); //STS_RF_write_send_leading(); // printf("address bits and cmd bits ...\r\n"); // send address and cmd code for (uint8_t i=0; i < rf_length; i++) { for (uint8_t j=0; j < 8; j++) { // if (0x01&(rf_payload[i]>>j)) // TODO XXXX if (0x80&(rf_payload[i]<> 24; sec_byte = (frame_data>>16) & 0xff; tir_byte = frame_data >> 8; fou_byte = frame_data; /* 记得清标志位 */ frame_flag = 0; if( (first_byte==(uint8_t)~sec_byte) && (first_byte==IRDA_ID) ) { if( tir_byte == (u8)~fou_byte ) return tir_byte; } return 0; /* 错误返回 */ } // IO 线中断, 接红外接收头的数据管脚 void IRDA_EXTI_IRQHANDLER_FUN(void) { uint8_t pulse_time = 0; uint8_t leader_code_flag = 0; /* 引导码标志位,当引导码出现时,表示一帧数据开始 */ uint8_t irda_data = 0; /* 数据暂存位 */ if(EXTI_GetITStatus(IRDA_EXTI_LINE) != RESET) /* 确保是否产生了EXTI Line中断 */ { while(1) { if( IrDa_DATA_IN()== SET ) /* 只测量高电平的时间 */ { pulse_time = Get_Pulse_Time(); /* >=5ms 不是有用信号 当出现干扰或者连发码时,也会break跳出while(1)循环 */ if( pulse_time >= 250 ) { break; /* 跳出while(1)循环 */ } if(pulse_time>=200 && pulse_time<250) /* 获得前导位 4ms~4.5ms */ { leader_code_flag = 1; } else if(pulse_time>=10 && pulse_time<50) /* 0.56ms: 0.2ms~1ms */ { irda_data = 0; } else if(pulse_time>=50 && pulse_time<100) /* 1.68ms:1ms~2ms */ { irda_data =1 ; } else if( pulse_time>=100 && pulse_time<=200 ) /* 2.1ms:2ms~4ms */ {/* 连发码,在第二次中断出现 */ frame_flag = 1; /* 一帧数据接收完成 */ frame_cnt++; /* 按键次数加1 */ isr_cnt ++; /* 进中断一次加1 */ break; /* 跳出while(1)循环 */ } if( leader_code_flag == 1 ) {/* 在第一次中断中完成 */ frame_data <<= 1; frame_data += irda_data; frame_cnt = 0; isr_cnt = 1; } } }// while(1) EXTI_ClearITPendingBit(IRDA_EXTI_LINE); //清除中断标志位 //LED2_TOGGLE; } } #define CLI() __set_PRIMASK(1) /* 关闭总中断 */ #define SEI() __set_PRIMASK(0) /* 开放总中断 */ extern uint8_t frame_flag; extern uint8_t isr_cnt; extern uint8_t frame_cnt; /** * @brief 主函数 * @param 无 * @retval 无 */ int irda_main(void) { uint8_t key_val; /* config the led */ LED_GPIO_Config(); LED1_ON; /* 配置SysTick 为10us中断一次 */ SysTick_Init(); /* 重新配置SysTick的中断优先级为最高,要不然SysTick延时中断抢占不了IO EXTI中断 * 因为SysTick初始化时默认配置的优先级是最低的 * 或者当你用其他定时器做延时的时候,要配置定时器的优先级高于IO EXTI中断的优先级 */ NVIC_SetPriority (SysTick_IRQn, 0); /* USART1 config 115200 8-N-1 */ USART_Config(); printf("\r\n 这是一个红外遥控发射与接收实验 \r\n"); /* 初始化红外接收头CP1838用到的IO */ IrDa_Init(); for(;;) { if( frame_flag == 1 ) /* 一帧红外数据接收完成 */ { key_val = IrDa_Process(); printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 按键次数frame_cnt=%d \r\n",frame_cnt); printf("\r\n 中断次数isr_cnt=%d \r\n",isr_cnt); /* 不同的遥控器面板对应不同的键值,需要实际测量 */ switch( key_val ) { case 0: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n Error \r\n"); break; case 162: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n POWER \r\n"); break; case 226: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n MENU \r\n"); break; case 34: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n TEST \r\n"); break; case 2: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n + \r\n"); break; case 194: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n RETURN \r\n"); break; case 224: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n |<< \r\n"); break; case 168: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n > \r\n"); break; case 144: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n >>| \r\n"); break; case 104: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 0 \r\n"); break; case 152: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n - \r\n"); break; case 176: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n C \r\n"); break; case 48: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 1 \r\n"); break; case 24: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 2 \r\n"); break; case 122: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 3 \r\n"); break; case 16: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 4 \r\n"); break; case 56: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 5 \r\n"); break; case 90: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 6 \r\n"); break; case 66: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 7 \r\n"); break; case 74: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 8 \r\n"); break; case 82: LED1_TOGGLE; printf("\r\n key_val=%d \r\n",key_val); printf("\r\n 9 \r\n"); break; default: break; } } } } #endif