程序::#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
sbit DQ=P1^0;
bdata uchar dat;
sbit dat0=dat^0;
sbit dat7=dat^7;
uchar dp[16]={0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9};
uchar code segtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xef,0xbf};
uchar dbuf[4]={0,0,0,0};
void disp(void)
{ uchar i,n,wx;
wx=0xfe;
for(n=0;n<4;n++)
{ P2=wx;
P0=segtab[dbuf[n]];
if(n==1) P0=P0&0x7f;
wx=(wx<<1)+1;
for(i=1;1<200;i++);
P0=0xff;
}
}
void delay(unsigned int i)
{ unsigned int j;
for(j=i;j>0;j--);
}
bit reset(void)
{ bit flag;
DQ=0;
delay(60);
DQ=1;
delay(3);
flag=DQ;
delay(25);
return(flag);
}
void ds18b20_init(void)
{
while(1)
{
if(!reset())
{
DQ=1;
delay(30);
break;
}
else
reset();
}
}
void wrbyte(uchar t)
{
uchar i,dat;
dat=t;
for(i=8;i>0;i--)
{
DQ=0;
_nop_();
DQ=dat&0x01;
dat=dat>>1;
delay(5);
DQ=1;
delay(1);
}
}
uchar rdbyte(void)
{ uchar i;
uchar dat=0;
DQ=1;_nop_();
for(i=8;i>0;i--)
{
DQ=0;
dat>>=1;
DQ=1;_nop_();_nop_();
if(DQ) dat|=0x80;
delay(30);
DQ=1;
_nop_();
}
return(dat);
}
void convert(void)
{
ds18b20_init();
wrbyte(0xcc);
wrbyte(0x44);
delay(40);
}
int readt(void)
{ uchar h,l;
ds18b20_init();
wrbyte(0xcc);
wrbyte(0x44);
l=rdbyte();
h=rdbyte();
return(h*256+l);
}
void tdatacl(int x)
{
bit zf;
zf=0;
if(x<0)
{zf=1;
x=-x;
}
dbuf[0]=dp[x&0x0f];
x=x>>4;
dbuf[3]=x/100;
x=x%100;
dbuf[2]=x/10;
dbuf[1]=x%10;
if(zf==1)
{ if(dbuf[2]==0)
{ dbuf[3]=0xff;
dbuf[2]=0xbf;
}
else
dbuf[3]=0xbf;
}
else
{ if(dbuf[3]==0)
if(dbuf[2]==0)
{dbuf[2]=0xff;
dbuf[3]=0xff;
}
else dbuf[3]=0xff;
}
}
void main()
{
int t;
uchar i;
while(1)
{ convert();
t=rdbyte();
tdatacl(t);
for(i=50;i>0;i--)
disp();
}
仿真图搞不上来!!下楼继续
求助关于ds18b20温度显示的问题恳求个位人士帮忙解决
关键词: 求助 关于 ds18b20 温度 显示 问题 恳求
仿真时数码管只亮不显示数字!一直停留在0000!仿真图搞不上来!!帮忙看看程序有没有错误!!如有帮忙改正一下万分感谢!!!
我当年使用的版本之一。
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P3^3; //定义DS18B20接口
int temp;
uchar flag1;
void display(unsigned char *lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数
void delay();//延时子函数,5个空指令
code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,
0x40,
0x39,
0x00};
//共阴数码管显示数的组成是 "0-9""0-9有小数点的" "-" "C" "空 表"
unsigned char l_tmpdate[8]={0,0,10,0,0,0,0,0};//定义数组变量,并赋值1,2,3,4,5,6,7,8,就是本程序显示的八个数
int tmp(void);
void tmpchange(void);
void tmpwritebyte(uchar dat);
uchar tmpread(void);
bit tmpreadbit(void);
void dsreset(void);
void delayb(uint count);
void main() //主函数
{
uchar i;
int l_tmp;
while(1)
{
tmpchange(); //温度转换
l_tmp=tmp(); //读取温度值
if(l_tmp<0)
l_tmpdate[0]=20; //判断温度为负温度,前面加"-"
else
{
l_tmpdate[0]=l_tmp/1000; //显示百位,这里用1000,是因为我们之前乖以10了
if(l_tmpdate[0]==0)
l_tmpdate[0]=22;//判断温度为正温度且没有上百,前面不显示,查表第12是空
}
l_tmp=l_tmp%1000;
l_tmpdate[1]=l_tmp/100;//获取十位
l_tmp=l_tmp%100;
l_tmpdate[2]=l_tmp/10;//获取个位再
l_tmpdate[2]+=10;//加入小数点,查表可得出有小数点的排在后10位,所以加10
l_tmpdate[3]=l_tmp%10;//获取小数第一位
l_tmpdate[4]=21;
for(i=0;i<10;i++){ //循环输出10次,提高亮度
display(l_tmpdate,5);
}
}
}
void display(unsigned char *lp,unsigned char lc)//显示
{
unsigned char i; //定义变量
P2=0; //端口2为输出
P1=P1&0xF8; //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管
for(i=0;i<lc;i++){ //循环显示
P2=table[lp[i]]; //查表法得到要显示数字的数码段
delay(); //延时5个空指令
if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据
break;
P2=0; //清0端口,准备显示下位
P1++; //下一位数码管
}
}
void delay(void) //空5个指令
{
_nop_();_nop_();_nop_();_nop_();_nop_();
}
void delayb(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void dsreset(void) //DS18B20初始化
{
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) // 读一位
{
uint i;
bit dat;
DS=0;i++; //小延时一下
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //读一个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好//一个字节在DAT里
}
return(dat); //将一个字节数据返回
}
void tmpwritebyte(uchar dat)
{ //写一个字节到DS18B20里
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) // 写1部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //写0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //发送温度转换命令
{
dsreset(); //初始化DS18B20
delayb(1); //延时
tmpwritebyte(0xcc); // 跳过序列号命令
tmpwritebyte(0x44); //发送温度转换命令
}
int tmp() //获得温度
{
float tt;
uchar a,b;
dsreset();
delayb(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //发送读取数据命令
a=tmpread(); //连续读两个字节数据
b=tmpread();
temp=b;
temp<<=8;
temp=temp|a; //两字节合成一个整型变量。
tt=temp*0.0625; //得到真实十进制温度值,因为DS18B20
//可以精确到0.0625度,所以读回数据的最低位代表的是
//0.0625度。
temp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入操作。
return temp; //返回温度值
}
void readrom() //read the serial 读取温度传感器的序列号
{ //本程序中没有用到此函数
uchar sn1,sn2;
dsreset();
delayb(1);
tmpwritebyte(0x33);
sn1=tmpread();
sn2=tmpread();
}
void delay10ms()
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 | |
【FRDM-MCXN947评测】核间通信MUTEX被打赏50分 |