iic.h和iic.c用官方驱动,不做变动
onewire.c
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include "reg52.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
while(t--);
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(50);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(50);
}
//从DS18B20读取一个字节
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(50);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(120);
DQ = 0;
Delay_OneWire(800);
DQ = 1;
Delay_OneWire(100);
initflag = DQ;
Delay_OneWire(50);
return initflag;
}
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned char rd_temperature(void); //; ;
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
#endif
main.c
#include <reg52.h>
#include <iic.h>
#include <onewire.h>
sfr P4=0XC0;
unsigned char duanma[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char duanma_x[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned int temp=0;
unsigned int u=0;
unsigned int t=25;
unsigned int tt=25;
sbit R1=P3^2;
sbit R2=P3^3;
sbit C1=P4^4;
sbit C2=P4^2;
unsigned char flag_s4=0;
unsigned char flag_s5=0x00;//模式1,取反后变成0xff;或者这样定义:bit flag_s5=0;bit定义的变量只能取0或1,取反后变1
void display_smg(unsigned char pos,unsigned char dat);
void display_temp();//温度显示界面
void display_p();//参数设置界面
void displaySMG_dac();//DAC转换界面
void read_ds18b20_temp();
void delay_smg(unsigned int t)
{
while(t--);
}
void delay(unsigned int t)
{
while(t--)
{
display_temp();
}
}
void display_smg(unsigned char pos,unsigned char dat)
{
P2=0XE0;P0=0XFF;
P2=0XC0;P0=0X01<<pos;
P2=0XE0;P0=dat;
}
void display_temp()//温度显示界面
{
display_smg(7,duanma[temp%10]);
delay_smg(200);
display_smg(6,duanma[(temp/10)%10]);
delay_smg(200);
display_smg(5,duanma_x[(temp/100)%10]);
delay_smg(200);
display_smg(4,duanma[temp/1000]);
delay_smg(200);
display_smg(0,0xc6);
delay_smg(200);
display_smg(3,0xff);
delay_smg(200);
display_smg(2,0xff);
delay_smg(200);
display_smg(1,0xff);
delay_smg(200);
P2=0XC0;P0=0XFF;
P2=0XE0;P0=0XFF;
}
void display_p()//参数设置界面
{
display_smg(7,duanma[t%10]);
delay_smg(200);
display_smg(6,duanma[t/10]);
delay_smg(200);
display_smg(0,0x8c);
delay_smg(200);
P2=0XC0;P0=0XFF;
P2=0XE0;P0=0XFF;
}
void displaySMG_dac()//DAC转换界面
{
display_smg(7,duanma[u%10]);
delay_smg(200);
display_smg(6,duanma[(u/10)%10]);
delay_smg(200);
display_smg(5,duanma_x[u/100]);
delay_smg(200);
display_smg(0,0x88);
delay_smg(200);
P2=0XC0;P0=0XFF;
P2=0XE0;P0=0XFF;
}
void display()
{
switch(flag_s4) //界面切换
{
case 0:
read_ds18b20_temp();
display_temp();break;
case 1:
display_p();break;
case 2:
displaySMG_dac();break;
}
}
void read_ds18b20_temp()//读取温度
{
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
delay(10);//设置合适的延时时间,避免影响按键操作
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
temp=MSB;
temp=(temp<<8)|LSB;
if((temp&0xf800)==0x0000)
{
temp>>=4;
temp=temp*100;//显示两位小数,放大十倍,这样做的目的将小数点后第二位数字也转换为可显示数字
temp=temp+(LSB&0x0f)*0.625;
}
}
void read_dac(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);//DA转换,数模转换,数字温度转换成模拟电压输出0100 0000
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(dat);//写入对应转换的电压值
IIC_WaitAck();
IIC_SendAck(1);
IIC_Stop();
}
void key()
{
R1=1;//s4界面切换
R2=0;
C1=C2=1;
if(C1==0)
{
delay_smg(100);
if(C1==0)
{
while(C1==0)
{
display();
}
flag_s4++;
if(flag_s4==3)
{
flag_s4=0;
}
if(flag_s4==1)
{
t=tt;//进入参数界面时,获取当前参数
}
else if(flag_s4==2)
{
tt=t;//退出参数界面时,参数生效
}
}
}
R1=0;//s5参数设置
R2=1;
C1=C2=1;
if(C1==0)
{
delay_smg(100);
if(C1==0)
{
while(C1==0)
{
display();
}
flag_s5=~flag_s5;
}
}
R1=1;//s8 温度参数减1
R2=0;
C1=C2=1;
if(C2==0)
{
delay_smg(100);
if(C2==0)
{
while(C2==0)//避免参数设置时数据闪动
{
display();
}
if(flag_s4==1)//仅在参数界面有效
{
t--;
}
}
}
R1=0;//s9 温度参数加1
R2=1;
C1=C2=1;
if(C2==0)
{
delay_smg(100);
if(C2==0)
{
while(C2==0)
{
display();
}
if(flag_s4==1)//仅在参数界面有效
{
t++;
}
}
}
}
void led()//led显示
{
P2=0X80;
if(flag_s5==0x00) //模式1
{
P0&=0XFE;//L1亮
}
if(flag_s4==0) //温度显示界面
{
P0&=0XFD;//L2亮
}
else if(flag_s4==1) //参数设置界面
{
P0&=0XFB;//L3亮
}
else if(flag_s4==2) //DAC输出界面
{
P0&=0XF7;//L4亮
}
}
void dac_ms()//模式变换
{
if(flag_s5==0x00)//模式1
{
if(temp<t*100)
{
u=0;
read_dac(0x00);
}
else
{
u=500;
read_dac(0xff);
}
}
if(flag_s5==0xff)//模式2
{
if(temp<2000)
{
u=100;
read_dac(0x51);//255/5=51 1v=(1/5)*5v 5v对应255
}
else if(temp<=4000)
{
u=(0.15*temp)-200;//用点(2000,100)和(4000,400)解出直线方程
read_dac(u*0.51);
}
else
{
u=400;
read_dac(204);
}
}
}
void main()
{
unsigned char i=0;
P2=0x80;P0=0xff;P2=0XA0;P0=0X00;
while(1)
{
key();
led();
dac_ms();
display();
}
}