微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > DS18B20和ADC0809电压采集程序合在一起显示就不对了?

DS18B20和ADC0809电压采集程序合在一起显示就不对了?

时间:10-02 整理:3721RD 点击:
我这有DS18B20温度程序 和ADC0809电压采集程序 我想合到一起 在LCD1602第一行显示温度 第2行显示电压 怎么合都合不到一块!求大神来指点。
程序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;

}


是什么问题呢?

具体呢?我对程序也不是懂

只能正常显示一个 另一个乱码

欧克 我试试

欧克 我试试.。。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top