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; //head
Rm433Info.FirstSegTime = TX_HEAD_FIRST_SEG_TIME; //Time/50 //所有时间 4.5ms
Rm433Info.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++];
// MSB
Rm433Info.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
{
// MSB
Rm433Info.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++];
// MSB
Rm433Info.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; //1ms
Radio_Send_FixedLen(); //RF发送函数
}
}
调用发送函数,按键触发调用一次发送。
rf_send_value(0x01,0x0A); //模式1 等级10
修正:空闲时将发送脚设置为低电平。如果DATA是高电平时功耗异常,到达20ma.
case RF_IDLE: //空闲,等待使能
if(Rm433Info.TxEnable)
{
Rm433Info.State = RF_HEAD; //head
Rm433Info.FirstSegTime = TX_HEAD_FIRST_SEG_TIME; //Time/50 //所有时间 4.5ms
Rm433Info.AllTime = TX_HEAD_ALL_FRAME_TIME; //(Seg1+Seg2)/50
Rm433Info.TxCnt = 0;
Rm433Info.NowByteIndex = 0; //Buf[0]
Rm433Info.NowBitIndex = 0;
Rm433Info.TxTimesCnt = 0; //次数:和重复段不同点
}
else
{
TX_GpioPIN_L ;
}
break;