📄 jjwnew.c
字号:
//DS18B20数字温度计C程序
//使用ATMEGA8L单片机,1MHZ晶振,用共阴极LED数码管显示
//PB0端口为温度输入口,PC0,PC1端口为段码输出口
#include <iom8v.h>
#define uchar unsigned char
#define uint unsigned int
//温度小数部分查表
uchar dit[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//共阴极LED段码表
uchar playtab[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40};
//"0""1""2""3""4""5""6""7""8""9""不亮""-"的编码
//读出温度暂放数组
uchar tempdata[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
//显示数据暂放数组
uchar display[5]={0x00,0x00,0x00,0x00,0x00};
//延时6us函数
void delay(uint t)
{
uint i;
for(i=0;i<t;i++);
}
//显示函数
void play(void)
{
uint i,j,d;
uchar d1;
int x;
i=0;
while(i<3)//循环3次,显示3位数码管
{
if(i==1)//如果i==1,则点亮小数点并把要显示的数据赋给d1
{d1=playtab[display[i]]|0X80;}
else
{d1=playtab[display[i]];}//把要显示的数据赋给d1
for(j=0;j<8;j++) //此处的for循环用于显示一位数码管
{
x=d1&0x80;
if(x==0)
{
PORTC=0XFD;//PC0口置高
PORTC=0XFC;//PC0口置低
d1=d1<<1;//x左移一位
}
else
{
PORTC=0XFE;//PC1口置高
//asm("nop");//空循环
PORTC=0XFF;//PC0口置高
PORTC=0XFC;//PC0,PC1口置低
d1=d1<<1;//d1左移一位
}
}
i=i+1;
}
PORTC=0xFD;
PORTC=0xFC;
for(d=0;d<250;d++)
{
delay(250);
delay(250);
delay(250);
delay(250);
}
}
//DS18B20复位函数
void reset(void)
{
uchar presence=0x01;
uchar m;
while(presence==0x01)
{
while(presence==0x01)
{
DDRB=0xFF;
//PORTB=0XFF;//PB0口置高
//asm("nop");
//asm("nop");
PORTB=0xFE;//PB0口置低
delay(80);//延时503us
//PORTB=0XFF;//PB0口置高
DDRB=0xFE;
delay(10);//延时83us
m=PINB;
presence=m&0x01;//presence=0x00继续下一步
}
delay(80);//延时503us
m=PINB;
presence=(~m)&0x01;//按位逻辑反
}
//PORTB=0XFF;//PB0口置高
}
//向DS18B20写函数
void write(uchar value)
{
uchar a;
for(a=0;a<8;a++)
{
DDRB=0xFF;
//PORTB=0XFF;//PB0口置高
//asm("nop");
//asm("nop");
PORTB=0XFE;
if(value&0x01)
{
//PORTB=0XFE;
//asm("nop");
//asm("nop");
DDRB=0xFE;
delay(8);
}
else
{
//PORTB=0XFE;
delay(8);
DDRB=0xFE;
}
//PORTB=0XFE;
//asm("nop");
//PORTB=value&0x01;//最低位移出
//delay(8);
//DDRB=0xFE;
value=value>>1;
asm("nop");
}
//PORTB=0XFF;
}
//从DS18B20读函数
uchar read(void)
{
uchar b,c;
uchar value=0;
DDRB=0xFE;
for(b=0;b<8;b++)
{
DDRB=0xFF;
PORTB=0XFF;
asm("nop");
asm("nop");
value=value>>1;//右移一位
PORTB=0XFE;
asm("nop");
DDRB=0xFE;
//PORTB=0XFF;
asm("nop");
asm("nop");
c=PINB;
if(c&0x01==0x01)//如果c&0x01==c成立,则value的最高位置1
{value|=0X80;}
delay(8);
PORTB=0XFE;
asm("nop");
asm("nop");
}
//PORTB=0XFF;
return(value);
}
//读出温度函数
void readtemp(void)
{
reset();//总线复位
write(0xCC);//发出SKIP ROM命令
write(0xBE);//发出读命令
tempdata[0]=read();//温度低8位
tempdata[1]=read();//温度高8位
reset();
write(0xCC);
write(0x44);//发转换命令
}
//温度数据处理函数
void worktemp(void)
{
uchar c=0;
if(tempdata[1]>7)//负温度求补码
{
tempdata[1]=(256-tempdata[1]);
tempdata[0]=(256-tempdata[0]);
c=1;
}
display[4]=tempdata[0]&0x0F;
display[0]=dit[display[4]];
display[4]=((tempdata[0]&0xF0)>>4)+(((tempdata[1])*256)>>4);
//display[3]=display[4]/100;
display[1]=display[4]%100;
display[2]=display[1]/10;
display[1]=display[1]%10;
//if(!display[3])//最高位为0时都不显示
//{display[3]=0x00;}
//if(!display[2])
//{display[2]=0x00;}
//if(c)//负温度时最高位显示“-”
//{display[3]=0x40;}
}
//主函数
void main(void)
{
int x;
uint i,j,k;
uchar d1;
DDRC=0X03;//初始化端口
PORTC=0XFC;
DDRB=0XFE;
PORTB=0XFF;
reset();
write(0xCC);
write(0x44);
i=0;
while(i<3)//开机显示“000”
{
d1=0x3F;
for(j=0;j<8;j++)
{
x=d1&0x80;
if(x==0)
{
PORTC=0XFD;
PORTC=0XFC;
d1=d1<<1;
}
else
{
PORTC=0XFE;
//asm("nop");
PORTC=0XFF;
d1=d1<<1;
PORTC=0XFC;
}
}
i=i+1;
}
PORTC=0xFD;
PORTC=0xFC;
for(k=0;k<250;k++)
{
delay(250);
delay(250);
delay(250);
delay(250);
}
while(1)
{
readtemp();//读出DS18B20温度数据
worktemp();//处理温度数据
play();//显示
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -