看的小蜜蜂老师的视频,自己头一次写。
#include <reg52.h>
#include <onewire.h>
sfr P4 = 0xc0;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C2 = P4^2;
sbit C1 = P4^4;
sbit out = P3^4;
unsigned char code SMG_duanma[13] = {0xc0,0xf9,0xa4,
0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xc6,0xff};
// 0 1 2 3 4 5 6 7 8 9 - c 全灭
unsigned char mod = 1; //工作模式存储变量
unsigned char t_mod = 0; //计时模式存储变量
unsigned char c_mod = 0; //温度显示模式控制字
unsigned char t_work = 0; //倒计时时间
unsigned char t_pwm; //pwm计时变量
unsigned int temp = 0; //温度存储字
void Display_led();
void SelectHC573(unsigned char channel) //573选通
{
switch(channel)
{
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;
break;
}
}
void ScanKeys() //键盘扫描函数
{
C1 = 0;
C2 = 1;
R3 = R4 = 1;
if(R4 == 0) //PWM
{
void Display_Dynamic();
while(R4 == 0)
{
Display_Dynamic();
}
switch(mod)
{
case 1:
mod = 2;
t_pwm = 3;
break;
case 2:
mod = 3;
t_pwm = 7;
break;
case 3:
mod = 1;
t_pwm = 2;
break;
}
Display_led();
}
if(R3 == 0) //计时
{
Display_Dynamic();
while(R3 == 0)
{
Display_Dynamic();
}
if(t_mod == 0) t_mod =1 ,t_work = 60;
else if(t_mod == 1) t_mod = 2 ,t_work = 120;
else if(t_mod == 2) t_mod = 0 ,t_work = 0;
Display_led();
}
C2 = 0;
C1 = 1;
R3 = R4 = 1;
if(R3 == 0) //机器启闭
{
Display_Dynamic();
while(R3 == 0)
{
Display_Dynamic();
}
t_work = 0;
Display_led();
}
if(R4 == 0) //温度显示
{
Display_Dynamic();
while(R4 == 0)
{
Display_Dynamic();
}
if(c_mod == 0)
{
c_mod =1;
}
else c_mod = 0;
Display_led();
}
}
void Cls_peripheral() //关闭外设
{
P0 = 0xff;
SelectHC573(4);
SelectHC573(0);
P0 = 0;
SelectHC573(5);
SelectHC573(0);
}
void DisplaySMG_bit(unsigned char pos,unsigned char value)
{
P0 = 0xff; //消隐
SelectHC573(6);
P0 = 0x01 << pos;
SelectHC573(0);
P0 = SMG_duanma[value];
SelectHC573(7);
}
void initTimer() //初始化定时器
{
TMOD = 0x12; //T0用PWM计时,T1用作工作计时
TH0 = 0x9b; //255-100
TL0 = 0x9b;
TH1 = (65535-50000)/256;
TL1 = (65535-50000)%256;
ET0 = 1; //使能中断
ET1 = 1;
TF0 = 0;
TF1 = 0;
EA = 1;
TR0 = 0; //启动
TR1 = 1;
}
void Delay(unsigned int t)
{
while(t--)
{
Display_Dynamic();
}
}
void DelaySMG(unsigned char t)
{
while(t--);
}
void Display_led() //led显示控制
{
SelectHC573(4);
if(mod == 1 & t_work != 0) P0 = 0xfe;
else if(mod == 2 & t_work != 0) P0 = 0xfd;
else if(mod == 3 & t_work != 0) P0 = 0xfb;
else P0 = 0xff;
SelectHC573(0);
}
void Display_Dynamic() //数码管动态显示
{
DisplaySMG_bit(0,10);
DelaySMG(100);
DisplaySMG_bit(2,10);
DelaySMG(100);
DisplaySMG_bit(3,12); //熄灭第四位
DelaySMG(100);
if(c_mod == 0) //工作时间显示
{
DisplaySMG_bit(1,mod);
DelaySMG(100);
DisplaySMG_bit(7,t_work%10);
DelaySMG(100);
DisplaySMG_bit(6,(t_work/10)%10);
DelaySMG(100);
DisplaySMG_bit(5,t_work/100);
DelaySMG(100);
DisplaySMG_bit(4,0);
DelaySMG(100);
}
if(c_mod == 1) //温度显示
{
DisplaySMG_bit(1,4); //温度显示模式
DelaySMG(100);
DisplaySMG_bit(4,12); //熄灭第五位
DelaySMG(100);
DisplaySMG_bit(7,11); //显示摄氏度
DelaySMG(100);
DisplaySMG_bit(6,temp%10);
DelaySMG(100);
DisplaySMG_bit(5,(temp/10)%10);
DelaySMG(100);
}
}
void Read_DS18B20_temp() //读取温度
{
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay(1000);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = MSB;
temp =(temp << 8)| LSB;
temp >>=4; //数据处理
}
unsigned char count0;
void ServiceTimer0() interrupt 1
{
count0++; //计数100微秒
if(count0 == t_pwm)
{
out = 0;
}
else if(count0 == 10 & t_work !=0) //计数周期 1微秒
{
out = 1;
count0 = 0;
}
}
unsigned char count1;
void ServiceTimer1() interrupt 3
{
TH1 = (65535-50000)/256;
TL1 = (65535-50000)%256;
count1++;
if(count1 ==20 & t_work != 0) //计数1秒
{
t_work--; //变化秒数
count1 = 0;
}
if(t_work == 0)
{
SelectHC573(4);
P0 = 0xff;
SelectHC573(0);
}
if(count1 == 20) //手动重置计数器
{
count1 = 0;
}
}
void main()
{
Cls_peripheral();
initTimer();
while(1)
{
ScanKeys();
Read_DS18B20_temp();
Display_Dynamic();
}
}
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
{
unsigned char i;
while(t--);
{
for(i=0;i<12;i++);
}
}
//通过单总线向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;
}
/*
unsigned int rd_temperature(void)
{
unsigned char low, high;
init_ds18b20(); // 初始化
Write_DS18B20(0xCC); // 跳过ROM
Write_DS18B20(0x44); // 转换温度
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE); // 读暂存器
low = Read_DS18B20(); // 低字节
high = Read_DS18B20(); // 高字节
return (high<<8)+low;
}
*/
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
bit init_ds18b20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
#endif