找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1611|回复: 11
收起左侧

51单片机用蓝牙制作的检测酒精浓度的,现在在1602上可以显示数据但是在手机上显乱码

[复制链接]
ID:291819 发表于 2019-5-17 14:36 | 显示全部楼层 |阅读模式
51单片机制作的检测酒精浓度的,用蓝牙发送检测到的数据到手机APP上,数据在1602上可以正常显示,在APP上显示的是乱码?不知道哪里出错了,请教大神帮帮忙。在串口助手上和APP一样都是乱码,在程序上需要改动哪里,会显示正常数据?下面是程序:
#include<reg52.h>
#include<string.h>
#include <stdio.h>
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={'0','1','2','3','4','5','6','7','8','9'};
uchar code table1[]="ALC warn=90mg/L";                 //初始显示
uchar code table2[]="current=";                                //报警浓度和实测浓度表示
uchar code table3[]="mg/L";
sbit led=P2^6;
sbit beep=P1^3;
sbit lcdrs=P2^5;               //1602液晶的RS脚接在P2.3口上
sbit lcdrw=P2^4;               //1602液晶的RW脚接在P2.4口上
sbit lcden=P2^3;               //1602液晶的E脚接在P2.5口上
sbit SDA=P3^6;                                                         
sbit SCL=P3^7;
int count,t,num;
uchar cur1,cur2,cur3;                               
uint cur_bj=90;                         //CO报警值
unsigned char ADbuf;//设置8位的寄存器用来暂存A/D转换结果
void delay(unsigned int z)
{
        uint i,j;
        for(i=z;i>0;i--)
          for(j=110;j>0;j--);
}

/*******************************延时函数*********************************/
void delayms(unsigned int ms)
{
        unsigned char i=100,j;
        for(;ms;ms--)
        {
                while(--i)
                {
                        j=10;
                        while(--j);
                }
        }
}





/*******************************报警函数*********************************/
void led_warn()                                               
{
        led=~led;
        delay(200);
}
void beep_warn()

{
        beep=~beep;
        delay(200);
}





   /******************************写命令函数********************************/
void write_com(uchar com)
{
         lcdrs=0;
         P0=com;                                //读命令
         delay(1);
         lcden=1;                                //启动脉冲
         delay(1);
         lcden=0;
}
/******************************写数据函数********************************/
void write_data(uchar date)
{
         lcdrs=1;
         P0=date;                                //写命令
         delay(1);
         lcden=1;                                //启动脉冲
         delay(1);
         lcden=0;
}
/******************************LCD初始化*********************************/
void init_1602()
{
         lcden=0;
         write_com(0x38);                        //设置16*2显示;5*7点阵;8位数据接口
         write_com(0x0c);                        //设置开显示,不显示光标
         write_com(0x06);                        //写一个字符后地址指针自动加1
         write_com(0x01);                        //设置清0,数据指针清零
}





void IICstart(void)
{
     SDA=1;                //先将SDA=1,以准备在SCL=1时,将SDA=0
     SCL=1;                //时钟总线拉高
     _nop_();                          //略做延时
     _nop_();                          //略做延时
     SDA=0;                //SCL=1时,将SDA拉低即产生启动信号
     _nop_();                          //略做延时
     _nop_();                          //略做延时
     SCL=0;                //将SCL=0,完成启动信号操作      
}


/*****************************IIC停止信号函数***********************************/
void IICstop(void)
{
     SDA=0;                //先将SDA=0,以准备在SCL=1时,将SDA=1
     SCL=1;                //时钟总线拉高
     _nop_();                          //略做延时
     _nop_();                          //略做延时
     SDA=1;                //SCL=1时,将SDA拉高即产生停止信号
     _nop_();                          //略做延时
     _nop_();                          //略做延时
     SCL=0;                //将SCL=0,完成启动信号操作      
}

/*****************************向IIC总线写入1个字节函数**************************/
void Write1Byte(unsigned char Buf1)
{
     unsigned char k;      //1个字节要分8次写入,需要定义一个寄存器用来计数
     for(k=0;k<8;k++)      //做一个8次的循环,每次写入1位,需要写8次
     {
         if(Buf1&0x80)     //从最高位开始写
         {
             SDA=1;        //如果欲写入数据为1,就将数据线置1
         }
         else
         {
             SDA=0;        //如果欲写入数据为0,就将数据线写0
         }
         _nop_();          //略做延时
         _nop_();          //略做延时
         SCL=1;            //时钟线做一个上升沿,将一位数据写入
         Buf1=Buf1<<1;     //数据左移一位,将下次要写入的位数据移到最高位
         _nop_();          //略做延时
         SCL=0;            //将SCL=0,以准备通过上升沿将数据写入
         _nop_();          //略做延时
     }
     SDA=1;                //将SDA=1,准备读应答信号
     _nop_();              //略做延时
     SCL=1;                //将SCL=1,做个上升沿准备读应答信号
     _nop_();              //略做延时
     _nop_();              //略做延时
     SCL=0;                //将SCL=0,结束应答信号读操作
}

