//程序使用msp430g2553单片机写的,用的是28引脚的。用3位共阳极数码管显示18B20 //的温度。最后附上电路图。我自己随便画的。可能有些地方不太标准。 #include \
#define uchar unsigned char #define uint unsigned int
#define DQ BIT3
#define DQ1 P1OUT |= BIT3 #define DQ0 P1OUT &= ~BIT3 #define DQIN P1DIR &= ~BIT3 #define DQOUT P1DIR |= BIT3
#define READ_DQ (P1IN&DQ)//读DQ电平
uint temp; uint a,b,c,d,F; uchar x; uint fz=0;
//数码管7位段码:0--f
uchar scandata[16] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; uchar scandata1[3] = {0x04,0x02,0x01};
void delay2(void) {
uint tmp;
for(tmp = 800;tmp > 0;tmp--); }
void DS18B20_Init(void) //DS18B20初始化函数 {
//char x; DQOUT;
DQ0; //拉低总线
__delay_cycles(4800); //精确延时 大于 480us DQ1; //释放总线 __delay_cycles(480); DQIN;
if(READ_DQ) {
x =1;//初始化失败 } else
{
x = 0;//初始化成功 }
DQOUT; DQ1;
__delay_cycles(3600); }
void DS18B20_WriteData(uchar dat) //写一个字节 {
uchar i;
for(i=0;i<8;i++)//位计数值 {
DQ0; //拉低总线产生写信号 __delay_cycles(48);
if(dat&0x01) DQ1;//此位数据是否为高,是高则将单总线拉高 else DQ0;//是低则将单总线拉低 dat>>=1; //准备下一位数据的传送 __delay_cycles(400);
DQ1; //释放总线,等待总线恢复 __delay_cycles(80); } }
uchar DS18B20_ReadData(void) //读一个字节 {
uchar i;
uchar dat=0;
for(i=0;i<8;i++)//位计数值 {
dat>>=1;//右移,准备接受新的数据位 DQ0; //拉低总线产生读信号 __delay_cycles(48);
DQ1; //释放总线准备读数据 __delay_cycles(72);//等待5微秒
DQIN;//配置为输入,开始读取数据位 _NOP();
if(READ_DQ)//该位是否为高 {
dat|=0x80;//是就将此位置高 }
__delay_cycles(400);//等待50微秒 DQOUT;
DQ1;
__delay_cycles(80); }
return(dat);//将读到的一个字节返回 }
uint Read_Temp(void) //读取温度 {
uint temp_low,temp_high,d; float c;
DS18B20_Init();//初始化,每次写命令都从初始化开始 DS18B20_WriteData(0xcc); //跳过ROM命令 DS18B20_WriteData(0x44); //温度转换命令
DS18B20_Init();//初始化,每次写命令都从初始化开始 DS18B20_WriteData(0xcc); //跳过ROM命令 DS18B20_WriteData(0xbe); //
temp_low=DS18B20_ReadData();//读温度低字节 temp_high=DS18B20_ReadData(); //读温度高字节 if(temp_high&0xf8) {
temp_high<<=8;
temp_high|=temp_low; d=~temp; d+=1;
F=1;//温度为负值 } else {
temp_high<<=8;
d=temp_high|temp_low; F=0;//温度为正值 }
c=d*0.0625; d=(uint)(c*100);
return(d); //返回16位变量 }
void delay(uint z) //延时函数 {
uint x,y;
for(x=z;x>0;x--) for(y=110;y>0;y--); }
int main(void) {
WDTCTL = WDTPW + WDTHOLD;//停止看门狗
BCSCTL1 = CALBC1_8MHZ;//MCLK为DCO,8MHZ DCOCTL = CALDCO_8MHZ; P1DIR |=BIT0; P2DIR=0xff; P3DIR=0xff;
while(1) {
temp=Read_Temp(); if(F==0) {
a=temp000/1000; b=temp00/100; d=temp0/10; c=temp/10000; int k=4000; if(c!=0) {
while(k>0) {
P2OUT = scandata1[2];
P3OUT = scandata[c]; //用一位数码管显示 delay2();
P2OUT = scandata1[1];
P3OUT = scandata[a]; //用一位数码管显示 delay2();
P2OUT = scandata1[0];
P3OUT = scandata[b]; //用一位数码管显示 delay2(); k--; } } else {
while(k>0) {
P2OUT = scandata1[2];
P3OUT = scandata[a]; //用一位数码管显示