APT32F1023 接收RF433处理

对应上篇RF433发送:APT32F1023X 发送RF433处理-CSDN博客

1.硬件

接收芯片来自华普微: 

CMT2210LB_OOK射频接收芯片_315/433/8686/915MHz无线接收芯片 - RF射频、数字传感器产品专业设计生产商-深圳市华普微电子股份有限公司

2.代码示例

rf433.c

#include "rf433.h"

/*
 * -------		    -- 		----
 * 		  |		   |  |	   |	|
 * 		   --------	   ----	     --
 * */
//引导码低电平时间,4ms低电平 1ms高电平
#define RF_START_L_MAX    90    //80*50us=4ms
#define RF_START_L_MIN    70    //

#define RF_START_H_MAX    15    //
#define RF_START_H_MIN    5     //

#define RF_REC_BIT_LEN    32	//32位数据  4个字节

//	准备就绪:高电平1ms,4ms低电平
//	逻辑0:高电平1ms,低电平2ms
//	逻辑1:高电平2ms,低电平1ms
#define RF_LOGIC0_L_MAX   45//27        //50us  2ms 40
#define RF_LOGIC0_L_MIN   35//12	   	//50us

#define RF_LOGIC1_L_MAX   25//14      	//50us 1ms 20
#define RF_LOGIC1_L_MIN   15//7       	//

#define RF_433_USER_CODE   0xA2

 volatile U8_T Su8RfRxBitCnt = 0;  //接收数据位
 volatile U32_T Su32RfRxData  = 0;  //数据缓冲区
///全局与宏
volatile U8_T Gu8RfRxLowCnt  = 0;   //低电平接收计时器
volatile U8_T Gu8RfRxHighCnt = 0; 	//高电平接收计时器
volatile U8_T Gu8RfRxUserCode = 0;  //客户代码
volatile U8_T Gu8RfRxUserCode1 = 0; //客户代码
volatile U8_T Gu8RfRxKeyValue = 0;   //按键值
volatile U8_T bRfDecodeOk     = 0;    //解码是否成功标志位
volatile U8_T bRfRecStartFlag = 0;    //接收同步码成功标志位   
volatile U8_T bRfRecCodeOk    = 0;	

/*
*********************************************************************************************************
*	函 数 名: user_create
*	功能说明: 校验函数
*	形    参:  无
*	返 回 值: 无
*********************************************************************************************************
*/
unsigned char user_create (unsigned char *p1, unsigned short int len)
{
    unsigned char sum = 0;
    for(;len > 0; len--)
    {
        sum += *p1++;
    }
    //return sum;
	return (sum & 0xFF);// 只保留最低的8位
}
/*
*********************************************************************************************************
*	函 数 名: Rf433SoftDecode
*	功能说明: 解码函数
*	形    参:  无
*	返 回 值: 无
*********************************************************************************************************
*/
void Rf433SoftDecode(void)
{
	//临时变量
	volatile char *pa;
	//
	if(bRfRecStartFlag == 0)		//第一步,检测引导码,获取到引导码后开始检测数据
	{
		if((Gu8RfRxLowCnt > RF_START_L_MIN)&&(Gu8RfRxLowCnt < RF_START_L_MAX))	//引导码判断5ms低电平
		{
			bRfRecStartFlag = 1;	//下次循环跳过此if,开始接收数据 
			
			Su32RfRxData    = 0;    //数据缓存清零
			Su8RfRxBitCnt   = 0;    //数据长度清零
			Gu8RfRxUserCode = 0;
			Gu8RfRxKeyValue = 0;
		}
	}
	else if((bRfRecStartFlag == 1)&&(Su8RfRxBitCnt < RF_REC_BIT_LEN))  //用接收位数判断暂停        
	{
		if((Gu8RfRxLowCnt > RF_LOGIC0_L_MIN)&&(Gu8RfRxLowCnt < RF_LOGIC0_L_MAX))//逻辑0时长判断,低电平时间范围需稍微加宽
		{
			Su32RfRxData = Su32RfRxData<<1;  //LSB,从低位开始传数据,数据0直接位移
			Su8RfRxBitCnt++;				//总位数++																											
		}
		//
		else if((Gu8RfRxLowCnt > RF_LOGIC1_L_MIN)&&(Gu8RfRxLowCnt < RF_LOGIC1_L_MAX))
		{
			//Su32RfRxData = Su32RfRxData<<1;
			Su32RfRxData <<= 1;
			Su32RfRxData |= 1;         			//最低位赋值为1
			Su8RfRxBitCnt++;
		}
		else									//某一位的时长不符合协议要求,丢弃整个数据
		{
			bRfRecStartFlag = 0;
      		Su8RfRxBitCnt = 0;
		}
	}

	if(Su8RfRxBitCnt == 32)						//接受完32位后解析用户码
	{
		Su8RfRxBitCnt   = 0;					
		bRfRecStartFlag = 0;					//下一次重新检测引导码
		//
		pa =(char *)&Su32RfRxData;
		//
		g_rxBuffer[0] = *((char *)pa+3);
		g_rxBuffer[1] = *((char *)pa+2);
		g_rxBuffer[2] = *((char *)pa+1);
		g_rxBuffer[3] = *((char *)pa+0);
		//验证是否正确
		if(g_rxBuffer[3] == (user_create(g_rxBuffer,3)))
		{
			bRfRecCodeOk = 1;  
			//my_printf("g_rxBuffer[0] = %x",g_rxBuffer[0]);
			//my_printf("g_rxBuffer[1] = %x",g_rxBuffer[1]);
			//my_printf("g_rxBuffer[2] = %x",g_rxBuffer[2]);
			//my_printf("g_rxBuffer[3] = %x",g_rxBuffer[3]);		

		}
	}
}

