首先这是一篇血泪文章,当你看到这篇文章的时候,笔者已经失败了,首先笔者选用了51单片机进行编写,51单片机的一个串口难以进行相应的验证,这是其一;其二,使用AT+CWLAP调回WIFI信息的时候,你会发现字符串的数量过于庞大,验证时间过长;其三RSSI值影响太大了,可以说基本没有精度。下面我会分享我的流程,如果你有幸成功的话,可以在下面留言。同时这篇文章包含字符串的接收和发送等知识,包含中断,超时接收,如何检验帧头帧尾等内容,希望对大家有所帮助。
1,字符串的发送
void SendChar(char Char)//这是发送单个字符的
{
SBUF=Char;
while(!TI);
TI=0;
}
void SendString(char *p)//发送字符串
{
while(*p!='\0')
{
SendChar(*p);
p++;
}
}
这个地方笔者不做太多的解释,主要就是利用TI和SBUF,进行单个字符的发送,而字符串的发送则是调用指针的类型然后进行字符串的发送。
2串口的初始化函数(这一部分可以在ISP中进行寻找)
void UsartInit()
{
SCON=0X50; //???????1
TMOD=0X20; //?????????2
//PCON=0X80; //?????
TH1=0xfd; //????????,??????9600?
TL1=0xfd;
ES=1; //??????
EA=1; //?????
TR1=1; //?????
}
不做太多解释
3利用中断进行字符串的接收(本人使用了帧头检验,帧尾检验以及超时接收等)
void Usart() interrupt 4//中断
{
if(RI)//当检验到数据时
{
RI = 0;//归0,下次检验
start_timer = 1;//定时计数器置1
temp = SBUF;//这里是定义了一个中间变量,将SBUF的内容传给中间变量,然后对中间变量进行检验
if(temp != 0x63)//这里本人是用的字符串“c”使用的是16进制,因为单片机接收数据接受的是16进制
{
recv_buf[recv_cnt] = temp;//这里讲接收到的一帧放入数组
recv_cnt++;//recv_cnt进行累加,方便下一次
if(recv_cnt > MAX_LEN)//当recv_cnt大于规定的最大字符串时,不再进行接收
{
recv_cnt = MAX_LEN;
}
}
else
{
usart_receive_flag = 1;//这是串口接收字符的标志位
recv_length = 47;//我设置的最大接收区为47(51单片机最多接收128个字符)
//recv_cnt = 0;
}
recv_timer_cnt = 0;//定时器计数归0
}
}
void Timer0Init(void) //1??@11.0592MHz
{
//AUXR &= 0x7F; //?????12T??
TMOD &= 0xF0; //???????
TL0 = 0x66; //??????
TH0 = 0xFC; //??????
TF0 = 0; //??TF0??
ET0 = 1;
TR0 = 1; //???0????
}
void timer0_ISR() interrupt 1
{
TR0 = 0;
if(start_timer == 1)
{
recv_timer_cnt++;
if(recv_timer_cnt > MAX_REV_TIME)
{
recv_timer_cnt =0;
recv_cnt = 0;
usart_receive_flag = 1;
}
}
TL0 = 0x66; //??????
TH0 = 0xFC; //??????
TR0 = 1;
}
4.清楚数组的数据也就是清除缓存
void clr_recvbuffer(unsigned char *buf)
{
unsigned char i;
for(i=0;i<MAX_LEN;i++)
{
buf[i] = 0;
}
}
这里很容易理解,就是利用i来清空每一个数组
5串口中断服务函数
void uart_service(unsigned char *buf)
{
unsigned char recv_move_index ;//recv_move_index是为了简单,其实这个可以随便定义
if (usart_receive_flag)//当字符串接收完全后会变为1,然后进入
{
usart_receive_flag = 0;//标志位置0
start_timer = 0;//定时计数器标志位置0
while((recv_cnt >= 40) && (recv_move_index <= recv_cnt))//recv_cnt为接收的字符串长度
{
if( (buf[recv_move_index+0] == 0X42) && (buf[recv_move_index+1] == 0X31))//这里就是本人的数据位检验,使用的是“B1”采用的是他们的16进制
{
a = buf[recv_move_index+5]-48;
b = buf[recv_move_index+6]-48;
RSSI1 = a*10+b;
if(RSSI1 < 40)
{
LED=0;
//SendString("<\r\n");
//Delay1000ms();
//SendString("AT+CWLAP\r\n");
clr_recvbuffer(recv_buf);
}
if(RSSI1 >=40)
{
LED=1;
//SendString(">\r\n");
//Delay1000ms();
//SendString("AT+CWLAP\r\n");
//SendString("AT+RST\r\n");
clr_recvbuffer(recv_buf);//清除数组缓存
}
break;
}
recv_move_index++;//这里进行累加是为了进行以后的验证
}
recv_cnt = 0;//归0
//clr_recvbuffer(recv_buf);
}
}
6关于计算RSSI值
a = buf[recv_move_index+5]-48;//这里是讲字符型数据转化为整数型数据
b = buf[recv_move_index+6]-48;
RSSI1 = a*10+b;//计算RSSI值
7关于发送AT+CWLAP的返回内容
注意开头有隐藏的AT+CWLAP指令
AT+CWLAP
+CWLAP:(0,"B1",-32,"ca:c9:a3:78:b6:0b",1,-6,0)
+CWLAP:(4,"feika102",-36,"8c:a6:df:fc:b5:1f",1,30,0)
+CWLAP:(5,"HBU-1X",-79,"d4:61:fe:fd:e7:70",1,-6,0)
+CWLAP:(0,"HBU-WEB",-81,"d4:61:fe:fd:e7:71",1,-4,0)
+CWLAP:(5,"HBU-1X",-66,"d4:61:fe:fe:07:d0",1,-6,0)
+CWLAP:(0,"HBU-WEB",-64,"d4:61:fe:fe:07:d1",1,-6,0)
+CWLAP:(3,"123456789",-40,"66:64:d7:b9:87:eb",5,28,0)
+CWLAP:(4,"ZJBGS",-79,"ec:26:ca:67:ba:89",6,8,0)
+CWLAP:(5,"HBU-1X",-67,"d4:61:fe:fe:0b:90",6,0,0)
+CWLAP:(0,"HBU-WEB",-68,"d4:61:fe:fe:0b:91",6,0,0)
+CWLAP:(5,"HBU-1X",-77,"d4:61:fe:fe:0c:50",1,0,0)
+CWLAP:(4,"kexie203",-40,"5c:02:14:cd:0a:28",11,26,0)
+CWLAP:(0,"HBU-WEB",-77,"d4:61:fe:fe:0c:51",1,0,0)
+CWLAP:(5,"HBU-1X",-85,"d4:61:fe:fe:7b:d0",1,-4,0)
+CWLAP:(0,"HBU-WEB",-85,"d4:61:fe:fe:7b:d1",1,-4,0)
ok
8关于两个蓝牙的设置(一个充当蓝牙一个充当热点)
配置如下:
热点设置
AT+CWSAP?//查询当前AP模式下的参数,返回+CWSAP:,,,;
AT+CWMODE=2设置模式为AP(服务器模式)
AT+CWSAP="B1","aaaaaa",1,0//打开热点设置
AT+CWLIF//查询已经连接的设备ID
蓝牙设置
AT+CWJAP?//查询当前选择的AP,返回+CWJAP:OK
AT+CWMODE=1设置模式为SATION模式
AT+CWJAP="B1","aaaaaa"//连接上述热点
AT+CWLAP//查询连接如下
蓝牙模式
AT+CWMODE=3//两种模式兼顾
AT+CWMODE?//当前模式查询
AT+CIOBAUD=9600//修改为9600波特率
发送所有命令时都需要回车进行换行
9算法(本人也是在CSDN看到的)
算法方面
其中d为距离,单位是m。
RSSI为rssi信号强度,为负数。
A为距离探测设备1m时的rssi值的绝对值,最佳范围在45-49之间。
n为环境衰减因子,需要测试矫正,最佳范围在3.25-4.5之间。
abs()取绝对值
d=10^((ABS(RSSI)-A)/(10*n))
int a = 45
float n = 3.25
RSSI记得取绝对值
距离==10^((abs(RSSI)-A)/(10*n))
使用数学函数记得引用
#include <math.h>
本人全部代码如下 看不懂代码的可以去B站(单片机应用实践篇——单片机串行口定时中断实现超时接收一串数据的编程实现_哔哩哔哩_bilibili)这位老师讲解的很详细还是希望大家能够用心理解
/**************************************************************************************
* ?????? *
????:?????????????,???????9600,???????????????????
***************************************************************************************/
#include "reg52.h" //????????????????????
#include "string.h" //???????
#include <stdio.h>
#include <stdlib.h>
#include <intrins.h>
void clr_recvbuffer(unsigned char *buf);
void uart_service(unsigned char *buf);
void Delay500ms() ;
void Delay2000ms();
void Delay4000ms();
void Delay1000ms();
void Delay5000ms();
void Timer0Init(void);
sbit LED = P2^6;
#define MAX_LEN 47 //??????????
#define MAX_REV_TIME 5
unsigned char temp ;
unsigned char recv_length;
unsigned char recv_buf[MAX_LEN];
unsigned char recv_cnt;
unsigned char usart_receive_flag = 0;
unsigned char start_timer = 0;
unsigned char recv_timer_cnt;
//unsigned char RSSI =0;
int a ;
int b ;
int RSSI1 ;
typedef unsigned int u16; //???????????
typedef unsigned char u8;
//u8 receiveData[47]; //????,????????//????,????4????????
/*******************************************************************************
* ??? :UsartInit()
* ???? :????
* ?? : ?
* ?? : ?
*******************************************************************************/
void UsartInit()
{
SCON=0X50; //???????1
TMOD=0X20; //?????????2
//PCON=0X80; //?????
TH1=0xfd; //????????,??????9600?
TL1=0xfd;
ES=1; //??????
EA=1; //?????
TR1=1; //?????
}
//??????
void SendChar(char Char)
{
SBUF=Char;
while(!TI);
TI=0;
}
//???????
void SendString(char *p)
{
while(*p!='\0')
{
SendChar(*p);
p++;
}
}
/*******************************************************************************
* ? ? ? : main
* ???? : ???
* ? ? : ?
* ? ? : ?
*******************************************************************************/
void main()
{
LED = 0;
//SendString("AT+CWLAP\r\n");
Timer0Init;
UsartInit(); // ?????
EA=1;
//SendString("AT+CWLAP\r\n");
//SendString("AT+RST\r\n");
//Delay1000ms();
while(1)
{
SendString("AT+CWLAP\r\n");
Delay4000ms();
//Delay1000ms();
//SendString("AT+CWLAP\r\n");
uart_service(recv_buf);
//18 11 12
/*if(usart_receive_flag==1 && rxDataBuff[i+7]==','&&rxDataBuff[i]=='B'&&rxDataBuff[i+1]=='1')
{
usart_receive_flag=0;
rxDataBuff[0]='\0';
a = rxDataBuff[i+5]-48;
b = rxDataBuff[i+6]-48;
RSSI1 = a*10+b;
SendString("dadawda\r\n");
if(RSSI1 < 100)
{
LED = 1;
SendString("LED=1???\r\n");
// usart_receive_flag=0;
}
/*if(RSSI1 >= 27)
{
LED = 1;
SendString("LED=0???\r\n");
}*/
}
}
/*******************************************************************************
* ??? : Usart() interrupt 4
* ???? : ????????
* ?? : ?
* ?? : ?
*******************************************************************************/
void uart_service(unsigned char *buf)
{
unsigned char recv_move_index ;
if (usart_receive_flag)
{
usart_receive_flag = 0;
start_timer = 0;
while((recv_cnt >= 40) && (recv_move_index <= recv_cnt))
{
if( (buf[recv_move_index+0] == 0X42) && (buf[recv_move_index+1] == 0X31))//A TÑéÖ¤
{
a = buf[recv_move_index+5]-48;
b = buf[recv_move_index+6]-48;
RSSI1 = a*10+b;
if(RSSI1 < 40)
{
LED=0;
//SendString("<\r\n");
//Delay1000ms();
//SendString("AT+CWLAP\r\n");
clr_recvbuffer(recv_buf);
}
if(RSSI1 >=40)
{
LED=1;
//SendString(">\r\n");
//Delay1000ms();
//SendString("AT+CWLAP\r\n");
//SendString("AT+RST\r\n");
clr_recvbuffer(recv_buf);
}
break;
}
recv_move_index++;
}
recv_cnt = 0;
//clr_recvbuffer(recv_buf);
}
}
void clr_recvbuffer(unsigned char *buf)
{
unsigned char i;
for(i=0;i<MAX_LEN;i++)
{
buf[i] = 0;
}
}
void Timer0Init(void) //1??@11.0592MHz
{
//AUXR &= 0x7F; //?????12T??
TMOD &= 0xF0; //???????
TL0 = 0x66; //??????
TH0 = 0xFC; //??????
TF0 = 0; //??TF0??
ET0 = 1;
TR0 = 1; //???0????
}
void timer0_ISR() interrupt 1
{
TR0 = 0;
if(start_timer == 1)
{
recv_timer_cnt++;
if(recv_timer_cnt > MAX_REV_TIME)
{
recv_timer_cnt =0;
recv_cnt = 0;
usart_receive_flag = 1;
}
}
TL0 = 0x66; //??????
TH0 = 0xFC; //??????
TR0 = 1;
}
void Usart() interrupt 4
{
if(RI)
{
RI = 0;
start_timer = 1;
temp = SBUF;
if(temp != 0x63)//????c
{
recv_buf[recv_cnt] = temp;
recv_cnt++;
if(recv_cnt > MAX_LEN)
{
recv_cnt = MAX_LEN;
}
}
else
{
usart_receive_flag = 1;
recv_length = 47;
//recv_cnt = 0;
}
recv_timer_cnt = 0;//
}
}
void Delay4000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 169;
j = 24;
k = 59;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay5000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 211;
j = 30;
k = 11;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 43;
j = 6;
k = 203;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay2000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay500ms() //????,??500ms
{
unsigned char i, j, k;
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);//do while??
} while (--i);
}