WL55JC_AS923/Core/Src/ev1527.c

706 lines
20 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 Received_Byte_Count = 0; // 接收数据字节计数
static uint8_t Bit_Count = 0; // 接收数据位计数
static uint8_t Received_Data = 0; // 接收到的数据
static Decode_State_t RF_Decode_State = LEAD_CODE; // 数据解码状态
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 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)
{
// 判断解码后的功能字节,并执行相应操作
printf("\r\n ADDR= %02x %02x %02x CMD=%02x",Received_Buffer[0],Received_Buffer[1],Received_Buffer[2], 0x0F&Received_Buffer[FUNCTION_BYTE_INDEX]);
printf("\r\n Function# %d \r\n", (0x0F&Received_Buffer[FUNCTION_BYTE_INDEX]));
}
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_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]<<j))
if (0x80&(rf_payload[i]<<j))
{
STS_RF_write_send_1();
} else {
STS_RF_write_send_0();
}
}
}
STS_RF_write_send_ending();
// 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.68ms1ms~2ms */
{
irda_data =1 ;
}
else if( pulse_time>=100 && pulse_time<=200 ) /* 2.1ms2ms~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