/*
*********************************************************************************************************
1.低电平计数/滤波
接收解码扫描函数,每50us对433接收到的波形计数一次
采样扫描程序
*********************************************************************************************************
*/
void Recevie433DecodeScan(void)  			//放在50us定时器中断服务函数中
{
	static U8_T Su8FilterCnt = 0;
	static U8_T SbJumpFlag = 0;		 		//高低电平跳变标志,记录上一次引脚的状态,来反应从高到低或从低到高
	
	if(bRfDecodeOk == 0)					//解码不成功的时候需连续解码,解码成功后延时150ms再次解码
	{
		if(!RF_IO_DATA)            			//引脚输入低电平
		{
			Gu8RfRxLowCnt++;				//计时低电平个数来算时间,只通过低电平时间判断逻辑1或逻辑0
			Su8FilterCnt = 0;				//高电平滤波计算
			if(SbJumpFlag && Gu8RfRxLowCnt >= 2)    //两个50us的低电平后才判断电平从高到低,忽略部分杂波
			{
				SbJumpFlag = 0;  					//高到低跳变
			//	Su8FilterCnt = 0;
			}
		}
		else  								  		//引脚检测到高电平时,判断高高电平是否有效,高电平有效后,计算进入解码程序
		{
			if(!SbJumpFlag && Su8FilterCnt++ >= 2)  //可滤波
			{
				SbJumpFlag = 1;  					 //低到高跳变
				Rf433SoftDecode();          		 //对上后解码,一次一位
				Gu8RfRxLowCnt = 0;
				Su8FilterCnt = 0;
			}    
		}
	}
}


rf433.h

#ifndef _RF433_H_
#define _RF433_H_
//.H之中声明,在外部调用时,只需要#include包含相对应的.h
//需要用到的头文件
#include "apt32f102.h"
#include "my_printf.h"
#include "apt32f102_gpio.h"

//IO
#define RF_IO_DATA				GPIO_Read_Status(GPIOB0,3)
//
#define RF_PACKET_SIZE   4//32               /* Define the payload size here */

 U8_T g_rxBuffer[RF_PACKET_SIZE];   /* RF Rx buffer */
 
extern volatile U8_T Su8RfRxBitCnt 	;  //接收数据位
extern volatile U32_T Su32RfRxData 	;  //数据缓冲区
extern volatile U8_T bRfDecodeOk     ;  //解码是否成功标志位
extern volatile U8_T bRfRecStartFlag ;  //接收同步码成功标志位   
extern volatile U8_T bRfRecCodeOk    ;	

//函数声明
unsigned char user_create (unsigned char *p1, unsigned short int len);
void Rf433SoftDecode(void);
void Recevie433DecodeScan(void)  ;

#endif

3.实际处理

      解码函数定时50us中断中

 if((GPT0->MISR&GPT_INT_PEND)==GPT_INT_PEND)        //End of cycle interrupt 
    {
        GPT0->ICR = GPT_INT_PEND;//定时器中断        
        //50us
        Recevie433DecodeScan();            //433接收处理。

   }

解码成功后,进行逻辑处理。