/****************************从IIC总线读入1个字节函数******************************/
unsigned char Read1Byte(void)
{
     unsigned char k;      //1个字节要分8次读出,需要定义一个寄存器用来计数
     unsigned char t=0;    //定义一个寄存器用保存读出数据
     for(k=0;k<8;k++)      //做一个8次的循环,每次读入1位,需要读8次
     {
         t=t<<1;           //数据左移一位,空出最低位以准备保存读入的一位数据
         SDA=1;            //将SDA写1准备读
         SCL=1;            //将SCL=1,做个上升沿准备读一位数据
         _nop_();          //略做延时
         _nop_();          //略做延时
         if(SDA==1)        //读一位数据,并判断
         {
             t=t|0x01;     //如果读入数据为1,就将接收缓冲区最低一位置1
         }
         else
         {
             t=t&0xfe;     //如果读入数据为0,就将接收缓冲区最低一位写0
         }
         SCL=0;            //SCL恢复为0,结束一位数据读操作
         _nop_();          //略做延时
         _nop_();          //略做延时
     }
     return t;             //将读入的一个字节返回
}

/******************************软件模拟IIC向PCF8591指定地址写一个字节函数********************************/
void WritePCF8591(unsigned char Databuf)
{                          //直接调用本函数即可启动PCF8591的D/A转换
    IICstart();            //IIC启动信号

    Write1Byte(0x90);      //发送PCF8591的器件地址和写信号

    Write1Byte(0x40);      //发送器件子地址

    Write1Byte(Databuf);   //发送数据

    IICstop();             //产生IIC停止信号
}


/******************************软件模拟IIC从PCF8563指定地址读一个字节函数************************************/
unsigned char ReadPCF8591(unsigned char Ch)
{                          //直接调用本函数即可从PCF8591的Ch通道读出数据返回
    unsigned char buf;     //定义一个寄存器用来暂存读出的数据
    IICstart();            //IIC启动信号

    Write1Byte(0x90);      //发送PCF8591的器件地址和写信号

    Write1Byte(0x40|Ch);   //发送器件通道参数Ch=0-3

    IICstart();            //IIC启动信号

    Write1Byte(0x91);      //发送PCF8591的器件地址和读信号

    buf=Read1Byte();//读一个字节数据

    IICstop();             //产生IIC停止信号

    return(buf);           //将读出数据返回
}


/******************************显示初始值函数**********************************/
void dis_init()
{
        uchar a,b,c;
        write_com(0x80+0x00);        //初始化显示
         for(a=0;a<15;a++)
         {
                  write_data(table1[a]);
                  delay(1);
         }
        delay(200);
        write_com(0x80+0x40);        //第二行显示酒精浓度表示单位       
         for(b=0;b<8;b++)
         {
                  write_data(table2[b]);
                  delay(1);
         }
                 write_com(0x80+0x4B);        //第二行显示酒精浓度表示单位       
         for(c=0;c<4;c++)
         {
                  write_data(table3[c]);
                  delay(1);
         }

}



/*********************************1602显示浓度数据h和酒精报警程序**************************/
void dis_cur(uint t)
{
  uchar i;
     t=t*100/255;
   i=t/100;
   write_com(0x80+0x48);           //显示浓度百位
   write_data(table[i]);
   cur1=table[i];
  i=t%100/10;

    write_com(0x80+0x49);
        write_data(table[i]);
         cur2=table[i];
  i=t%100%10;
          write_com(0x80+0x4A);           //显示浓度个位
         write_data(table[i]);

         cur3=table[i];


         if(t>cur_bj)
          {          
                led_warn();
            beep_warn();
          }

    else
          {
                led=1;
                beep=1;
          }

}

/*******************************串口初始化********************************/
void  UARTinit()
{
//   TMOD=0X21;
//   SCON=0X40;
  TMOD=0x20;
  PCON=0x00;
  SCON=0x50;
   TH1=0XFF;
   TL1=0XFD;
   TH0=(65536-45872)/256;
   TL0=(65536-45872)%256;
   TR1=1;
   TR0=1;
   EA=1;
   ES=1;
   TI=0;
   ET0=1;
}
/*******************************发送一个字节************************************/
void UART_Send_Byte(unsigned char mydata)       
{
         ES=0;
         TI=0;
         SBUF=mydata;
         while(!TI);
         TI=0;
         ES=1;
}
/****************************发送文本串****************************************/
void UART_Send_Str(char *s)          
{
         int i=0;
         while(s[i]!=0)
         {
                 UART_Send_Byte(s[i]);
                 i++;
         }

}

