大家好,有一个关于51单片机的问题想请教一下,51开发版外接了一HC06蓝牙模块,然后再手机串口软件上发送1想让程序直接跳到step3,发送二直接跳到step5这样写程序可以吗

大家好,有一个关于51单片机的问题想请教一下,51开发版外接了一HC06蓝牙模块,然后再手机串口软件上发送1想让程序直接跳到step3,发送二直接跳到step5,这样写程序可以吗?

不可以的话希望可以给出修改意见,开发板晶振是12MHZ的,咨询了一下用11.0592的比较好,自己焊接的话怎么保证焊好后晶振是1.0592的呢?

是个不太懂的小白,希望解答的时候可以基础一些

number是我定义的一个全局变量,初值是0

主函数: void main()

{

   AS=0; //关锁

LcdWriteCom(0x01); //清屏

delay(1000);

LcdInit();   //初始化LCD屏

delay(1000);

Step=0;  //初值

Step5=0;   

Error_Num=0x00; //错误次数初值为0


UsartInit();

while(number==0)

{   

key_num=KeyDown();          //读取输入值


switch(Step)

{

case 0:

{Step_0();break;}

case 1:

{Step_1();break;}

case 2:

{Step_2();break;}

case 3:

{Step_3();break;}

case 4:

{Step_4();break;}

case 5:

{Step_5();break;}

case 6:

{Step_6();break;}

  

}


}

if(number==1)

{

Step_3();

}

else if(number==2)

{

Step_5();

}

}



中断:

void UsartInit()

{

  TMOD=0x20;

  TH1=0xF3;

  TL1=0xF3;

  PCON=0x80;

  TR1=1;

  SCON=0x50;

  ES=1;

  EA=1;

  TI=0;

  RI=0;

}


void ustart() interrupt 4 

