|
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; */
}
}
|
|