1.硬件电路--CMT2110A
需要注意:发射端MCU写数据的频率要匹配,如果MCU发送中时间最小脉宽是1MS,那么它的发送需要设置为1kbps。
通过华普微USB调试工具+PC软件RFPDK_V1.55查看设置是否正确。
2.RF433发送
用到的发送和接收代码来自“无线433发送接收数据测试程序原理,有杂波解决方案_433无线协议-CSDN博客”,我在此基础做了修改方便识别。
发送波形:
空闲电平为 高
引导码 高1ms 低4ms
逻辑1 高电平时间2ms 低电平时间 1ms
逻辑0 高电平时间1ms 低电平时间 2ms
重复间隔时间 5ms
3.代码示例
rf.h文件
#ifndef _RF_H_
#define _RF_H_#include "apt32f102.h"
#define RF_DATA_INIT() {GPIO_Init(GPIOA0,8,0),GPIO_Write_High(GPIOA0,8);}
#define TX_GpioPIN_H GPIO_Write_High(GPIOA0,8)
#define TX_GpioPIN_L GPIO_Write_Low(GPIOA0,8)enum ENUM_RemoteNecStep
{RF_IDLE,RF_REPEATED,RF_HEAD,RF_SDATA,RF_SDATA_H
}; //状态表#define TX_FIRST_SEG_TIME_H 2 //逻辑1的高电平时间
#define TX_FIRST_SEG_TIME_L 1 //逻辑1的低电平时间#define TX_HEAD_FIRST_SEG_TIME 1 //引导码的低电平时间,基准时间1ms
#define TX_HEAD_ALL_FRAME_TIME 4 #define TX_REPEAT_INTERVAL_TIME 5 //Tx重复间隔时间#define TX_REPEAT_FIRST_SEG_TIME 1 //重复第一段时间
#define TX_REPEAT_ALL_FRAME_TIME 4 //Tx重复所有帧时间#define TX_ONE_BIT_ALL_FRAME_TIME TX_FIRST_SEG_TIME_L+TX_FIRST_SEG_TIME_H //每帧时间Tx 1位 逻辑1或逻辑0的总时间typedef struct
{unsigned char State; //步骤unsigned char TxEnable:1; //发送使能位置 //可判断首字节是否为空替代unsigned char TxTimes; //发送次数 //可宏替代unsigned char TxTimesCnt; //次数计数器unsigned char TxBufLength; //数据长度 //可宏替代unsigned char TxCnt; //高低电平计数、间隔时间计数unsigned char NowByte; //现在字节unsigned char NowByteIndex; //现在字节索引 unsigned char NowBit:1;unsigned char NowBitIndex; unsigned char FirstSegTime; //第一段时间unsigned char AllTime; //总时间
}RemoteNecObject_t;extern RemoteNecObject_t Rm433Info;#endif
rf.c
#include "rf.h"#define RF_PACKET_SIZE 4//6 /* Define the payload size here */#define TX_433_REPEAT_TIMES 3 //发送次数
u8 TxBuf[RF_PACKET_SIZE];RemoteNecObject_t Rm433Info =
{0,// unsigned char State; //步骤0,// unsigned char TxEnable:1; //发送使能位置TX_433_REPEAT_TIMES,// unsigned char TxTimes; //发送次数 //可宏替代0,// unsigned char TxTimesCnt; //次数计数器4,// unsigned char TxBufLength; //数据长度 //可宏替代0,// unsigned char TxCnt; //发送计数器 0,// unsigned char NowByte;0,// unsigned char NowByteIndex;0,// unsigned char NowBit:1;0,// unsigned char NowBitIndex;0,// unsigned char FirstSegTime; //第一段时间0,// unsigned char AllTime; //一位总时间
};static unsigned char user_create (unsigned char *p1, unsigned short int len)
{unsigned char sum = 0; //用于存储累加和的值,初始值为0。for(;len > 0; len--) {sum += *p1++;}//return sum;return (sum & 0xFF); // 只保留最低的8位
}void rf_send_value(U8_T command,U8_T value)
{if(Rm433Info.TxEnable == 0 ) //发送是否繁忙{//memset(TxBuf,0x00,sizeof(TxBuf));TxBuf[0] = 0x55;TxBuf[1] = command;TxBuf[2] = value;TxBuf[3] = user_create(TxBuf,3); //校验值;Rm433Info.State = RF_IDLE; //发送状态Rm433Info.TxEnable = 1; //使能发送}
}void Radio_Send_FixedLen(void)
{switch(Rm433Info.State){case RF_IDLE: //空闲,等待使能if(Rm433Info.TxEnable){Rm433Info.State = RF_HEAD; //headRm433Info.FirstSegTime = TX_HEAD_FIRST_SEG_TIME; //Time/50 //所有时间 4.5msRm433Info.AllTime = TX_HEAD_ALL_FRAME_TIME; //(Seg1+Seg2)/50 Rm433Info.TxCnt = 0;Rm433Info.NowByteIndex = 0; //Buf[0]Rm433Info.NowBitIndex = 0;Rm433Info.TxTimesCnt = 0; //次数:和重复段不同点}break;case RF_REPEATED: // 重复码TX_GpioPIN_H; if(++Rm433Info.TxCnt >= TX_REPEAT_INTERVAL_TIME) //间隔时间{Rm433Info.TxCnt = 0;//Rm433Info.State = RF_HEAD;Rm433Info.FirstSegTime = TX_REPEAT_FIRST_SEG_TIME; //Time/50 此时间根据实际需求设置 Rm433Info.AllTime = TX_REPEAT_ALL_FRAME_TIME; //(Seg1+Seg2)/50 //所有时间Rm433Info.TxCnt = 0;Rm433Info.NowByteIndex = 0; //Buf[0]Rm433Info.NowBitIndex = 0;//}break;case RF_HEAD: // 头码//设置第一段时间,总时间,发送一位使能,等待发送完成if(Rm433Info.TxCnt < Rm433Info.FirstSegTime){TX_GpioPIN_H ; // 预设}else{TX_GpioPIN_L ;}if(++Rm433Info.TxCnt > Rm433Info.AllTime){Rm433Info.TxCnt = 0;//TX_GpioPIN = 1; //此处会占用一个周期 /******************/Rm433Info.State = RF_SDATA; //发送完头码发送数据域Rm433Info.NowByte = TxBuf[Rm433Info.NowByteIndex++];// MSBRm433Info.NowBit = (Rm433Info.NowByte&(0x80>>(Rm433Info.NowBitIndex++)))?1:0;// LSB --- NowBit = (NowByte&(0x01<<NowBitIndex++))?1:0;if(Rm433Info.NowBit) //第一个bit牵引{Rm433Info.FirstSegTime = TX_FIRST_SEG_TIME_H;}else{Rm433Info.FirstSegTime = TX_FIRST_SEG_TIME_L;}Rm433Info.AllTime = TX_ONE_BIT_ALL_FRAME_TIME; //之后不用改,Tx 每帧时间1位}break;case RF_SDATA:if(Rm433Info.TxCnt < Rm433Info.FirstSegTime){TX_GpioPIN_H; // 预设}else{TX_GpioPIN_L;}if(++Rm433Info.TxCnt >= Rm433Info.AllTime) //发送完 1 bit{Rm433Info.TxCnt = 0;//TX_GpioPIN = 1; //Alltime -1 此行省略//此处会占用一个周期 /******************/if(Rm433Info.NowBitIndex <= 0x07) //判断是否发送完 1 byte{// MSBRm433Info.NowBit = (Rm433Info.NowByte&(0x80>>(Rm433Info.NowBitIndex++)))?1:0;// LSB --- Rm433Info.NowBit = (Rm433Info.NowByte&(0x01<<Rm433Info.NowBitIndex++))?1:0;if(Rm433Info.NowBit){Rm433Info.FirstSegTime = TX_FIRST_SEG_TIME_H; //TX_LOGIC1_LOW_TIME}else{Rm433Info.FirstSegTime = TX_FIRST_SEG_TIME_L; //TX_LOGIC0_LOW_TIME}}else //Next Byte{Rm433Info.NowBitIndex = 0;if(Rm433Info.NowByteIndex < Rm433Info.TxBufLength)//判断是否发送完数据域{Rm433Info.NowByte = TxBuf[Rm433Info.NowByteIndex++];// MSBRm433Info.NowBit = (Rm433Info.NowByte&(0x80>>(Rm433Info.NowBitIndex++)))?1:0;// LSB --- Rm433Info.NowBit = (Rm433Info.NowByte&(0x01<<Rm433Info.NowBitIndex++))?1:0;if(Rm433Info.NowBit){Rm433Info.FirstSegTime = TX_FIRST_SEG_TIME_H;}else{Rm433Info.FirstSegTime = TX_FIRST_SEG_TIME_L;}} else{Rm433Info.TxTimesCnt++;if(Rm433Info.TxTimesCnt < Rm433Info.TxTimes) //次数{Rm433Info.State = RF_REPEATED; //发送重复码Rm433Info.TxCnt = 0;}else{//一次发送完成Rm433Info.State = RF_SDATA_H;}}}}//设置第一段时间,总时间,发送一位使能,等待发送完成,直到第N字节发送完成break;case RF_SDATA_H:Rm433Info.TxTimesCnt = 0;Rm433Info.State = RF_IDLE; //空闲,等待使能//TX_GpioPIN_L; TX_GpioPIN_H; Rm433Info.TxEnable = 0; //一次发送完成break;default:break;}
}
4.具体应用
GPT配置1ms 定时
void GPT0IntHandler(void)
{// ISR content ...if((GPT0->MISR&GPT_INT_PEND)==GPT_INT_PEND) //End of cycle interrupt {GPT0->ICR = GPT_INT_PEND;//定时器中断bFixTimer = 1; //1msRadio_Send_FixedLen(); //RF发送函数 }
}
调用发送函数,按键触发调用一次发送。
rf_send_value(0x01,0x0A); //模式1 等级10