From c54733fdf794ec28dcd8672bdc84959fa4e7d1ea Mon Sep 17 00:00:00 2001 From: YunHorn Technology Date: Thu, 27 Feb 2025 18:45:36 +0800 Subject: [PATCH] good decoder and encoder send --- Core/Inc/ev1527.h | 29 ++ Core/Inc/main.h | 12 +- Core/Inc/tim.h | 3 +- Core/Src/ev1527.c | 391 ++++++++++++++++++++++++-- Core/Src/gpio.c | 4 +- Core/Src/main.c | 22 +- Core/Src/stm32wlxx_hal_msp.c | 53 +--- Core/Src/stm32wlxx_it.c | 23 +- Core/Src/sys_app.c | 71 +---- Core/Src/tim.c | 84 +++++- STM32CubeIDE/Release/WL55JC_AS923.elf | Bin 67776 -> 68660 bytes 11 files changed, 541 insertions(+), 151 deletions(-) diff --git a/Core/Inc/ev1527.h b/Core/Inc/ev1527.h index 040ef57..96088f2 100644 --- a/Core/Inc/ev1527.h +++ b/Core/Inc/ev1527.h @@ -51,4 +51,33 @@ void STS_RF_Send_AddressBit_and_CmdBit(uint8_t *rf_payload, uint8_t rf_length); void EV1527Reset(void); void EV1527Decode(uint32_t v); + + +#if 0 +// #include "stm32f10x.h" +void EXTI_PB11_Config(void); +void IrDa_Init(void); +uint8_t Get_Pulse_Time(void); +uint8_t IrDa_Process(void); + +#define IRDA_ID 0 + +//红外遥控使用的GPIO及时钟 +#define IRDA_GPIO_PORT GPIOE +#define IRDA_GPIO_CLK RCC_APB2Periph_GPIOE +#define IRDA_GPIO_PIN GPIO_Pin_5 +#define IRDA_GPIO_PORT_SOURCE GPIO_PortSourceGPIOE +#define IRDA_GPIO_PIN_SOURCE GPIO_PinSource5 + +//中断相关 +#define IRDA_EXTI_LINE EXTI_Line5 +#define IRDA_EXTI_IRQN EXTI9_5_IRQn +#define IRDA_EXTI_IRQHANDLER_FUN EXTI9_5_IRQHandler + + //读取引脚的电平 +#define IrDa_DATA_IN() GPIO_ReadInputDataBit(IRDA_GPIO_PORT,IRDA_GPIO_PIN) +#endif + + + #endif diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 7d6dddb..c03903a 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -90,8 +90,16 @@ void Error_Handler(void); #define USART1_TX_GPIO_Port GPIOB #ifdef RC + #define TIM1_PRESCALER_VALUE 47L // 1 us for stm32wle5xx 48Mhz -#define TIM1_PERIOD_VALUE 79L // 80 us +#define TIM1_PERIOD_VALUE 9L // 10 us + +#define TIM2_PRESCALER_VALUE (uint32_t)(((SystemCoreClock) /(1000000)) - 1) +// make it 1 us interval +#define TIM2_PERIOD_VALUE (90 - 1) +// make it 40 us interval +#define PRESCALER_VALUE TIM2_PRESCALER_VALUE +#define PERIOD_VALUE TIM2_PERIOD_VALUE // REMOTE CONTROL EV1527/HS1527 LORA-WAN RELAY NODE @@ -172,7 +180,7 @@ void Error_Handler(void); #define RF_Receive_GPIO_Port GPIOA #define RF_Receive_GPIO_Pin GPIO_PIN_9 #define RF_Receive_GPIO_CLK_EN() __HAL_RCC_GPIOA_CLK_ENABLE(); - +#define RF_Receive_Data_In() HAL_GPIO_ReadPin(RF_Receive_GPIO_Port, RF_Receive_GPIO_Pin) #endif diff --git a/Core/Inc/tim.h b/Core/Inc/tim.h index efd1057..f811edd 100644 --- a/Core/Inc/tim.h +++ b/Core/Inc/tim.h @@ -39,8 +39,9 @@ extern TIM_HandleTypeDef htim1; /* USER CODE BEGIN Prototypes */ void MX_TIM1_Init(void); +void MX_TIM2_Init(void); void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); - +uint8_t Get_Pulse_Time(void); /* USER CODE END Prototypes */ #ifdef __cplusplus diff --git a/Core/Src/ev1527.c b/Core/Src/ev1527.c index 48d1571..49fd96a 100644 --- a/Core/Src/ev1527.c +++ b/Core/Src/ev1527.c @@ -1,14 +1,15 @@ #include "ev1527.h" volatile uint32_t TIM1_cnt=0; // 定时周期 -#define TIME_CYCLE 80 +//#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 (80 / TIME_CYCLE) +#define MIN_BIT_DURATION (100 / TIME_CYCLE) #define MAX_BIT_DURATION (2400 / TIME_CYCLE) // 定义功能字节在接收缓冲区中的索引位置 @@ -84,28 +85,21 @@ void RF_Signal_Decode(void) // 判断是否低电平 if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_RESET) { - // printf("_"); - // Lead_Code_Count++; - // Lead_Code_Count = TIM1_cnt - Lead_Code_Count_Start; + + Lead_Code_Count++; } else // 高电平判断范围 { - - Lead_Code_Count = TIM1_cnt - Lead_Code_Count_Start; - printf("+"); // 判断引导码范围是否合法 - 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; // 进入高位数据位判断状态 - printf("+"); } else { - printf("."); Reset_Decode_Parameters(); // 引导码范围不合法,重置解码参数 } } @@ -115,20 +109,16 @@ void RF_Signal_Decode(void) // 判断是否高电平 if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_SET) { - // High_Bit_Count++; - // High_Bit_Count = TIM1_cnt; - High_Bit_Count_Start = TIM1_cnt; + High_Bit_Count++; } else // 低电平判断范围 { - High_Bit_Count = TIM1_cnt - High_Bit_Count_Start; // 判断高位数据位范围是否合法 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; // 进入低位数据位判断状态 - printf("-"); } else { @@ -141,20 +131,16 @@ void RF_Signal_Decode(void) // 判断是否低电平 if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_RESET) { - //Low_Bit_Count++; - // Low_Bit_Count = TIM1_cnt; - Low_Bit_Count_Start = TIM1_cnt; + Low_Bit_Count++; } else // 高电平判断范围 { - Low_Bit_Count = TIM1_cnt - Low_Bit_Count_Start; // 判断低位数据位范围是否合法 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; // 进入数据处理状态 - printf("o"); } else { @@ -302,10 +288,6 @@ void Reset_Decode_Parameters(void) High_Bit_Duration = 0; Low_Bit_Duration = 0; RF_Decode_State = LEAD_CODE; - - Lead_Code_Count_Start = TIM1_cnt; - High_Bit_Count_Start = TIM1_cnt; - } /**----------------------------------------------------------------------------------------------** @@ -383,12 +365,13 @@ void Execute_Function(void) default: // 默认操作 - printf("\r\n --- code =%02x",Received_Buffer[FUNCTION_BYTE_INDEX]); + // 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; } } - +#if 0 uint8_t RF; uint8_t decode_ok; //解码成功 uint8_t hh_w,ll_w; //高,低电平宽度 @@ -404,6 +387,7 @@ uint8_t old_rc5; //保存上一次查询到的电平状态 uint8_t tb_ok; //接收到同步的马时置1 uint8_t D0,D1,D2,D3; uint16_t s,s1; +#endif uint8_t bt_auto; //自动设置遥控接收波特率标志 extern uint8_t rf_data[4]; @@ -541,5 +525,358 @@ void STS_RF_Send_AddressBit_and_CmdBit(uint8_t *rf_payload, uint8_t rf_length) // printf("ending bits ...\r\n"); } +#if 0 +/** + ****************************************************************************** + * @file bsp_irda.c + * @author fire + * @version V1.0 + * @date 2013-xx-xx + * @brief 红外遥控器接口 + ****************************************************************************** + * @attention + * + * 实验平台:野火 F103-指南者 STM32 开发板 + * 论坛 :http://www.firebbs.cn + * 淘宝 :https://fire-stm32.taobao.com + * + ****************************************************************************** + */ + +//#include "./IrDa/bsp_irda.h" +//#include "./systick/bsp_SysTick.h" +//#include "./led/bsp_led.h" + +uint32_t frame_data=0; /* 一帧数据缓存 */ +uint8_t frame_cnt=0; +uint8_t frame_flag=0; /* 一帧数据接收完成标志 */ + + /** + * @brief 配置嵌套向量中断控制器NVIC + * @param 无 + * @retval 无 + */ +static void NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + + /* Configure one bit for preemption priority */ + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); + + /* 配置P[A|B|C|D|E]11为中断源 */ + NVIC_InitStructure.NVIC_IRQChannel = IRDA_EXTI_IRQN; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} +/* 初始化红外接收头1838用到的IO */ +void IrDa_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + EXTI_InitTypeDef EXTI_InitStructure; + + /* config the extiline clock and AFIO clock */ + RCC_APB2PeriphClockCmd(IRDA_GPIO_CLK | RCC_APB2Periph_AFIO,ENABLE); + + /* config the NVIC */ + NVIC_Configuration(); + + /* EXTI line gpio config */ + GPIO_InitStructure.GPIO_Pin = IRDA_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init(IRDA_GPIO_PORT, &GPIO_InitStructure); + + /* EXTI line mode config */ + GPIO_EXTILineConfig(IRDA_GPIO_PORT_SOURCE, IRDA_GPIO_PIN_SOURCE); + EXTI_InitStructure.EXTI_Line = IRDA_EXTI_LINE; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿中断 + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); +} + +/* 获取高电平的时间 */ +uint8_t Get_Pulse_Time(void) +{ + uint8_t time = 0; + while( IrDa_DATA_IN() ) + { + time ++; + Delay_us(2); // 延时 20us + if(time == 250) + return time; // 超时溢出 + } + return time; +} + +/* + * 帧数据有4个字节,第一个字节是遥控的ID,第二个字节是第一个字节的反码 + * 第三个数据是遥控的真正的键值,第四个字节是第三个字节的反码 + */ +uint8_t IrDa_Process(void) +{ + uint8_t first_byte, sec_byte, tir_byte, fou_byte; + + first_byte = frame_data >> 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 + diff --git a/Core/Src/gpio.c b/Core/Src/gpio.c index 59c5973..0079795 100644 --- a/Core/Src/gpio.c +++ b/Core/Src/gpio.c @@ -125,8 +125,8 @@ void MX_GPIO_Init(void) #if 1 GPIO_InitStruct.Pin = RF_Receive_GPIO_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; //GPIO_MODE_INPUT; //GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //GPIO_MODE_INPUT; //GPIO_MODE_IT_RISING_FALLING; + GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(RF_Receive_GPIO_Port, &GPIO_InitStruct); #endif diff --git a/Core/Src/main.c b/Core/Src/main.c index 5eaf1b7..785bc00 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -32,7 +32,7 @@ // #include "sts_aq_o3.h" /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ -TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim1, htim2; //uint8_t rf_payload[3]={0xF8,0xCD,0x07}, rf_length=3; uint8_t rf_payload[3]={0x1F,0xB3,0xE0}, rf_length=3; // RC_PROJECTOR uint8_t sos_rf_payload[3]={0x82,0x73,0xA0}, sos_rf_length=3; // sos_button @@ -137,10 +137,26 @@ int main(void) // MX_USART1_UART_Init(); - MX_TIM1_Init(); + //MX_TIM1_Init(); + MX_TIM2_Init(); + + /*## Start the TIM Base generation in interrupt mode ####################*/ + /* Start Channel1 */ + if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK) + { + /* Starting Error */ + Error_Handler(); + } + printf("start \r\n"); + while(1) + { + + } + + // EV1527_Init(); #if 0 @@ -506,6 +522,8 @@ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ + + HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET); __disable_irq(); while (1) { diff --git a/Core/Src/stm32wlxx_hal_msp.c b/Core/Src/stm32wlxx_hal_msp.c index 73369f8..5e315e3 100644 --- a/Core/Src/stm32wlxx_hal_msp.c +++ b/Core/Src/stm32wlxx_hal_msp.c @@ -150,35 +150,18 @@ void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef* htim_ic) */ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(htim_base->Instance==TIM1) + + if(htim_base->Instance==TIM2) { /* USER CODE BEGIN TIM1_MspInit 0 */ /* USER CODE END TIM1_MspInit 0 */ /* Peripheral clock enable */ - __HAL_RCC_TIM1_CLK_ENABLE(); + __HAL_RCC_TIM2_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - /**TIM1 GPIO Configuration - PA9 ------> TIM1_CH2 - */ - GPIO_InitStruct.Pin = GPIO_PIN_9; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - /* TIM1 interrupt Init */ - HAL_NVIC_SetPriority(TIM1_BRK_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM1_BRK_IRQn); - HAL_NVIC_SetPriority(TIM1_UP_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM1_UP_IRQn); - HAL_NVIC_SetPriority(TIM1_TRG_COM_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM1_TRG_COM_IRQn); - HAL_NVIC_SetPriority(TIM1_CC_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); + /* TIM1 interrupt Init */ + HAL_NVIC_SetPriority(TIM2_IRQn, 3, 0); + HAL_NVIC_EnableIRQ(TIM2_IRQn); /* USER CODE BEGIN TIM1_MspInit 1 */ /* USER CODE END TIM1_MspInit 1 */ @@ -194,27 +177,19 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) */ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM1) + if(htim_base->Instance==TIM2) { - /* USER CODE BEGIN TIM1_MspDeInit 0 */ + /* USER CODE BEGIN TIM2_MspDeInit 0 */ - /* USER CODE END TIM1_MspDeInit 0 */ + /* USER CODE END TIM2_MspDeInit 0 */ /* Peripheral clock disable */ - __HAL_RCC_TIM1_CLK_DISABLE(); + __HAL_RCC_TIM2_CLK_DISABLE(); - /**TIM1 GPIO Configuration - PA9 ------> TIM1_CH2 - */ - HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9); + /* TIM2 interrupt DeInit */ + HAL_NVIC_DisableIRQ(TIM2_IRQn); + /* USER CODE BEGIN TIM2_MspDeInit 1 */ - /* TIM1 interrupt DeInit */ - HAL_NVIC_DisableIRQ(TIM1_BRK_IRQn); - HAL_NVIC_DisableIRQ(TIM1_UP_IRQn); - HAL_NVIC_DisableIRQ(TIM1_TRG_COM_IRQn); - HAL_NVIC_DisableIRQ(TIM1_CC_IRQn); - /* USER CODE BEGIN TIM1_MspDeInit 1 */ - - /* USER CODE END TIM1_MspDeInit 1 */ + /* USER CODE END TIM2_MspDeInit 1 */ } } diff --git a/Core/Src/stm32wlxx_it.c b/Core/Src/stm32wlxx_it.c index d732eaa..ee6d2e7 100644 --- a/Core/Src/stm32wlxx_it.c +++ b/Core/Src/stm32wlxx_it.c @@ -63,7 +63,7 @@ extern DMA_HandleTypeDef hdma_usart2_tx; extern UART_HandleTypeDef huart2; extern UART_HandleTypeDef huart1; -extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim1, htim2; /* USER CODE BEGIN EV */ @@ -197,7 +197,7 @@ void PendSV_Handler(void) void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ - + // HAL_IncTick(); /* USER CODE END SysTick_IRQn 0 */ /* USER CODE BEGIN SysTick_IRQn 1 */ @@ -459,10 +459,9 @@ void SUBGHZ_Radio_IRQHandler(void) } /* USER CODE BEGIN 1 */ -#if 0 +#if 1 void TIM1_IRQHandler(void) { - TIM1_cnt++; HAL_TIM_IRQHandler(&htim1); } #endif @@ -499,4 +498,20 @@ void TIM1_IC_IRQHandler(void) } #endif + +/** + * @brief This function handles TIM2 Global Interrupt. + */ +void TIM2_IRQHandler(void) +{ + /* USER CODE BEGIN TIM2_IRQn 0 */ + + /* USER CODE END TIM2_IRQn 0 */ + HAL_TIM_IRQHandler(&htim2); + /* USER CODE BEGIN TIM2_IRQn 1 */ + + /* USER CODE END TIM2_IRQn 1 */ +} + + /* USER CODE END 1 */ diff --git a/Core/Src/sys_app.c b/Core/Src/sys_app.c index 1fc1cd1..aea649d 100644 --- a/Core/Src/sys_app.c +++ b/Core/Src/sys_app.c @@ -382,86 +382,19 @@ void HAL_Delay(__IO uint32_t Delay) /* USER CODE END HAL_Delay_2 */ } + /* USER CODE BEGIN Overload_HAL_weaks */ /** * @note This function overwrites the __weak one from HAL */ void HAL_Delay_Us(uint32_t uDelay) { -#if 0 - uint32_t startval, tickn, delays, wait; - startval = SysTick->VAL; - tickn = HAL_GetTick(); - delays = uDelay * 48; - if (delays > startval) - { - while (HAL_GetTick() == tickn) {} - wait = 48000 + startval -delays; - while (wait < SysTick->VAL) {}; - - }else { - wait = startval - delays; - while(wait < SysTick->VAL && HAL_GetTick() == tickn) - { - - } - } -#endif -#if 0 - uint32_t g_fac_us=48; - uint32_t ticks; - uint32_t told, tnow, tcnt =0; - uint32_t reload = SysTick->LOAD; - - ticks = uDelay * g_fac_us; - - told = SysTick->VAL; - - while(1) - { - tnow = SysTick->VAL; - if (tnow != told) - { - if (tnow < told) - { - tcnt += told -tnow; - } else { - tcnt += reload - tnow + told; - } - told = tnow; - if (tcnt >= ticks) - { - break; - } - } - } - -#endif - #if 1 __IO uint32_t delay= uDelay*48/8; do {__NOP();} while(delay --); #endif -#if 0 - /* TIMER_IF can be based on other counter the SysTick e.g. RTC */ - /* USER CODE BEGIN HAL_Delay_1 */ -uint32_t startval, tickn, delays, wait; -startval = SysTick->VAL; -tickn = HAL_GetTick(); -// sysclock = 48000 -delays = uDelay*48; -if (delays > startval) -{ - while(HAL_GetTick() == tickn) ; - wait = 48000 + startval - delays; - while(wait < SysTick->VAL) ; -} else { - wait = startval - delays; - while (wait < SysTick->VAL && HAL_GetTick() == tickn) ; -} - /* USER CODE END HAL_Delay_1 */ -#endif + /* USER CODE BEGIN HAL_Delay_2 */ /* USER CODE END HAL_Delay_2 */ diff --git a/Core/Src/tim.c b/Core/Src/tim.c index 7e86e12..67a6b18 100644 --- a/Core/Src/tim.c +++ b/Core/Src/tim.c @@ -23,7 +23,7 @@ #include "stdio.h" #include "ev1527.h" /* USER CODE BEGIN 0 */ -extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim1, htim2; // DMA_HandleTypeDef hdma_tim1_ch1; //PA8 WS2812B @@ -89,20 +89,24 @@ void MX_TIM1_Init(void) htim1.Instance = TIM1; htim1.Init.Prescaler = TIM1_PRESCALER_VALUE; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; - htim1.Init.Period = 0xffff; // TIM1_PERIOD_VALUE; // 0xffff; // TIM1_PERIOD_VALUE; + htim1.Init.Period = TIM1_PERIOD_VALUE; // TIM1_PERIOD_VALUE; // 0xffff; // TIM1_PERIOD_VALUE; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; -#if 0 +#if 1 if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } #endif + +#if 1 if (HAL_TIM_IC_Init(&htim1) != HAL_OK) { Error_Handler(); } +#endif + #if 0 sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; sSlaveConfig.InputTrigger = TIM_TS_TI2FP2; @@ -148,6 +152,54 @@ void MX_TIM1_Init(void) } + + +/** + * @brief TIM2 Initialization Function + * @param None + * @retval None + */ +void MX_TIM2_Init(void) +{ + + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + htim2.Instance = TIM2; + htim2.Init.Prescaler = PRESCALER_VALUE; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = PERIOD_VALUE; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ + +} + + #if 1 #define EV1527_H4 328 // NARROW PULSE WIDTH us, varies on different remote control @@ -203,6 +255,13 @@ void EV1527Decode(uint32_t v) } } +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + //printf("."); + RF_Signal_Decode(); + +} + void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { static uint32_t uwICValue; @@ -214,9 +273,9 @@ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) //printf(" cc "); // RF_Signal_Decode(); - //if (TIM1 == htim->Instance) + if (TIM1 == htim->Instance) { - //if ((htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)) + if ((htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)) { if (HAL_GPIO_ReadPin(RF_Receive_GPIO_Port,RF_Receive_GPIO_Pin)== GPIO_PIN_RESET) { // Falling edge @@ -665,6 +724,21 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) } #endif +/* 获取高电平的时间 */ +uint8_t Get_Pulse_Time(void) +{ + uint8_t time = 0; + while( RF_Receive_Data_In() ) + { + time ++; + HAL_Delay_Us(1); + if(time == 250) + return time; // 超时溢出 + } + return time; +} + + /* USER CODE BEGIN 1 */ diff --git a/STM32CubeIDE/Release/WL55JC_AS923.elf b/STM32CubeIDE/Release/WL55JC_AS923.elf index 9975a367443671eab9db566d3f172c646d75f4b3..d80305a9605d3dfd22811494f12e991b31cf0de3 100644 GIT binary patch delta 24196 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 GJNiE@>+`1o delta 22841 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