先说一下这个通信协议的数据格式,这个图片是我在手册里截的。
/*
@Description 输出高低电平按EV1527协议
@mode 逻辑0或1
*/
void S433_SendBit(u8 mode){
if(mode==)
{
PEout()=;
SysTick\_Delay\_Us(\*);
PEout()=;
SysTick\_Delay\_Us();
}else if(mode==)
{
PEout()=;
SysTick\_Delay\_Us();
PEout()=;
SysTick\_Delay\_Us(\*);
}else{
debug\_led(, LED\_TOGGLE);
}
}
/*
@Description 同步脉冲(或叫引导)
*/
//同步脉冲 4:124
void Sync_Pulse(){
PEout()=;
SysTick\_Delay\_Us();
PEout()=;
SysTick\_Delay\_Us(\*);
}
/*
@Description 发送码函数调用
@num 24位二进制的 10进制数
*/
//对发送过来的10进制数进行处理 , 根据需求可以更改
void S433_Send(u32 num){
u8 i;
u32 result=,temp;
temp = num;
Sync_Pulse();
while(result){
i = temp%; //对十进制数取余 结果等于最低位二进制数
S433\_SendBit(i);
temp = temp/;//除二取整
result--;
}
}
接收要比发送复杂得多,思路就是
通过触发外部中断处理函数,来检测数据,每触发一次上升或下降沿,记一下时间,根据时间长度来判段杂波,同步波还是数据波,接收关键在于判断。
下面一段是一些值的初始化,和IO引脚的初始化
static volatile unsigned long long rx433_previous_time = ;//上一次进入中断时间
static volatile unsigned char Sync_Pulse_begin =;//检测同步脉冲完整性 1是同步脉冲
static volatile unsigned char rx433_begin= ;//同步脉冲开启标志1开启 0没开
static volatile unsigned short interval_previous_time=;//上一个间隔时间
////////////
static volatile u8 Rx433Cnt=;
static volatile u8 Rx433bit[]={};
static volatile u8 rxbit=;
static volatile u8 firstbit=;
static volatile u32 Rx433[]={};
///////////
//对管脚初始化 参考普通IO管脚用通信
void S433_SR_Init(){
GPIO\_InitTypeDef GPIO\_InitStructure;
EXTI\_InitTypeDef EXTI\_InitStructure;
NVIC\_InitTypeDef NVIC\_InitStructure;
RCC\_APB2PeriphClockCmd(RCC\_APB2Periph\_GPIOE,ENABLE); //使能GPIOE时钟
//E9使能
GPIO\_InitStructure.GPIO\_Pin = GPIO\_Pin\_9;
GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_Out\_PP;
GPIO\_InitStructure.GPIO\_Speed = GPIO\_Speed\_50MHz;
GPIO\_Init(GPIOE, &GPIO\_InitStructure);
GPIO\_ResetBits(GPIOE, GPIO\_Pin\_9);// 引脚拉低
//接收 E7
RCC\_APB2PeriphClockCmd(RCC\_APB2Periph\_AFIO,ENABLE);
GPIO\_InitStructure.GPIO\_Pin = GPIO\_Pin\_7;
GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_IPD; //输入为低
GPIO\_InitStructure.GPIO\_Speed = GPIO\_Speed\_50MHz;
GPIO\_Init(GPIOE, &GPIO\_InitStructure);
GPIO\_EXTILineConfig(GPIO\_PortSourceGPIOE,GPIO\_PinSource7);
EXTI\_InitStructure.EXTI\_Line=EXTI\_Line7;
EXTI\_InitStructure.EXTI\_Mode=EXTI\_Mode\_Interrupt;
EXTI\_InitStructure.EXTI\_Trigger= EXTI\_Trigger\_Rising\_Falling;
EXTI\_InitStructure.EXTI\_LineCmd=ENABLE;
EXTI\_Init(&EXTI\_InitStructure);
NVIC\_InitStructure.NVIC\_IRQChannel=EXTI9\_5\_IRQn;
NVIC\_InitStructure.NVIC\_IRQChannelPreemptionPriority=;
NVIC\_InitStructure.NVIC\_IRQChannelSubPriority=;
NVIC\_InitStructure.NVIC\_IRQChannelCmd=ENABLE;
NVIC\_Init(&NVIC\_InitStructure);
}
是否是同步波判断,以及检测发送完成度
/*
@Description 判断是否是同步脉冲
@pre 之前时间段数
@now 现在时间段数
@return rebit开启同步 success同步成功 synerror 不是同步脉冲
*/
u8 Sync_PulseRx(u8 pre,u8 now){
if(!PEin()){//每次下降沿开始测
Sync\_Pulse\_begin=;//开始检测同步脉冲
}else if(Sync\_Pulse\_begin==&&(pre==)&&(now==)){//满足条件则判断出时间脉冲
Sync\_Pulse\_begin=;//同步成功将同步码关掉
rx433\_begin=;//正式开始传输数据
rxbit=;//将数据位数清零
firstbit=;//置一等待下个跳变正式开始
return success;
}else{
Sync\_Pulse\_begin=;//不是脉冲置0
return synerror;
}
return rxbit;
}
/*
@Description 判断逻辑0和1
@pre 之前时间段数
@now 现在时间段数
@return rxerror 接收超位
*/
u8 RX433_Bit(u8 pre,u8 now){
if(firstbit==){
firstbit=;//此步骤防止引导完成后直接进入此函数
}else if(rx433_begin==&&PEin()){//上升沿检测
if(rxbit>){//能加到24 说明一帧数据获取到了
rxbit=;//归零
rx433\_begin=;//归零 及下一组做准备
}
if(now==&&pre==){//逻辑0
Rx433bit\[rxbit\]=;
rxbit++;
}else if(now==&&pre==){//逻辑1
Rx433bit\[rxbit\]=;
rxbit++;
}else{
//跑飞
rx433\_begin=;
rxbit=;
return rxerror;
}
return rxbit-;
}
return ;
}
外部中断处理函数,常常被触发,因为接收各种杂波,但进入不了关键的处理函数。
//先判断同步脉冲
//如果是同步脉冲,begin开启判断数据接收并判断情况情况
//如果数据接收位超过预期24位,数据位数接收超量(状态)
//如果从一半开始接收,无视这一段,从下一段开始
void EXTI9_5_IRQHandler(void){
if(EXTI\_GetITStatus(EXTI\_Line7)!=RESET)
{
unsigned char skip\_index = ;//这次几个数据位
unsigned char skip\_pervious\_index=;//之前几个数据位
unsigned long long now\_time=sys\_micros();//此刻时间
unsigned short interval\_time = now\_time - rx433\_previous\_time;//计算一个电平状态持续的时长
rx433\_previous\_time = now\_time;//为下次计算时长做准备
skip\_index = (interval\_time/);//得出某个电平持续时长的倍数 计算出几段高或低电平
skip\_pervious\_index=(interval\_previous\_time/);//同上 不过是前一次的
Sync\_PulseRx(skip\_pervious\_index,skip\_index);//同步脉冲
RX433\_Bit(skip\_pervious\_index,skip\_index);//数据位
if(interval\_time<){
interval\_previous\_time = interval\_time;
}else{
interval\_previous\_time = ;
}
EXTI\_ClearITPendingBit(EXTI\_Line7);//清除中断挂起标志位
}
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章