{

 u8 receive_data;

  EA = 0;

 if(RI) //当硬件接收到一个数据时,RI会置1

{

RI = 0;

receive_data = SBUF;//接收到的数据

   if(receive_data==0x31)

{

number=1 ;

}

else if(receive_data==0x32)

{

    number=2;

    } 

  

 

}


EA = 1;



需求并不难,但是你代码有点乱.

思路可以是这样

你Step 都没有被赋值,程序肯定只能走swicth为0的分支

我不太清楚你如何接受 手机的 12 数据

如果是通过一个函数接收的话 假设是 readKey();
int key = readKey();
switch(key){
  case 1:
    // do something
  case 2:
    // do something
}

比方说 你有一个界面,是步骤1-5的界面
可以这么写
int exit = 0;
int step = 0;
while(!exit){
  if(step==1){
    // do something
    step++;
  }else if(step ==2){
    // do something
    step++;
  }
  ..
  else if(step ==5)
  {
    // do someting;
    exit = 1;
  }
}
通俗易懂的
int exit = 0;
int step = 0;
// 从手机读取数据
int key = readKey();
switch(key){
  case 1:
    // do something
    step = 3;
    break;
  case 2:
    // do something
    step = 5;
    break;
}
while(!exit){
  if(step==1){
    // do something
    step++;
  }else if(step ==2){
    // do something
    step++;
  }
  ..
  else if(step ==5)
  {
    // do someting;
    exit = 1;
  }
}

整个程序是现在KEIL4里的

step初值都有啊在主函数靠前边的位置,我这个程序是想实现一个蓝牙智能电子密码锁的功能,不加蓝牙的话只有电子门锁,开锁、密码修改功能都能实现,已经在开发板上走过一遍了。

只看while(number==0)是无蓝牙部分 key_num=KeyDown()是读取开发板矩阵按键的值进行选择开锁还是其他

单片机中断这块没学明白,一直不太清楚是怎么个工作过程,我上边程序的思路是:主函数里有中断初始化,如果接受了数据是不是直接就进入了void ustart() interrupt 4 函数,然后就会有number值的改变,之后回到主函数根据number值运行相应程序(step-3是开锁,5是修改密码,另外问了卖蓝牙的店家他说手机发送1,接受到的还是1,是透传的)

您的程序我还没仔细看,先去吃个饭回来仔细看看在交流啊,

不好意思,你源码里Step 只赋值了 一个 零, 程序只会走 0的分支...除非 你Step_0函数里 有对Step进行改变。

是的,开始确实是从0分之走,之后的函数里都会改变step的值,就类似下边的

void Step_0()

{

LcdInit();

    ShowString(0x00,"  WELCOME!  ");              // 第一行显示 WELCOME!  

while(KeyDown()==0xff)

Step=1;                 // 有按键按下进入下一步  

    

}


void Step_1() //显示出‘开锁’ ‘改密码’两个选项

{

LcdWriteCom(0x01);            //清屏

 ShowString(0x00,"Unlock");     //1602第一行显示unlock

ShowString(0x0f,"<");        //1602第一行最后显示 <            

 ShowString(0x10,"Change Password");  // 1602第二行显示Change Password 

ShowString(0x1f," ");                                                          

 Step=2;                            //

}

.............................

看了您的程序,我的理解是矩阵按键走while(!exit),手机程序走key....但一遍程序过后不久没有没法进入while(!exit)了吗

不用手机开锁的时候,一直扫描按键,手机开锁时进入中断进行处理,另外我问题的主要就是,蓝牙与51单片机txd RXD连接,然后怎么将蓝牙接收到的数据用串口中断进行处理?

蓝牙接受到的数据是直接就传给单片机了吗

是的,开始确实是从0分之走,之后的函数里都会改变step的值,就类似下边的

void Step_0()

{

LcdInit();

    ShowString(0x00,"  WELCOME!  ");              // 第一行显示 WELCOME!  

while(KeyDown()==0xff)

Step=1;                 // 有按键按下进入下一步  

    

}


void Step_1() //显示出‘开锁’ ‘改密码’两个选项

{

LcdWriteCom(0x01);            //清屏

 ShowString(0x00,"Unlock");     //1602第一行显示unlock

ShowString(0x0f,"<");        //1602第一行最后显示 <            

 ShowString(0x10,"Change Password");  // 1602第二行显示Change Password 

ShowString(0x1f," ");                                                          

 Step=2;                            //

}

.............................

看了您的程序,我的理解是矩阵按键走while(!exit),手机程序走key....但一遍程序过后不久没有没法进入while(!exit)了吗

不用手机开锁的时候,一直扫描按键,手机开锁时进入中断进行处理,另外我问题的主要就是,蓝牙与51单片机txd RXD连接,然后怎么将蓝牙接收到的数据用串口中断进行处理?

蓝牙接受到的数据是直接就传给单片机了吗

void ustart() interrupt 4 这个函数中写了的
receive_data = SBUF;//接收到的数据
SBUF应该是个宏定义,SUBF函数只返回一个二进制的字符,如果你能看到SBUF接收源码的话,才能知道它数据是怎么截断的。
receive_data就是你要的数据呀。
你贴的代码并不全,肯定有地方是做接收数据的。有地方是调用界面的。

我把全部代码发上来,您有空帮忙看一下吗,

你贴吧。。

#include "reg52.h"   //此文件中定义了单片机的一些特殊功能寄存器

#include "lcd.h"

#include "key.h"

#define u16 unsigned int //对数据类型进行声明定义

#define u8 unsigned char

sbit AS=P2^2;        //继电器


u8 pw_num=0,Error_Num,PassWord_Length=6; //Error_Num错误次数 PassWord_Length规定密码长度 pw_num实际输入密码长度

u8 PASSWORD[]={6,6,6,6,6,6,0,0,0,0};//初始密

u8 INPUT_PW_Tab[10];           //实际输入密码数组

u8 key_num,Step,Step5;  

u8 number=0;


bit result_flag,Input_suc_flag;      //Input_suc_flag密码输入完成标志 result_flag密码比对标志

bit List1=0;

bit flag_REC =0;


void Step_0();            

void Step_1();

void Step_2();

void Step_3();

void Step_4();  

void Step_5();

  void Step5_0();

  void Step5_1();

  void Step5_2();

  void Step5_3();

  void Step5_4();

  void Step5_5();

void Step_6();


void CipherComparison(); //密码比对函数

void input_password(bit m); //密码输入函数

void UsartInit(); //中断初始化





void main()

{

   AS=0; //关锁

LcdWriteCom(0x01); //清屏

delay(1000);

LcdInit();   //初始化LCD屏

delay(1000);

Step=0;  //初值

Step5=0;   

Error_Num=0x00; //错误次数初值为0


UsartInit();

while(number==0)

{   

key_num=KeyDown();          //读取输入值


switch(Step)

{

case 0:

{Step_0();break;}

case 1:

{Step_1();break;}

case 2:

{Step_2();break;}

case 3:

{Step_3();break;}

case 4:

{Step_4();break;}

case 5:

{Step_5();break;}

case 6:

{Step_6();break;}

  

}


}

if(number==1)

{

Step_3();

}

else if(number==2)

{

Step_5();

}

}



void Step_0()

{

LcdInit();

    ShowString(0x00,"  WELCOME!  ");              // 第一行显示 WELCOME!  

while(KeyDown()==0xff)

Step=1;                 // 有按键按下进入下一步  

    

}


void Step_1() //显示出‘开锁’ ‘改密码’两个选项

{

LcdWriteCom(0x01);            //清屏

 ShowString(0x00,"Unlock");     //1602第一行显示unlock

ShowString(0x0f,"<");        //1602第一行最后显示 <            

 ShowString(0x10,"Change Password");  // 1602第二行显示Change Password 

ShowString(0x1f," ");                                                          

 Step=2;                            //

}


void Step_2() //选择是开锁还是修改密码

{


if(key_num!=0x0b) //确认键没按下

{

if(key_num==0x01)           //1键按下

{

List1=~List1;      //??按位取反 List1=1       //Change Password

if(List1==0)

{                          

ShowString(0x0f,"<");              // Unlock      <

ShowString(0x1f," ");              // Change Password  

}

else

{

ShowString(0x0f," ");              // Unlock       

ShowString(0x1f,"<");              // Change Password  <

}

}

}

else                              //确认键按下

{

if(List1==0){Step=3;}

else    {Step=5;List1=0;}   

}

}


void Step_3()        //(开锁) 

{

Step=4;

              pw_num=0;

LcdInit();

ShowString(0x00,"Pass Word: ");

         

}


void Step_4()      //输入密码                   

{

  input_password(0);                       //输入密码并以*显示

  if(Input_suc_flag==1)

  {Step=6;

Input_suc_flag=0;}                


                     

}


void Step_5()        //修改密码

{

switch(Step5)

{

case 0: {Step5_0();} break;

case 1: {Step5_1();} break;

case 2: {Step5_2();} break;

case 3: {Step5_3();} break;

 case 4: {Step5_4();} break;

case 5: {Step5_5();} break;


}

}


void Step_6()  

{

CipherComparison();                //密码比对

if(result_flag==1)               

{

LcdInit();

ShowString(0x00,"  WELCOME!");

AS=1;                     //开继电器

delay(60000);

delay(60000);

AS=0;                     //关继电器

}

else                        //密码错误

{

LcdInit();

ShowString(0x00,"Error 01!"); //显示错误 01

delay(6000000);

}

Step=0;


}


/****************************************************************************************

密码输入函数

密码长度:pw_num

密码输入完成标志:Input_suc_flag

*****************************************************************************************/


void Step5_0()      

{

LcdWriteCom(0x01); //清屏

 ShowString (0x00,"Input PassWord:");   

 Step5=1;

 pw_num=0;

}

void Step5_1()   //输入密码      

{

input_password(0);        

if(Input_suc_flag==1)        //密码输入完成

{

Step5=2;         //

Input_suc_flag=0;  

}

}

void Step5_2()    

{

   CipherComparison();        //密码比对

  Step5=3;

}

void Step5_3()    //

{

  if(result_flag==0)     //    密码错误

{

if(Error_Num<3)       //输出错误次数小于3

{

Error_Num++;

LcdInit();

ShowString (0x00,"Error 01");

delay(1000000);

Step5=0;

}

else             //密码错误次数大于3

{ LcdInit();

ShowString (0x00,"Error>3");

delay(1000000);

Error_Num=0; ///////将错误次数清零方便下次记录

Step=0;

}

}

else         //密码正确

{

LcdInit();

ShowString (0x00,"New PassWord:");

pw_num=0;

Step5=4;

}

}

void Step5_4()

{

input_password(1);        //输入密码并显示

if(Input_suc_flag==1)         //输入完成

Step5=5;

Input_suc_flag=0;

LcdWriteCom(0x01); //清屏

   ShowString (0x00," OK!");

}

}

