历程:
main.c
#include <STC15F2K60S2.H>
#include "onewire.h"
#include "iic.h"
void SMG_Show();
void led_kong();
sbit H3=P3^2;
sbit H4=P3^3;
sbit L1=P4^4;
sbit L2=P4^2;
unsigned int T_smg=0;
float T=0;
unsigned char mode=1,mode_V=1;
unsigned char T_can=25;
unsigned char led_state=0xff;
float Vda=0;
unsigned int V_smg=0;
unsigned char Vda_smg=0;
unsigned char code SMG_NODOT[]={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,
~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};
unsigned char code SMG_DOT[]={~0xBF,~0x86,~0xDB,~0xCF,~0xE6,~0xED,~0xFD,~0x87,~0xFF,~0xEF,~0x46};
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(--xms)
{
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
void HC138(unsigned char Y,date)
{
P0=date;
switch(Y)
{
case 4:
P2=(P2&0X1F)|0X80;
break;
case 5:
P2=(P2&0X1F)|0Xa0;
break;
case 6:
P2=(P2&0X1F)|0Xc0;
break;
case 7:
P2=(P2&0X1F)|0Xe0;
break;
case 0:
P2=(P2&0X1F)|0X00;
break;
}
P2=(P2&0X1F)|0X00;
}
void Read_ds18b20_T()
{
unsigned char LSB,MSB;
unsigned int temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
temp=MSB;
temp=(temp<<8)|LSB;
if((temp&0xf800)==0x0000)
{
T=temp*0.0625;
}
}
void SMG(unsigned char wei,shu)
{
HC138(6,0X01<<wei);
HC138(7,shu);
Delay(2);
HC138(6,0xff);
HC138(7,0xff);
}
void scankeys()
{
H4=0;//S4
L2=H3=L1=1;
if(L1==0)
{
Delay(10);
if(L1==0)
{
if(mode!=3)
mode++;
else
mode=1;
}
while(L1==0)
{
SMG_Show();
led_kong();
}
}
H4=0;//S8
H3=L1=L2=1;
if(L2==0)
{
Delay(10);
if(L2==0)
{
if(mode==2)
{
if(T_can!=0)
T_can-=1;
}
}
while(L2==0)
{
SMG_Show();
led_kong();
}
}
H3=0;//S9
H4=L1=L2=1;
if(L2==0)
{
Delay(10);
if(L2==0)
{
if(mode==2)
{
if(T_can!=99)
T_can+=1;
else
T_can=99;
}
}
while(L2==0)
{
SMG_Show();
led_kong();
}
}
H3=0;//S5
H4=L1=L2=1;
if(L1==0)
{
Delay(10);
if(L1==0)
{
if(mode_V==1)
{
mode_V=2;
}
else if(mode_V==2)
{
mode_V=1;
}
}
while(L1==0)
{
SMG_Show();
led_kong();
}
}
}
void SMG_Show()
{
switch(mode)
{
case 1:
T_smg=T*100;
Read_ds18b20_T();
SMG(0,0xc6);
SMG(4,SMG_NODOT[T_smg/1000]);
SMG(5,SMG_DOT[T_smg/100%10]);
SMG(6,SMG_NODOT[T_smg/10%10]);
SMG(7,SMG_NODOT[T_smg%10]);
break;
case 2:
SMG(0,0x8c);
SMG(6,SMG_NODOT[T_can/10]);
SMG(7,SMG_NODOT[T_can%10]);
break;
case 3:
if(mode_V==1)
{
if(T<T_can)
Vda=0;
else
Vda=5;
Vda_smg=Vda;
SMG(0,0x88);
SMG(7,SMG_NODOT[Vda_smg]);
}
else if(mode_V==2)
{
Read_ds18b20_T();
if(T<=20)
Vda=1.0;
else if(T>=40)
Vda=4.0;
else
Vda=(3/20.0)*T-2;
V_smg=Vda*100;
SMG(0,0x88);
SMG(5,SMG_DOT[V_smg/100]);
SMG(6,SMG_NODOT[V_smg/10%10]);
SMG(7,SMG_NODOT[V_smg%10]);
}
break;
}
}
void Init_sys()
{
HC138(0,0X00);
HC138(4,0XFF);
HC138(5,0X00);
HC138(6,0XFF);
HC138(7,0XFF);
}
void Init_ds18b20_85()
{
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
do
{
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
MSB=(MSB<<4)|(LSB>>4);
}while(MSB==85);
}
void Read_PCF8591_da(unsigned char da)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(da);
IIC_WaitAck();
IIC_Stop();
}
void led_kong()
{
if(mode_V==1)
{
led_state&=~0x01;
HC138(4,led_state);
}
else
{
led_state|=0x01;
HC138(4,led_state);
}
if(mode==1)
{
led_state&=~0x02;
HC138(4,led_state);
}
else
{
led_state|=0x02;
HC138(4,led_state);
}
if(mode==2)
{
led_state&=~0x04;
HC138(4,led_state);
}
else
{
led_state|=0x04;
HC138(4,led_state);
}
if(mode==3)
{
led_state&=~0x08;
HC138(4,led_state);
}
else
{
led_state|=0x08;
HC138(4,led_state);
}
}
void main()
{
Init_ds18b20_85();
Init_sys();
while(1)
{
scankeys();
SMG_Show();
Read_PCF8591_da((Vda*51));
}
}
iic.c:
/*
³̐÷: IICלϟǽ¶¯³̐ ȭ¼þ»·¾³: Keil uVision 4.10
Ӳ¼þ»·¾³: CT107µ¥Ƭ»úכºϊµѵƽ̨ 8051£¬12MHz
ȕ ƚ: 2011-8-9
*/
#include <STC15F2K60S2.H>
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
sbit SDA = P2^1;
sbit SCL = P2^0;
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
void IIC_SendAck(bit ackbit)
//{
// SCL = 0;
// SDA = ackbit;
// IIC_Delay(DELAY_TIME);
// SCL = 1;
// IIC_Delay(DELAY_TIME);
// SCL = 0;
// SDA = 1;
// IIC_Delay(DELAY_TIME);
//}
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//unsigned char IIC_RecByte(void)
//{
// unsigned char i, da;
// for(i=0; i<8; i++)
// {
// SCL = 1;
// IIC_Delay(DELAY_TIME);
// da <<= 1;
// if(SDA) da |= 1;
// SCL = 0;
// IIC_Delay(DELAY_TIME);
// }
// return da;
//}
iic.h:
#ifndef _IIC_H_
#define _IIC_H_
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
//void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
//unsigned char IIC_RecByte(void);
#endif
onewire.c:
#include "onewire.h"
void Delay_OneWire(unsigned int t)
{
unsigned int n;
n=t*10;
while(n--);
}
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
onewire.h:
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#include <STC15F2K60S2.H>
sbit DQ = P1^4;
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
void Write_DS18B20(unsigned char dat);
#endif
编码解释:
1:初始上电数码管显示85摄氏度。
读取温度的函数读取一遍温度所用的时间长(750ms),所以刚上电时会读取芯片内部的温度(出厂设置85度),想要解决这个问题有两种办法:
第一:在初始化系统中先测一遍温度,并且Delay(>750ms)跳过第一次读取温度,等读取完之后再进行显示。如下
第二:单独定义一个温度函数,当温度时85度时,不进行显示。如下
2.为什么DA输出时要乘51?
因为Vda是实际的电压值,而da存储的是0--255的份数,所以想要存储,就必须进行换算:份数=实际电压(Vda/(5.0/255)即Vda*51)。