目录
一、Onewire初始化代码
- 加载“Onewire.c”文件,主函数中添加“Onewire.h”头文件;
- 调节软件延迟时长(全部扩大10倍即可){解释:蓝桥杯给的资料是89C52的代码,由于开发板使用的是stc15系列,所以扩大十倍}
- 编写温度数据获取函数,并且在头文件中定义;
- 编写用户功能函数;
二、注意:多个.c文件的使用
- 不管有多少个函数,C总是从main()主函数开始执行。
- 一个工程里面包括多个.c的文件,其实每个.c的文件里就是一系列函数而已。
- 一般更多的.C文件,要配合其.H文件来使用,变量的定义,函数的定义均放置在头文件中
- 如果要使用这些函数,要在头文件里加入#include“XXX.h”
-
三、DS18B20的驱动函数
-
(1)init_ds18b20
-
接口函数:init_ds18b20
函数原型
bit init_ds18b20(void)
功能描述
OneWire总线启动函数;
入口参数1
无
返回值
0或1,是否得到OneWire总线的响应。
注意事项
该函数需要用户调用;
(2)Write_DS18B20
接口函数:Write_DS18B20 | |
函数原型 | void Write_DS18B20(unsigned char dat) |
功能描述 | 使用OneWire总线往从机写一个字节数据函数; |
入口参数1 | Dat:需要往从机写入的一个字节数据 |
返回值 | 无 |
注意事项 | 该函数需要用户调用; |
(3)Read_DS18B20
函数原型 | unsigned char Read_DS18B20(void) |
功能描述 | 使用OneWire总线从从机读出一个字节数据函数; |
入口参数1 | 无 |
返回值 | 从机独处的一个字节数据; |
注意事项 | 该函数需要用户调用; |
四、DS18B20温度读取函数
bit Temper_Flag = 0 ;
unsigned int Temp;
unsigned long Temp_get(void)
{
unsigned char low,high;
if(Temper_Flag == 0 )
{
Temper_Flag = 1 ;
init_ds18b20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
}
else if( Temper_Flag == 1 )
{
Temper_Flag = 0 ;
init_ds18b20();//启动总线
Write_DS18B20(0XCC);//发送跳过ROM指令
Write_DS18B20(0XBE);//发送读暂存器指令
low=Read_DS18B20();//读暂存器的低8位
high=Read_DS18B20(); //读暂存器的高8位
Temp=high&0X0F; // SSSS XXXX 高4位清零(符号位)
Temp <<= 8; // Temp =Temp << 8;高8位向左移8位
Temp |= low; // Temp =Temp | low;存储低8位
//
}
return Temp;
}
-
五、功能实现(代码)
(1)<onewire.h>
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned long Temp_get(void);
#endif
(2)<onewire.c>
#include <STC15F2K60S2.H>
#include <intrins.h>
sbit DQ = P1^4; //单总线接口
void Delay1us(unsigned int us) //@11.0592MHz
{
unsigned int i=0;
for(i=0;i<us;i++)
{
_nop_(); _nop_(); _nop_();
}
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit init_flag = 1;
DQ =1 ;
Delay1us(10);
DQ =0 ;
Delay1us(600);
DQ =1 ;
Delay1us(70);
init_flag = DQ ;
Delay1us(200);
return init_flag;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
DQ = 0;
Delay1us(2);
DQ = (dat & 0x01); // 1100 1100 & 0000 0001 = 0000 0000
Delay1us(60);
dat >>=1;
DQ = 1;
Delay1us(1);
}
Delay1us(50);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char dat;
unsigned char i=0;
for(i=0;i<8;i++)
{
DQ = 0;
Delay1us(2);
dat >>=1;
DQ = 1;
Delay1us(5);
if(DQ==1)
{
dat |= 0x80; //0000 0000 | 1000 0000 = 1000 0000
}
Delay1us(55);
}
DQ = 1;
Delay1us(10);
return dat;
}
//unsigned long Temp_get(void)
//{
// unsigned char low,high;
// unsigned int Temp;
//
// init_ds18b20();
// Write_DS18B20(0XCC); //发送跳过ROM指令
// Write_DS18B20(0X44); //发送启动温度转换指令
// Delay1us(200); //延迟
//
// init_ds18b20(); //启动总线
// Write_DS18B20(0XCC);
// Write_DS18B20(0XBE);
//
// low=Read_DS18B20();
// high=Read_DS18B20();
//
// Temp=high&0X0F; // SSSS XXXX
// Temp <<= 8; // Temp =Temp << 8;
// Temp |= low; // Temp =Temp | low;
// return Temp;
//}
bit Temper_Flag = 0 ;
unsigned int Temp;
unsigned long Temp_get(void)
{
unsigned char low,high;
if(Temper_Flag == 0 )
{
Temper_Flag = 1 ;
init_ds18b20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
}
else if( Temper_Flag == 1 )
{
Temper_Flag = 0 ;
init_ds18b20();//启动总线
Write_DS18B20(0XCC);//发送跳过ROM指令
Write_DS18B20(0XBE);//发送读暂存器指令
low=Read_DS18B20();//读暂存器的低8位
high=Read_DS18B20(); //读暂存器的高8位
Temp=high&0X0F; // SSSS XXXX 高4位清零(符号位)
Temp <<= 8; // Temp =Temp << 8;高8位向左移8位
Temp |= low; // Temp =Temp | low;存储低8位
//
}
return Temp;
}
(3)main.c
#include <STC15F2K60S2.H>
#include <intrins.h>
#include<onewire.h>
unsigned char Key_Value = 0;
unsigned char tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,\
0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,\
0XBF,0XFF};
unsigned char DigCom=0;
unsigned char DigBuf[8] = {20,20,20,20,20,20,20,20};
unsigned char LED_Bit=0XFF;
unsigned char Actuator_Bit=0X00;
#define LEDx_ON(n) { LED_Bit&=_crol_(0XFE,n-1); P0=LED_Bit; P2|=0X80; P2&=0X9F; P2&=0X1F;}
#define LEDx_OFF(n) { LED_Bit|=_crol_(0X01,n-1); P0=LED_Bit; P2|=0X80; P2&=0X9F; P2&=0X1F;}
#define Buzzer_ON Actuator_Bit|=0x40; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
#define Buzzer_OFF Actuator_Bit&=0XBF; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
#define Relay_ON Actuator_Bit|=0x10; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
#define Relay_OFF Actuator_Bit&=0XEF; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
unsigned char LED = 1 ;
unsigned int LED_tt =0;
bit LED_Ref = 0 ;
unsigned int SEG_tt =0; //定义一个数码管计数时间标识位
bit SEG_Ref = 0 ; //定义一个数码管刷新标识位
bit SEG_Run = 0 ; //定义一个控制数码管运行标识位
unsigned int Num = 999 ;
unsigned int Temp_tt =0; //定义一个温度传感刷新及时变量
bit Temp_Ref =0; //定义一个温度传感刷新标志位
unsigned int Temper = 0 ; //定义一个存储温度数据的变量(16位)
unsigned char Temp_Vaue = 0 ; //定义一个只存储温度整数数据的变量
unsigned long Temp_DotValue = 0 ; //定义一个计算温度带小数位的变量
void All_Init(void);
void Delay_MS(unsigned int ms);
void Key_Scan(void);
void Timer0Init(void); //1毫秒@11.0592MHz
void main(void)
{
All_Init();
Timer0Init();
EA=1;ET0=1;
while(1)
{
if(Temp_Ref==1)
{
Temp_Ref=0;
// Temp_Vaue=Temp_get()>>4;
// DigBuf[0]=21;DigBuf[1]=21;DigBuf[2]=21;DigBuf[3]=21;DigBuf[4]=21;
// DigBuf[5]=21;DigBuf[6]=Temp_Vaue/10;DigBuf[7]=Temp_Vaue%10;
Temp_DotValue = Temp_get()*625; //扩大一万倍
DigBuf[0]=21;DigBuf[1]=21;
DigBuf[2]=Temp_DotValue/100000;
DigBuf[3]=Temp_DotValue%100000/10000+10;// 显示带小数点的码值
DigBuf[4]=Temp_DotValue%10000/1000;
DigBuf[5]=Temp_DotValue%1000/100;
DigBuf[6]=Temp_DotValue%100/10;
DigBuf[7]=Temp_DotValue%10;
}
Key_Scan();
if(Key_Value==7){Key_Value=0;SEG_Run = 1 ;}
if(Key_Value==6){Key_Value=0;SEG_Run = 0 ;}
if(Key_Value==5){Key_Value=0;LEDx_ON(1);Buzzer_ON;}
if(Key_Value==4){Key_Value=0;LEDx_OFF(1);Buzzer_OFF;}
}
}
void All_Init(void)
{
P0 = 0X00;//先设置关闭蜂鸣器继电器的P0输出值(全关)
P2 |=0XA0;// 1010 0000 将P27 P25 设置为1 其他位保持不变
P2 &=0XBF;// 1011 1111将P26设置为0 其他位保持不变
P2 &=0X1F;// 0001 1111关闭所有的74HC573锁存器
P0 = 0XFF;//1111 1111 先设置关闭所有的LED的P0输出值(全关)
P2 |=0X80;//1000 0000 将P27设置为1 其他位保持不变
P2 &=0X9F;//1001 1111 将P26 P25设置为0 其他位保持不变
P2 &=0X1F;//0001 1111 关闭所有的74HC573锁存器
P0 = 0X00;//1111 1111 //先设置选择数码管位选的P0输出值(全不选)
P2 |=0XC0;//1100 0000 将P27设置为1 其他位保持不变
P2 &=0XDF;//1101 1111 将P26 P25设置为0 其他位保持不变
P2 &=0X1F;// 0001 1111 关闭所有的74HC573锁存器
}
void Delay_MS(unsigned int ms) //@11.0592MHz
{
unsigned char i, j;
while(ms--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void Key_Scan(void)
{
if(P30 == 0)
{
Delay_MS(10);
if(P30 == 0) Key_Value=7;
while(!P30);
}
if(P31 == 0)
{
Delay_MS(10);
if(P31 == 0) Key_Value=6;
while(!P31);
}
if(P32 == 0)
{
Delay_MS(10);
if(P32 == 0) Key_Value=5;
while(!P32);
}
if(P33 == 0)
{
Delay_MS(10);
if(P33 == 0) Key_Value=4;
while(!P33);
}
}
void Timer0(void) interrupt 1
{
P0 = 0X00;
P2 |=0XC0; // P2=P2|0XC0; XXXX XXXX | 1100 0000 = 11XX XXXX
P2 &=0XDF; // P2=P2&0XDF; 11XX XXXX & 1101 1111 = 110X XXXX
P2 &=0X1F; //关闭所有的74HC573锁存器
P0=tab[DigBuf[DigCom]];
P2 |=0XE0; // P2=P2|0XE0; XXXX XXXX | 1110 0000 = 111X XXXX
P2 &=0XFF; // P2=P2&0XDF; 11XX XXXX & 1101 1111 = 110X XXXX
P2 &=0X1F; //关闭所有的74HC573锁存器
P0=(0X01<<DigCom); //然后选中第一个数码管
P2|=0XC0; // P2=P2|0XC0; XXXX XXXX | 1100 0000 = 11XX XXXX
P2&=0XDF; // P2=P2&0XDF; 11XX XXXX & 1101 1111 = 110X XXXX
P2&=0X1F; //关闭所有的74HC573锁存器
if(++DigCom == 8)DigCom = 0 ;
if(++LED_tt == 1000) {LED_tt = 0 ; LED_Ref = 1 ;}
if(++SEG_tt==1000){SEG_tt=0;SEG_Ref=1;}
if(++Temp_tt==1000){Temp_tt=0;Temp_Ref=1;}
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初始值
TH0 = 0xD4; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}