void T0_time() interrupt 1
{
   count++;
   TH0=(65536-45872)/256;
   TL0=(65536-45872)%256;
           if(count==400)
                {
                 count=0;
                 num=1;
                }

}


main()
{
uchar g,s,b;

//        uchar i = 0;
//          uchar code Buffer[]="0" ;  //所要发送的数据
//          uchar *p;

        led=1;
        beep=1;
        lcdrw=0;                           //确定读操作
        init_1602();                   //初始化LCD1602
        delay(5);
        dis_init();                                //1602显示初始化  
        delay(2000);
        UARTinit();                           //串口初始化

       
          
//          Com_Init();
//          p = Buffer;
        while(1)       
        {
                   ADbuf=ReadPCF8591(0);     //将AIN0通道A/D转换结果暂存在ADbuf
                    dis_cur(ADbuf);        //浓度显示
                  b=ADbuf/100;
                s=ADbuf%100/10;
                g=ADbuf%100%10;
                if(num==1)
                {
                        UART_Send_Byte(g);
                        UART_Send_Byte(s);
                        UART_Send_Byte(b);
                //        UART_Send_Str("hello");
//                UART_Send_Str("ADbuf/100");
//                UART_Send_Str("ADbuf%100/10");
//                UART_Send_Str("ADbuf%100%10");

                }
   /*
                 SBUF = *p ;
            while(!TI){  ;//如果发送完毕,硬件会置位TI
              _nop_();   //此句似乎可以去掉
            }
            TI = 0;  //TI清零
            p++;
            if(*p == '\0')
              break;  */
        }  
}



1602上数据显示正常

1602上数据显示正常

串口助手上显示乱码

串口助手上显示乱码
回复

使用道具 举报

ID:291819 发表于 2019-5-19 14:07 | 显示全部楼层
请各位大神帮帮忙
回复

使用道具 举报

ID:425825 发表于 2019-5-19 20:25 | 显示全部楼层
UART_Send_Byte(g+48);
UART_Send_Byte(s+48);
UART_Send_Byte(b+48);
改成这样试试看吧
回复

使用道具 举报

ID:291819 发表于 2019-5-20 10:44 | 显示全部楼层
来51学习 发表于 2019-5-19 20:25
UART_Send_Byte(g+48);
UART_Send_Byte(s+48);
UART_Send_Byte(b+48);

按照你这样的改了,但是还是显示的是乱码,不知道哪里出错了
回复

使用道具 举报

ID:484435 发表于 2019-5-20 12:23 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:146145 发表于 2019-5-20 13:30 | 显示全部楼层
你可以看一下晶振的大小是否对应 换做11.0592M的尝试一下
回复

使用道具 举报

ID:146145 发表于 2019-5-20 13:31 | 显示全部楼层
11.0592M晶振试一下 我的是这样调过来的
回复

使用道具 举报

ID:291819 发表于 2019-5-22 14:15 | 显示全部楼层
嘟嘟嘟 发表于 2019-5-20 13:31
11.0592M晶振试一下 我的是这样调过来的

我用的就是11.0592的晶振,调不出来。你和我的程序一样吗?我不可以让我看看你的程序
回复

使用道具 举报

ID:291819 发表于 2019-5-22 14:17 | 显示全部楼层
嘟嘟嘟 发表于 2019-5-20 13:31
11.0592M晶振试一下 我的是这样调过来的

我的邮箱是981361331@qq.com,谢谢。
回复

使用道具 举报

ID:553887 发表于 2019-6-15 21:50 | 显示全部楼层
让我看看你的开发板是怎么连接的
回复

使用道具 举报

ID:517466 发表于 2019-6-17 00:32 | 显示全部楼层
1、单片机测的串口波特率要和串口助手使用相同的波特率。
2、你的串口助手中使用TEXT方式接收还是HEX方式接收?你的代码中发送的可是数值啊,不是ASCII码,在串口助手上肯定看不到。0x01是数值,加上0x30后,变成0x31,就是ASCII码的1
3、另外,在发送完数据后,加几个空格以及0x0d,0x0a换行符,避免接收端当成汉字处理。
回复

使用道具 举报

ID:564475 发表于 2019-6-17 13:22 | 显示全部楼层
单片机测的串口波特率要和串口助手使用相同的波特率。 2、你的串口助手中使用TEXT方式接收还是HEX方式接收?你的代码中发送的可是数值啊,不是ASCII码,在串口助手上肯定看不到。0x01是数值,加上0x30后,变成0x31,就是ASCII码的1 3、另外,在发送完数据后,加几个空格以及0x0d,0x0a换行符,避免接收端当成汉字处理。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表