DS18B20和ADC0809电压采集程序合在一起显示就不对了?
程序1:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar table[]={" temp:"};
/********IO引脚定义**********/
sbit rs=P1^0;
sbit rw=P1^1;
sbit en=P1^2;
sbit dq=P3^2;
sbit beep=P1^5;
uchar num;
uint tempwarn,d=0,h=0;
void delay(uint n) //延时程序
{
while(n>0)n--;
}
void write_com(uchar com) //液晶写命令程序
{
rs=0; //等0输入命令
en=0; //液晶使能信号初始化
P0=com; //把com参数,液晶的命令值送到P0口
delay(100); //延时,按照液晶的时序图的要求
en=1; //使能信号,0到1表示上升沿打开可以写命令数据到液晶里
delay(100);
en=0; //使能信号回复
}
void write_data(uchar date) //液晶写数据程序
{
rs=1; //等1表示输入数据en=0;
P0=date; //把date参数,液晶的数据送到P0口
delay(100);
en=1;
delay(100);
en=0;
}
void init() //液晶初始化程序
{
en=0;
write_com(0x38); //设置16X2显示,5X7点阵,8位数据口
write_com(0x0c); //设置开显示,不显示光标
write_com(0x06); //写一个字符后地址指针加1
write_com(0x01); //显示清0,数据指针清0
}
void
Writebyte(uchar dat)//DS18B20温度芯片的写字节程序
{
uchar j;
for(j=0;j<8;j++)
{
dq=0;
dq=dat&0x01;
delay(5);
dq=1;
dat>>=1;
}
}
uchar Readbyte(void)//DS18B20温度芯片读字节程序
{
uchar i,dat=0;
for(i=0;i<8;i++)
{
dq=0;
dat>>=1;
dq=1;
if(dq==1)
dat|=0x80;
delay(4);
}
return dat;
}
void initds18b20(void)//温度芯片初始化程序
{
uchar x=0;
dq=1;
delay(8);
dq=0;
delay(80);
dq=1;
delay(14);
x=dq;
delay(20);
}
void Readtemp(void)//读温度程序
{
initds18b20();
Writebyte(0xcc);
Writebyte(0x44);
initds18b20();
Writebyte(0xcc);
Writebyte(0xbe);
d=Readbyte(); //温度信号的低8位数据函数
h=Readbyte(); //温度信号的高8位数据函数
}
convert() //温度信号处理程序,把温度信号数据值转换为液晶显示
{
uint temp,tmp;
float tt;
tmp=d; //低8位数据给tmp
temp=h; //高8位数据给temp
temp<<=8; //高8位左移8位
temp|=d; //高低8位数据或起来再赋给temp
if((h&0x80)!=0) //高8位h&10000000是否等0,不等0表示负多少度
{
table[7]='-'; //把-赋给液晶数组的第8个元素,表示-号在第8位,1602一行有16个字符
temp=temp-1;
temp=~temp;
}
else
table[7]='+';
temp>>=4;
table[8]=(temp/100)+'0';//液晶第9位字符为温度的百位数,例如120度的1
table[9]=(temp/10)%10+'0'; //液晶第10位字符为温度的十位数,例如120度的2
table[10]=(temp%10)+'0'; //液晶第9位字符为温度的个位数,例如120度的0
tmp=tmp&0x0f; //低位温度提取小数数据
tt=tmp*0.0625; //小数部分数据转换
table[11]='.'; //显示小数点
table[12]=((uchar)(tt*10))%10+'0';//小数点后面的小数数字
tempwarn=temp;
return tempwarn;//温度值返回
}
void warn(uint tempwarn)//温度报警程序
{
if(tempwarn<=16) //返回的值是温度的值,如果温度小于20度就报警并且启动风冷设备
{
beep=0;
delay(5000);//蜂鸣器的声音响的时间
beep=1;
delay(50000); //蜂鸣器的声音不响的时间
}
else if(tempwarn>=25)//如果温度大于25度并且启动报警
{
beep=0;
delay(5000);
beep=1;
delay(50000);
}
}
void main()
{
rw=0; //rw直接置0,应该在液晶初始化前,否则断电后再通电就不能显示,切记!
init(); //液晶初始化函数
while(1) //大循环,不断检测和更新温度
{
Readtemp();
convert();
warn(tempwarn);
write_com(0x80); //液晶的第一行开始地址
for(num=0;num<15;num++)//显示16位数据,后面的几位没有用到就写不到16,以免后面的几位会出现一个随机数据显示乱码
{
write_data(table[num]);//液晶需要显示的内容
}
}
}
程序2:
//利用51单片机控制ADC0809读取外部模拟信号(只使用了一个通道,0809上的ABC三个引脚接地,模拟信号由in0进入),在LCD1602显示当前的信号数值
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define DATE_IO P0//P0口并行传输数据
sbit RS=P1^0;//LCD1602寄存器选择端
sbit RW=P1^1;//LCD1602读写控制端
sbit E=P1^2; //LCD1602使能信号端
sbit oe=P1^3;//0809输出允许控制端
sbit eoc=P1^4;//0809转换结束信号端
sbit clk=P1^5;//为0809提供时钟
sbit st=P1^6;//与0809的ale相连,一起启动a/d转换
uchar getdata=0;//转换后得到数据
uchar qian,bai,shi,ge;
uchar code table1[]="0123456789.v";
void initdingshi();//初始化定时器0
void adc0809();//启动0809转换,并得到转换后的结果
void initdingshi();//初始化LCD1602
//**********************延时函数*****************************************
void delay_us(unsigned int n)
{
if(n==0)
return;
while(--n);
}
void delay_ms(uint i)
{
unsigned char a,b;
for (a=1;a<i;a++)
for(b=1;b;b++);
}
void delay(uint z)
{
uint x,y;
for(x=110;x>0;x--)
for(y=z;y>0;y--);
} //***********************************************************************
//*********************控制LCD1602的函数*******************************
void write_command(uchar come)//写指令函数
{
RS=0;//选择指令寄存器
E=1;//由高电平跳变成低电平时,液晶执行命令 DA
DATE_IO=come;
delay_us(5);
E=0;
RS=1;
}
void write_date(uchar date)//写数据函数
{
RS=1;//选择数据寄存器
E=1;//由高电平跳变成低电平时,液晶执行命令
DATE_IO=date;
delay_us(5);
E=0;
RS=0;
}
//*****************************************************************************
//**************************液晶初始化函数(基本上都是这个模式)*******************
void inityejing()//液晶初始化函数
{
RW=0;//低电平时进行写操作(高电平时进行读操作)
E=0;
write_command(0x38);//设置LCD两行显示,一个数据由5*7点阵表示,数据由8跟线传输
delay_ms(5);
write_command(0x01);//清除屏幕显示
delay_ms(5);
write_command(0x06);//设定输入方式,增量不移位
delay_ms(5);
write_command(0x0c);//开整体显示,关光标,不闪烁
delay_ms(5);
}
//*****************************************************************************
void chufa(uchar chufa)//将各位数字拆开函数
{
bai=(getdata*2)/100;//求百位数字
shi=(getdata*2)%100/10;//求十位数字
ge=(getdata*2)%10;//求各位数字
write_command(0x80);//设置显示地址为LCD第一行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移
write_date(table1[bai]);//第一位显示百位
write_date(table1[10]); //第二位显示小数点
write_date(table1[shi]); //第三位显示十分位
write_date(table1[ge]); //第四位显示百分位
write_date(table1[11]);//显示电压单位'v'
delay(100);//改变数值可以修改数字滚动的速度
}
//**********************已成使用0809的固定格式,拿来即可用*****************
void adc0809()//启动0809转换,并得到转换后的结果
{
st=0;//以下三表达式表示启动A/D转换
st=1;
st=0;
while(!eoc);//等待转换结束
oe=1;//为高电平时,转换的数据输送个单片机
getdata=P2;//从P2引脚读转换后的信息
oe=0;
}
//**************************************************************************
void initdingshi()//初始化定时器0模式2(主要是为了给0809提供时钟)
{
TMOD=0x02;//定时器0的模式2
TH0=0xfb;//定时5us
TL0=0xfb;
TR0=1;//启动定时器0
ET0=1;//开定时器0中断控制位
EA=1;//开总中断
}
void main()
{
inityejing();//调用液晶初始化函数
initdingshi();//初始化定时器0
while(1)//程序一直循环执行0-999的计数
{
adc0809();//启动0809转换,并得到转换后的结果
chufa();//调用将各位数字拆开函数
}
}
void time0() interrupt 1//定时器0中断
{
clk=~clk;
}
是什么问题呢?
具体呢?我对程序也不是懂
只能正常显示一个 另一个乱码
欧克 我试试
欧克 我试试.。。