我用的是89C52RC,加了两个DS18B20和一个DS1302,目的是要测出两路温度,还要在DS1302储存日期和时间。程序中我用LCD1602显示,同时把温度和日期时间通过串口传输到电脑。但是运行后,LCD1602显示正常,传输到电脑的数据就有问题了,都是乱码。我传输的是字符串,波特率9600,串口助手上也都设置使用字符接收,但就是不能得到正确结果。我用SST89E516来仿真,运行过程的数据都是正确的,所有字符都是用ASCII码来表示的,但传输后也不是ASCII码。程序如下:
//用串口把温度、日期和时间发送到电脑上,同时1602显示这些量
#include <reg52.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "18b20.h"
#include "18b20a.h"
#include "1602.h"
#include "delay.h"
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
volatile unsigned char sending;
//DS18B20
bit ReadTempFlag;//定义读时间标志
//DS1302
bit ReadTimeFlag;//定义读时间标志
bit SetFlag; //更新时间标志位
unsigned char idata time_buf2[16];
void Init_Timer0(void);//定时器初始化
void UART_Init(void);
void UART_send_byte(unsigned char dat);
void UART_send_string(unsigned char *buf);
/*------------------------------------------------
串口通讯初始化
------------------------------------------------*/
void UART_Init(void)
{
TMOD=0x20; //定时器T1使用工作方式2
TH1=0xfd; //设置初值
TL1=0xfd;
TR1=1; //开始计时
PCON=0x00; //SMOD=0;
SCON=0x50; //工作方式1,波特率9600bit/s,允许接收
//TI=1;
EA=1;
ES=1;
}
//发送一字节
void UART_send_byte(unsigned char dat)
{
SBUF=dat;
sending=1; //设置发送标志
while(sending); //等待发送完毕
}
//发送字符串
void UART_send_string(unsigned char *buf)
{
while((*buf)!='\0')
{
//UART_send_byte(*buf++);
UART_send_byte(*buf);
buf++;
}
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
static unsigned int num;
TH0=(65536-2000)/256; //重新赋值 2ms
TL0=(65536-2000)%256;
num++;
if(num==50) //大致100ms
{
num=0;
ReadTempFlag=1; //读DS18B20标志位置1
ReadTimeFlag=1; //读DS1302标志位置1
}
}
/*------------------------------------------------
串口中断程序
------------------------------------------------*/
void UART_SER (void) interrupt 4 //串行中断服务程序
{
unsigned char Temp; //定义临时变量
unsigned char i;
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
}
else //发送完一字节数据
{
TI=0;
sending=0; //清正在发送标志
}
}
void main (void)
{
unsigned char idata i;
int idata temp,temp_a;
float idata temperature,temperature_a;
unsigned char idata temp_DS18B20[16],temp_DS1302[16];//定义显示区域临时存储数组
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏
Init_Timer0();
Ds1302_Init();
UART_Init();
Lcd_User_Chr(); //写入自定义字符,这个是18B20中用到的
Ds1302_Read_Time(); //首次读取时间
if((time_buf1[2]+time_buf1[7])==0) //如果所有参数都为0,写入一个初始值
Ds1302_Write_Time();
while (1) //主循环
{
//双DS18B20部分
if(ReadTempFlag==1)
{
ReadTempFlag=0;
temp=ReadTemperature();
temperature=(float)temp*0.0625;
temp_a=ReadTemperature_a();
temperature_a=(float)temp_a*0.0625;
sprintf(temp_DS18B20,"%7.3f %7.3f",temperature,temperature_a);//打印温度值
LCD_Write_String(0,0,temp_DS18B20);//两个温度值都显示在第一行
UART_send_string(temp_DS18B20);
}
//DS1302部分
if(SetFlag) //如果接收到串口信息则更新时钟,发送过来的数据格式是2015032313382402
{
for(i=0;i<8;i++)
{
time_buf1[i]=time_buf2[2*i]*10+time_buf2[2*i+1]; //此时time_buf1格式为{20,15,03,23,13,38,24,02}
}//数据整合,如2个数 1和5整合成15
Ds1302_Write_Time();
SetFlag=0; //时钟信息更新后标志位清零
}
if(ReadTimeFlag==1)
{
ReadTimeFlag=0;
Ds1302_Read_Time();
//修改一下,将日期时间显示在1602的第二行,格式是150324 10:51:16
sprintf(temp_DS1302,"%02d%02d%02d %02d:%02d:%02d",(int)time_buf1[1],(int)time_buf1[2],(int)time_buf1[3],(int)time_buf1[4],(int)time_buf1[5],(int)time_buf1[6]);
LCD_Write_String(0,1,temp_DS1302);//显示在第二行
UART_send_string(temp_DS1302);
}
}
}
小妹已经被这个程序折腾好几天了,求大神给我指点迷津吧。
------解决思路----------------------
电脑串口设置对吗?要设数据帧长度,起始停止位,波特率。