双机通信发送温度16位数据出现问题。高手帮忙看看
我是用A单片机采集18b20温度数据然后通过串口把温度数据发给B单片机,两边都通过lcd1602液晶显示。通过串口助手调试时A机发送正常,然后B机接受就出现问题。A机是把温度16位数据分成8位分两次发的,接收时是在原封不动和在一起进行处理。但是就是出现问题了,麻烦高手帮忙看看。所有程序贴过来有五百多行,为方便大家看,我只把串口及主程序贴过来。不重要的全部略去。[code]
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
int temper=0;
int temp=1;
/*------------------------------------------------
串口初始化函数
-----------------------------------------------*/
void UART_Init (void)
{
SCON = 0x50; //REN=1允许串行接受状态,串口工作模式2
TMOD|= 0x20; //定时器工作方式2
//PCON|= 0x80; //波特率提高一倍
TH1 = 0xFd; // //baud*2 /* 波特率4800、数据位8、停止位1。效验位无 (11.0592M)
TL1 = 0xFd;
TR1 = 1; //开启定时器1
ES = 1; //开串口中断
EA = 1; // 开总中断
}
/*-----------------------------------------------
名称:串口通信
频率;11.0592
内容:主机程序,给从机发送信息
-----------------------------------------------*/
void Uart_send(uchar send_dat)
{
SBUF=send_dat;
while(!TI);
TI=0;
}
void Uart_scan()
{
// uchar temperl,temperh;
// temperl=temper/256;
// temperh=temper*256;
if(temp!=temper)
{
// SBUF =temper; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
// SBUF =temper/256;
// while(!TI); // 等特数据传送 (TI发送中断标志)
// TI = 0; // 清除数据传送标志
// SBUF =temper%256;
// while(!TI); // 等特数据传送 (TI发送中断标志)
// TI = 0;
Uart_send(temper/256);
Uart_send(temper%256);
temp=temper;
}
// DelayMs(1000);
// SBUF =temper%256;
// while(!TI);
// TI=0;
// P1=(temper)%100/10;
// DelayMs(1000);
}
/*------------------------------------------------
主函数
-----------------------------------------------*/
void main()
{
uchar *dat,*dat1;
dat="overload:";
dat1="Fixed:";
LCD_Init(); //液晶初始化
LCD_Clear(); //液晶清屏
UART_Init();
while(1)
{
alarm(); //报警函数扫描
keyscan(); //按键函数扫描
temper=read_temp();
//DelayMs(10000);
Uart_scan();
if(temper<0) //用于检测负温度值,去掉不影响程序
{
LCD_Write_String(0,0,'-');
temper=-temper;
}
else
LCD_Write_String(0,0,dat); //第一行显示overload
LCD_Write_Char(9,0,(temper>>4)%100/10+0x30); //显示温度十位,加0x30转成asscii码
LCD_Write_Char(10,0,(temper>>4)%10+0x30); //显示温度个位
LCD_Write_Char(11,0,'.'); //显示小数点
LCD_Write_Char(12,0,((temper&0x000f)*62.5)/100+0x30); //显示小数点后的值
LCD_Write_String(0,1,dat1); //显示fixed
LCD_Write_Char(6,1,fixdat/10+0x30); //显示固定温度十位
LCD_Write_Char(7,1,fixdat%10+0x30); //显示固定温度个位
}
}
B机代码
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>
int temper=0;
uchar fixdat=28;
int temph;
int templ;
uchar i=0;
uchar rcv_dat[2];
//uchar temp;
void Uart_Init(void)
{
SCON = 0x50; /* SCON: 模式 1, 8-bit UART, 使能接收 */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 0xFd; /* TH1: reload value for 9600 baud @ 11.0592MHz */
TL1 = 0xFd;
TR1 = 1; /* TR1: timer 1 run */
EA = 1; /*打开总中断*/
ES = 1; /*打开串口中断*/
}
/******************************************************************/
/* 串口中断程序 */
/******************************************************************/
void UART_SER (void) interrupt 4 //串行中断服务程序
{
// unsigned char Temp; //定义临时变量
uchar j;
if(RI) //判断是接收中断产生
{
rcv_dat[j++]=SBUF;
RI=0;
if(j>=2)
j=0;
}
temph=rcv_dat[0];
temph=temph<<8;
templ=rcv_dat[1];
temper=temph+templ;
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)
{
uchar *dat,*dat1;
dat="overload:";
dat1="Fixed:";
Uart_Init();
LCD_Init(); //液晶初始化
LCD_Clear(); //液晶清屏
//cov_tempter();
while (1)
{
DelayMs(200);
LCD_Write_String(0,0,dat); //第一行显示overload
LCD_Write_Char(9,0,(temper>>4)%100/10+0x30); //显示温度十位,加0x30转成asscii码
LCD_Write_Char(10,0,(temper>>4)%10+0x30); //显示温度个位
LCD_Write_Char(11,0,'.'); //显示小数点
LCD_Write_Char(12,0,((temper&0x000f)*62.5)/100+0x30); //显示小数点后的值
LCD_Write_String(0,1,dat1); //显示fixed
LCD_Write_Char(6,1,fixdat/10+0x30); //显示固定温度十位
LCD_Write_Char(7,1,fixdat%10+0x30);//显示固定温度个位
}
------解决方案--------------------
现象是什么?
void UART_SER (void) interrupt 4 //串行中断服务程序 { // unsigned char Temp; //定义临时变量 uchar j;//!!!!这里不要用局部变量,看你的思路是通过j来确认收到的是高还是低字节,但定义成局部变量完全//不对 if(RI) //判断是接收中断产生 { rcv_dat[j++]=SBUF; RI=0; if(j>=2) j=0; } temph=rcv_dat[0]; temph=temph<<8; templ=rcv_dat[1]; temper=temph+templ; }
[解决办法]
太混乱了,改成全局的也不对,需要修改下
[code=C/C++]
uchar scnt=0;
void UART_SER(void) interrupt 4
{
if(RI)
{
rcv_dat[scnt]=SBUF;
scnt++;
if(scnt>=2)
{
temper=0;
temper|=rcv_dat[0];
temper<<=8;
temper|=rcv_dat[1];
scnt=0;
}
RI=0;
}
}