void rf_pro(void)
{
    if(bRfRecCodeOk)				  //解码成功,接收到的命令按照命令进行解析。
	{
		bRfRecCodeOk = 0;
		//
		Su8RfRxTimeCnt= 0;
		bRfDecodeOk = 1;			//成功标志,间隔一段时间去解码。
        switch(g_rxBuffer[1])
        {
            case 0x01:
                buzzer_en(1);        //蜂鸣器响1次 
                break;
            casw 0x02:
                break;
        }

    }
    if(bRfDecodeOk)            	 //110ms后再次接受遥控码,可减小时间
    {
		Su8RfRxTimeCnt++;
		if(Su8RfRxTimeCnt >= 200)  //1ms   
		{
			Su8RfRxTimeCnt = 0;
			bRfDecodeOk = 0; 	
			//bRfRecCodeOk = 0;					
		}
	}
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
)EV1527中断法解码 ① 设定定时器中断时间,设定为 80us,80us 进入中断进行解码。具体中断时间多少由自己 软件设定,但是中断时间不能太大。 ② 设定同步码解码范围,同步码定为 5.6ms - 16ms。进入中断判断到低电平,低电平判断 一直累加 Count_Lead++,累积低电平的采集时间,判断到高电平,就判断此时 Count_Lead 的值是否在 70 跟 200之间。(备注:5.6ms/80us=70 16ms/80us=200)。 ③ 引导头通过进入数据判断,刚开始是数据高电平,累积高电平的时间 Count_Data_Hi++, 当判断到低电平时候,判断 Count_Data_Hi 是否在 80us -2.4ms 之间。这里还没进行数据 0 跟 1 的区分,先把 Count_Data_Hi 的值保存在 Hi_Cnt 里面。 (备注:80us/80us=1 2.4ms/80us=30)。 ④ 高电平判断通过,开始判断低电平,累积低电平的时间 Count_Data_lo++,当判断到高电 平时候,判断 Count_Data_Lo 是否在 80us -2.4ms 之间。这里还没进行数据 0 跟 1 的区分, 先把 Count_Data_Lo 的值保存在 Lo_Cnt 里面。 (备注:80us/80us=1 2.4ms/80us=30)。 ⑤ 对 0 跟 1 进行区分,把 24bit 数据整理成三个 byte,存在数组 RfData[0],RfData[1], RfData[2]数组里面。 ⑥ 进行相应功能码的操作。 具体解码方法参考例子程序,因为不同的震荡电阻,1527 出来的编码长度不同,例子 程序是参考 1 lck=100us 波形来做的。具体时间参数可以根据自己的 1527 发射实际长度来 编写。
好的,根据您的要求,以下是一个基于APT32F1023单片机的C语言程序,实现串口1发送AT+RST指令给ESP01S模块,接收ESP01S模块回传的数据并解析。 ```c #include "apt32f102x.h" #include "stdio.h" #include "string.h" #define RX_BUFFER_SIZE 100 char rx_buffer[RX_BUFFER_SIZE]; uint8_t rx_index = 0; void UART1_Init(uint32_t baudrate) { // 使能UART1时钟 CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}}; CKCUClock.Bit.UART1 = 1; CKCU_PeripClockConfig(CKCUClock, ENABLE); // 配置UART1引脚 GPIO_ConfigTypeDef GPIO_InitStructure = {0}; GPIO_InitStructure.GPIO_Pin = GPIO_Pins_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置UART1 UART_InitTypeDef UART_InitStructure = {0}; UART_InitStructure.UART_BaudRate = baudrate; UART_InitStructure.UART_WordLength = UART_WordLength_8b; UART_InitStructure.UART_StopBits = UART_StopBits_1; UART_InitStructure.UART_Parity = UART_Parity_No; UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None; UART_Init(UART1, &UART_InitStructure); // 使能UART1接收中断 UART_INTConfig(UART1, UART_INT_RXDR, ENABLE); NVIC_EnableIRQ(UART1_IRQn); // 使能UART1 UART_Cmd(UART1, ENABLE); } void UART1_SendString(char *str) { while (*str) { while (UART_GetFlagStatus(UART1, UART_FLAG_TBE) == RESET); UART_SendData(UART1, *str++); } } void UART1_IRQHandler(void) { if (UART_GetFlagStatus(UART1, UART_FLAG_RXDR) == SET) { char data = UART_ReceiveData(UART1); if (data == '\n' || data == '\r') { rx_buffer[rx_index] = '\0'; rx_index = 0; printf("Received: %s\n", rx_buffer); } else { if (rx_index < RX_BUFFER_SIZE - 1) { rx_buffer[rx_index++] = data; } } } } int main(void) { // 初始化UART1 UART1_Init(115200); // 发送AT+RST指令 UART1_SendString("AT+RST\r\n"); // 主循环 while (1) { // 在这里添加您的代码,解析ESP01S模块回传的数据 } } ``` 在该程序中,我们首先定义了一个接收缓冲区 `rx_buffer` 和一个接收缓冲区的索引 `rx_index`,用于存储从UART1接收到的数据。 然后,我们定义了三个函数 `UART1_Init`、`UART1_SendString` 和 `UART1_IRQHandler`。 函数 `UART1_Init` 用于初始化UART1,包括使能UART1时钟、配置UART1引脚、配置UART1、使能UART1接收中断和使能UART1。 函数 `UART1_SendString` 用于向UART1发送字符串。 函数 `UART1_IRQHandler` 是UART1的中断处理函数,每当UART1接收到一个字符时,中断服务程序会将接收到的字符存储到接收缓冲区 `rx_buffer` 中,直到接收到回车或换行符,此时我们将接收缓冲区中的内容打印出来。 在主函数中,我们首先调用 `UART1_Init` 函数初始化UART1,然后调用 `UART1_SendString` 函数向ESP01S模块发送AT+RST指令。最后,在主循环中,我们可以添加代码来解析ESP01S模块回传的数据。 请注意,此程序仅提供一个框架,您需要根据您的具体需求来编写代码来解析ESP01S模块回传的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值