大家好,有一个关于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的分支 我不太清楚你如何接受 手机的 1和2 数据 如果是通过一个函数接收的话 假设是 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;
就是这
回一下私信