void Step5_5()

{

unsigned char j;

PassWord_Length=pw_num;             //读取输入密码长度

for(j=0;j<PassWord_Length;j++)     

{

PASSWORD[j]=INPUT_PW_Tab[j];         //读取密码

  }

Step5=0;

Step=0;

}



///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void input_password(bit m)

{

unsigned char j;

if(key_num!=0x0b)                   //确认键没有按下

{

if(key_num<0x0a)                //1-9按下

{

INPUT_PW_Tab[pw_num]=key_num;        //保存至输入密码数组

pw_num=pw_num+1;              

LcdWriteCom(0xc0);

for(j=0;j<pw_num;j++)

{

if(m==0) {LcdWriteData('*'); }            //密码隐藏

else   {LcdWriteData(INPUT_PW_Tab[j]+0x30);}  //显示密码

}

}

if(key_num==0x0a)               //返回键按下

{

if(pw_num!=0) {pw_num=pw_num-1;}

else     {Step=0;}

 

          LcdWriteCom(0xc0);

for(j=0;j<pw_num;j++)

{

if(m==0) {LcdWriteData('*'); }          //密码隐藏

else   {LcdWriteData(INPUT_PW_Tab[j]+0x30);}  //显示密码

  }

LcdWriteData(' '); 

}

else             //ok键按下

 {

if(pw_num==0)   

{

Step=0;

 LcdWriteCom(0x01);

 ShowString (0x00,"Error 02!");

delay(600000);

}

else {

Input_suc_flag=1;

}

}         

}

/*******************************************************

        密码比对

********************************************************/

void CipherComparison()

u8 i,j=0;


if(PassWord_Length==pw_num)            //密码长度比对

{  

for(i=0;i<PassWord_Length;i++)        

{

if(PASSWORD[i]!=INPUT_PW_Tab[i])

{

result_flag=0;

break;           //密码错误

}

else

{

result_flag=1;             //密码正确

}

 INPUT_PW_Tab[i]=0XFF;          //清除密码缓存数组

}

}

else //输入长度与正确密码长度不同直接返回错误的消息

{result_flag=0;}

}

void UsartInit()

{

  TMOD=0x20;

  TH1=0xFA;

  TL1=0xFA;

  PCON=0x80;

  TR1=1;

  SCON=0x50;

  ES=1;

  EA=1;

  TI=0;

  RI=0;

}


void ustart() interrupt 4 

{

 u8 receive_data;

 //uchar i;

  EA = 0;

 if(RI) //当硬件接收到一个数据时,RI会置1

{

RI = 0;

receive_data = SBUF;//接收到的数据

number=receive_data;

    

}

EA = 1;


RI = 0;

receive_data = SBUF;//接收到的数据

number=receive_data;

就是这

回一下私信