用18B20检测温度,并用显示器显示,但是
仿真图出不来,求大神指教
#include <reg51.h>
# define uchar unsigned char
# define uint unsigned int
uchar data disdata[7];
uchar temp1,temp2;
uchar d;
bit flag; //正负标志位
uint temper; //温度值
sbit DS=P2^4; //74HC595 单
sbit SH_CP=P2^3;
sbit ST_CP=P2^0;
sbit DS1=P2^7; //74HC595级联
sbit SH_CP1=P2^6;
sbit ST_CP1=P2^5;
sbit RS=P1^1; //1602
sbit RW=P1^2;
sbit E=P1^3;
sbit DQ=P1^0; //18B20
sbit SCL=P1^4; //AT24C02
sbit SDA=P1^5;
sbit SID=P1^6; //12864
sbit SCLK=P1^7; //端口定义
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //段选
uchar code table1[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //位选
uchar code text[]={'2','0','1','6','.','0','7','.','0','8'}; //日期 2016.07.08
uchar code text1[]={0x5b,0x3f,0x06,0xfd,0x3f,0x87,0x3f,0x7f,}; //数码管日期 2016.07.08
void delay(uint m) //延时
{
while(m--);
}
void delay1(uchar c) //延时
{
unsigned char a,b;
for(;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
/*********************DS18B20**********************/
init1 (void) /*初始化子程序*/
{
uchar i=0;
DQ=1; //DQ复位
delay(8);
DQ=0; //DQ拉低
delay(80); //精确延时大于480us
DQ=1; //拉高
delay(14);
i=DQ;
delay(20);
}
uchar read_date1() /*读数据子程序*/
{
uchar i;
uchar date=0;
for(i=0;i<8;i++)
{
DQ=0; //给脉冲信号
date>>=1;
DQ=1; //给脉冲信号
if(DQ)
date|=0x80;
delay(4);
}
return (date);
}
write_date1(uchar date) /*写数据子程序*/
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
date>>=1;
DQ=CY;
delay(5);
DQ=1;
}
}
read_temp() /*读温度并转换温度子程序*/
{
init1();
write_date1(0xcc);
write_date1(0x44);
delay(10);
init1();
write_date1(0xcc);
write_date1(0xbe);
temp1=read_temp(); //低位
temp2=read_temp(); //高位
temper=temp2; /*转换温度*/
temper<<=8;
temper=temper|temp1;
if(temper<0x0fff)
flag=0;
else
{
temper=~temper+1;
flag=1;
}
temper=temper*(0.625);//温度值扩大10倍,精确到1位小数
return(temper);
}
/****************AT24C02程序***********************/
void init2 () /*初始化子程序*/
{
SDA=1;
delay(20);
SCL=1;
delay(20);
}
void start () /*开始信号子程序*/
{
SDA=1; //SCL在高电平期间,SDA一个下降沿启动总线
delay(20);
SCL=1;
delay(20);
SDA=0;
delay(20);
}
void respons () /*应答信号子程序*/
{
uchar j;
SCL=1;
delay(20);
while ((SDA=1)&&(j<255)) //一段时间无应答,则不再等待
j++;
SCL=0;
delay(20);
}
void stop () /*停止信号子程序*/
{
SDA=0; //SCL在高电平期间,SDA一个上升沿停止 总线
delay(20);
SCL=1;
delay(20);
SDA=1;
delay(20);
}
void write_date2(uchar date) /*写数据子程序*/
{ //串行发送一个字节,先传最高位
uchar n,temp;
temp=date;
for(n=0;n<8;n++)
{
temp=temp<<1; //左移一位,最高位移入PSW寄存器的CY位
SCL=0;
delay(20);
SDA=CY;
delay(20);
SCL=1;
delay(20);
}
SCL=0;
delay(20);
SDA=1;
delay(20);
}
uchar read_date2() /*读数据子程序*/
{ //串行接收一个字节,先接收最高位
uchar n,k;
SCL=0;
delay(20);
SDA=1;
delay(20);
for(n=0;n<8;n++)
{
SCL=1;
delay(20);
k=(k<<1)|SDA;
SCL=0;
delay(20);
}
return k; //变量k中保存着接收的8位串行数据
}
void write_add(char address,char date) /*写地址子程序*/
{
start();
write_date2(0xa0);
respons ();
write_date2(address);
respons ();
write_date2(date);
respons ();
stop();
}
uchar read_add(char address) /*读地址子程序*/
{
char byte;
start();
write_date2(0xa0);
respons ();
write_date2(address);
respons ();
start();
write_date2(0xa1);
respons ();
byte=read_date2();
stop();
return byte;
}
void temp_save () //温度存入24c02
{
init2();
write_add(2,temper);
}
/****************1602程序***********************/
void write_595(unsigned char Data)
{
SH_CP=0;
ST_CP=1;
for (d=0;d<8;d++)
{
Data=Data<<1;
DS=CY;
SH_CP=1;
delay1(5);
SH_CP=0;
}
ST_CP=0;
delay1(5);
ST_CP=1;
delay1(5);
ST_CP=0 ;
}
void write_com3(unsigned char com)/*写命令子程序*/
{
RS=0;
RW=0;
write_595(com);
delay1(5);
E=1;
delay1(5);
E=0;
}
void write_date3(unsigned char date)/*写数据子程序*/
{
RS=1;
RW=0;
write_595(date);
delay1(5);
E=1;
delay1(5);
E=0;
}
void init3 () /*初始化子程序*/
{
E=0;
delay1(15); //延时较长,可跳过检查忙碌
write_com3(0x38);delay1(5); //显示模式设置
write_com3(0x0c);delay1(5); //开显示 光标不闪烁
write_com3(0x01);delay1(5); //清屏显示
write_com3(0x06);delay1(5); //光标加1
write_com3(0x80);delay1(5); //字符显示首地址
}
void lcd_display(unsigned char *p)//显示
{
while(*p!=' ')
{
write_date3(*p);
p++;
delay1(1);
}
}
void disp()//温度值显示
{
uchar flagdat;
disdata[0]=temper/1000+0x30;//百位数
disdata[1]=temper%1000/100+0x30;//十位数
disdata[2]=temper%100/10+0x30;//个位数
disdata[3]=temper%10+0x30;//小数位
if(flag==0)
flagdat=0x20;//正温度不显示符号
else
flagdat=0x2d;//负温度显示负号:-
if(disdata[0]==0x30)
{
disdata[0]=0x20;//如果百位为0,不显示
if(disdata[1]==0x30)
{
disdata[1]=0x20;//如果百位为0,十位为0也不显示
}
}
write_com3(0xc0);
write_date3(flagdat);//显示符号
write_com3(0xc1);
write_date3(disdata[0]);//显示百位
write_com3(0xc2);
write_date3(disdata[1]);//显示十位
write_com3(0xc3);
write_date3(disdata[2]);//显示个位
write_com3(0xc4);
write_date3(0x2e);//显示小数点
write_com3(0xc5);
write_date3(disdata[3]);//显示小数位
}
void disp1() //1602管显示日期
{
uchar g;
for(g=0;g<10;g++)
{
write_date3(text[g]);
delay(20);
}
}
/****************12864程序***********************/
void w_date4(unsigned char date) /*发送一个字节*/
{
unsigned char e;
for(e=0;e<8;e++)
{
SID=date&0x80; //取出最高位
SCLK=1;
SCLK=0;
date<<=1; //左移
}
}
void write_cd(bit start,uchar onedata) /*写指令或数据子程序*/
{
uchar start_data,Hdata,Ldata;
if(start==0)
start_data=0xf8; //0:写指令
else
start_data=0xfa; //1:写数据
Hdata=onedata&0xf0; //取高四位
Ldata=(onedata<<4)&0xf0; //取低四位
w_date4(start_data); //发送起始信号
delay1(1); //延时是必须的
w_date4(Hdata); //发送高四位
delay1(1); //延时是必须的
w_date4(Ldata); //发送低四位
delay1(1); //延时是必须的
}
void init4() /*LCD字库初始化程序*/
{
delay1(10); //启动等待,等LCD讲入工作状态
write_cd(0,0x30); //8 位介面,基本指令集
write_cd(0,0x0c); //显示打开,光标关,反白关
write_cd(0,0x01); //清屏,将DDRAM的地址计数器归零
delay1(10);
}
void Lcd_pos(uchar x,y) /* 设定显示位置 */
{
uchar pos;
if(x==1)
{x=0x80;}
else if(x==2)
{x=0x90;}
else if(x==3)
{x=0x88;}
else if(x==4)
{x=0x98;}
else
{x=0x80;}
pos=x+y-1;
write_cd(0,pos); // 设置RAM地址
}
/* 在液晶上显示字符串,输入横纵坐标,和字符串名即可 */
void lcd_mesg(uchar x,uchar y,uchar *str) /*显示函数*/
{
Lcd_pos(x,y);
while(*str!=' ')
{
write_cd(1,*str++);
}
}
void display_temp() /*温度显示函数*/
{
temper=read_temp();
disdata[0]=temper/1000+0x30; //将温度值存放在数组中 ,
disdata[1]=(temper%1000)/100+0x30;
disdata[2]=(temper%100)/10+0x30;
write_cd(0,0x88+4); //第三行第5位开始显示
write_cd(1,disdata[0]); //显示温度值
write_cd(1,disdata[1]);
write_cd(1,'.'); //显示小数点
write_cd(1,disdata[2]);
}
void disp2() //12864显示日期
{
uchar h;
for(h=0;h<10;h++)
{
write_cd(text[h]);
delay(20);
}
}
/****************数码管显示程序***********************/
void write2_595(unsigned char Data) //595级联
{
SH_CP1=0;
ST_CP1=1;
for (d=0;d<8;d++)
{
Data=Data<<1;
DS1=CY;
SH_CP1=1;
delay1(5);
SH_CP1=0;
}
ST_CP1=0;
delay1(5);
ST_CP1=1;
delay1(5);
ST_CP1=0 ;
}
void display(unsigned int temp) //温度显示子函数
{
uchar i;
temper=read_temp();
disdata[0]=temper/10000;
disdata[1]=temper%10000/1000;
disdata[2]=temper%1000/100;
disdata[3]=temper%100/10;
disdata[4]=temper%10;
disdata[5]=12;
for(i=0;i<6;i++)
{
if(i==2)
{
write2_595(table1[d]); //先传位码
write2_595(table[disdata[i]]|0x80); //后传段码
}
else
{
write2_595(table1[d]); //先传位码
write2_595(table[disdata[i]]); //后传段码
}
delay (100) ;
}
}
void disp3() //数码管显示日期
{
uchar l;
for(l=0;l<10;l++)
{
write2_595(table1[d]); //先传位码
write2_595(text1[l]); //后传段码
}
}
/****************外部中断程序***********************/
void int0() interrupt 0 //外部中断0子程序
{
EX0=0;
delay1(20);
EX0=1;
delay1(20);
disp(); //1602温度显示
display_temp(); //12864温度显示
display(); //数码管温度显示
}
void int1() interrupt 2 //外部中断1子程序
{
EX1=0;
delay1(20);
EX1=1;
delay1(20);
disp1(); //1602显示日期
disp2(); //12864显示日期
disp3(); //数码管显示日期
}
/****************主程序***********************/
void mian ()
{
EA=1; //打开总中断
EX0=1; //打开外部中断0
IT0=1; //设置为下降沿触发
EX1=1; //打开外部中断1
IT1=1; //设置为下降沿触发
while(1);
}
-
这个是仿真图
问题应该是出在程序上,如果可以,帮我看看程序哪里有问题吧
一周热门 更多>