学校的一个任务,用51单片机实现蓝牙通信。遇到的问题就是向蓝牙发送信息单片机没有响应,设计上要将从蓝牙获得的信息打印到OLED上。然而,从单片机端向蓝牙传递消息能引发串口中断并打印信息(但这个信息传递的方向不是我想要的啊。)
情况如下图所示
即,从单片机向蓝牙接收端发送的信息引起了中断并达成了预期结果,可是方向不对啊……
main函数主体
#include
#include
#include"oled.h"
#include"uart.h"
#include"bluetooth_show.h"
unsigned char cnt=0,x_stop=0,y_stop=0;
void Timer0Init(void) //1毫秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式 即定时器中断
TMOD |= 0x01; //设置定时器模式
TL0 = 0x66; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0=1; //打开中断开关
TR0=1;
}
//中断一用于按键
void timer0_ISR() interrupt 1
{
TR0=0;
//超时检测
if(start_timer==1)
{
recv_timer0++;
if(recv_timer0>MAV_WAUT)
{
start_timer=0;
recv_flag=1;
recv_timer0=0;
count=recv_cnt;
y_stop=Y_BEGIN+(count-1)/20;
x_stop=X_BEGIN+(count-1)%20*6;
recv_cnt=0;
}
}
if(!keyA6&&!keyA7)//模式切换检测
{
cnt++; //消抖
if(cnt>10&&!keyA6&&!keyA7)
{
cnt=0;
is_change=1; //当同时按下A6A7时,is_change置反,在mian的循环中改变模式
if(mode)mode=0; //模式切换
else mode=1;
while(!keyA6&&!keyA7); //松手等待
}
}
if(!keyA3&&mode==1)//左移闪烁
{
cnt++; //消抖
if(cnt>10&&!keyA3)
{
cnt=0;
if(x!=X_BEGIN||y!=Y_BEGIN)
{
if(y!=Y_BEGIN&&x==X_BEGIN)
{
x=X_END;
y--;
p2--;
}
else
{
p2--;
x=x-6;
}
}
while(!keyA3); //松手等待
}
}
if(!keyA2&&mode==1)//右移闪烁
{
cnt++; //消抖
if(cnt>10&&!keyA2)
{
cnt=0;
if(x!=x_stop||y!=y_stop)
{
if(y!=y_stop&&x==X_END)
{
x=X_BEGIN;
y++;
p2++;
}
else
{
x=x+6;
p2++;
}
}
while(!keyA2); //松手等待
}
}
}
//main函数主体
void main()
{
int s2=3;
ring=0;
//OLED初始化
OLED_Init();
//串口初始化
UartInit();
Timer0Init();
EA=1; ////打开总中断开关
//以下为接收模式
while(1)
{
if(is_change) //修改菜单
{
unsigned char i=0;
is_change=0; //重置菜单改变标志位
OLED_Set_Pos(0,0);
for(;i<128;i++) //清屏
{
OLED_WR_Byte(0x00);
}
switch(mode)
{
case 0:
OLED_ShowString(0,0,"receive mode:",8);
x=X_BEGIN;
y=Y_BEGIN;
break;
case 1:
OLED_ShowString(0,0,"send mode:",8);
break;
}
mess_area();//消息框
}
if(recv_flag==1&&mode==0) //接收模式
{
clr_show_area(); //清除显示区
beep();
delay(1000);
beep();
ring=1;
delay(10000);
ring=0;
delay(1000);
beep();
mess_show(count); //接收消息并显示与OLED上
//copy_buf(); //为什么这里要复制?为发送做准备?
clr_buf(recv_buf); //清除接收数组数据
recv_flag=0;
}
if(is_change==0&&mode==1)
{
mess_send(x,y);
P1=(0xff<if(s2==9) s2=3; //流水灯blingbling闪加持
delay(10000);
P1=0xff;
}
}
}
//串口中断,这部分我不太了解,也许问题出在设置上?
/*
蓝牙透传
波特率9600
数据位8
停止位1
无校验位
*/
#include"oled.h"
#include
#include"uart.h"
unsigned char value = 0;
unsigned char start_timer = 0;
unsigned char recv_buf[MAX_RECV]; //接受到的数据
unsigned char recv_cnt=0;
unsigned char recv_timer0=0;
unsigned char recv_flag=0; //接受标志位,标志是否接收到信息
unsigned char mode =0; //模式标志,0为接收,1为发送
void UartInit(void) //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率 SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xFD; //设置定时初始值
TH1 = 0xFD; //设置定时重载值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //定时器1开始计时
ES=1; //打开串口中断
}
void sendByte(unsigned char dat)
{
/*
SBUF=dat; //接收到的数据放入发送缓存器发送
while(!TI); //等待发送数据完成
*/ //清除发送完成标志位
ES = 0;
SBUF = dat;
while (!TI);
TI = 0; //RI(SCON.0)或TI(SCON.1),串行口中断请求标志。
ES = 1;
}
//中断检测
void uart_ISR() interrupt 4
{
if(RI) //超时检测
{
RI=0; //中断标志位清零
start_timer=1;
if(recv_cnt0)
{
recv_buf[recv_cnt]=SBUF; //从SBUF接收到的数据传递到承载数据的数组
recv_cnt++;
value=SBUF; //数组位数增加
}
recv_timer0=0; //为什么置零?
}
if(TI)
{
TI=0; //外部中断标志位,详情看知识点,//发送中断标志,在方式1,2,3中由内部硬件置1,不清零就会一直发送。
}
}
1.用最简单的例程进行通信(主要是看看没有中断能不能通信),结果是能的,在两边都能收到信息
猜想:是不是连接串口的usb1和蓝牙都用到RXD和TXD,所以当蓝牙收到消息时直接能通过usb反应给串口,在串口助手上就能直接收到。看了看学校给的原理图,好像还真是。(下图右上角usb1原理图)不过我知道这个好像也没用,还是不懂为什么一个能引起中断一个不能……
2.之前看到一个说法,在烧录的时候不要插蓝牙会有影响,那反过来应该也一样?但是我试着不用烧录的usb口供电,蓝牙依旧无法引发串口中断,也没有任何现象。
对蓝牙发送信息时,单片机能接收并反应在OLED上(OLED的事就不必了,只要说说怎么触发反应就好)
无解也是解,只要告诉我为啥无解就行。
你用的是蓝牙串口模块吧?
建议你首先将两个板子直接用串口连起来,而不经过蓝牙串口,看看能否正常显示,如果这样都不能,那通过蓝牙肯定也不行
另外,我看你这个代码容错性很差。通讯相关的程序,必须考虑通讯过程中的各种可能错误。解决办法,既有协议上的,也有算法上的。协议上,通讯过程常有的一个功能就是检测有效信息,你这个代码完全没有做这个。上电的时候很可能有一些杂乱信号被当成串口信号送过去占据了,而你的代码没有对这些做任何处理。
问题解决了吗,你给单片机下载完程序,跟ISP软件就没关系了,就剩下蓝牙USB转串口,就是一个数据收发
额,怎么感觉上面的回答都扯远了。数据都接收到了,不就是OLED显示的问题吗?我看你的代码应该是Mode模式没有切换的原因吧?!
if(!keyA6&&!keyA7)//模式切换检测 这两个按键是不是要同时按下,还是松开可以切换模式的?
{
cnt++; //消抖
if(cnt>10&&!keyA6&&!keyA7)
{
cnt=0;
is_change=1; //当同时按下A6A7时,is_change置反,在mian的循环中改变模式
if(mode)mode=0; //模式切换
else mode=1;
while(!keyA6&&!keyA7); //松手等待
}