目录

         1.基本功能

2.初始化内容

3.显示界面的状态

4.按键功能

5.代码

1.DS1302代码

2.llc

3.onewire

4.mian函数


1.基本功能

1)通过DS18B20温度传感器,采集环境温度数据,保留小数点后2位有效数字。

2)读取DS1302时钟芯片的时、分、秒数据。

3)通过PCF8591芯片,采集光敏电阻返回的电压。

4)通过数码管显示时间、温度数据和电压,显示界面可以通过按键来回切换。

2.初始化内容

1)关闭蜂鸣器和继电器。

2)数码管处于ADC界面。

3)实时时钟初始化时间为00:00:00.

3.显示界面的状态

1)ADC界面LED2亮,其他LED熄灭。

2)时间界面LED3亮,其他LED熄灭。

3)温度界面LED4亮,其他LED熄灭。

4.按键功能

1)S4按下切换为时间界面,再按下一次切换为温度界面,再按下两次返回原来界面。

5.代码

1.DS1302代码

#include <intrins.h>
#include "ds1302.h"
#include <STC15F2K60S2.H>

sbit SCK=P1^7;		
sbit IO=P2^3;		
sbit CE = P1^3;   		// DS1302复位											

void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		IO=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	CE=0;	_nop_();
 	SCK=0;	_nop_();
 	CE=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	CE=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	CE=0;	_nop_();
 	SCK=0;	_nop_();
 	CE=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(IO)
 		temp|=0x80;	
 		SCK=1;
	} 
 	CE=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	IO=0;	_nop_();
	IO=1;	_nop_();
	return (temp);			
}



void vClock_Set(unsigned char hour,unsigned char minute,unsigned char second)
{
	Write_Ds1302_Byte(0x8e,0x00);			//关闭写保护
	Write_Ds1302_Byte(0x80,DecToBCD(second));       //写入小时数据到对应的地址
	Write_Ds1302_Byte(0x82,DecToBCD(minute));       //写入分钟数据到对应的地址
	Write_Ds1302_Byte(0x84,DecToBCD(hour));         //写入秒钟数据到对应的地址
	Write_Ds1302_Byte(0x8e,0x80);			//打开写保护
}
 
#ifndef __DS1302_H
#define __DS1302_H


#define DecToBCD(dec) (dec/10*16)+(dec%10)
#define BCDToDec(bcd) (bcd/16*10)+(bcd%16)

unsigned char Read_Ds1302_Byte( unsigned char address );
void vClock_Set(unsigned char hour,unsigned char minute,unsigned char second);

#endif

2.llc


#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

void Delay_Ms(unsigned int ms)		//@12.000MHz
{
	unsigned char i, j;
while(ms--)
{
	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}
}


//总线引脚定义
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;  					// 0:应答,1:非应答
    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;
}

//通过I2C总线发送数据
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;  
}

//从I2C总线上接收数据
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;    
}
 

    

//读取	
char ADC(unsigned  char c)
{
char q;
 IIC_Start();
 IIC_SendByte(0x90);
 IIC_WaitAck();
 IIC_SendByte(c);
 IIC_WaitAck();


 IIC_Start();
 IIC_SendByte(0x91);
 IIC_WaitAck();
q=IIC_RecByte();
 IIC_SendAck(1);
 IIC_Stop();

return q;
}
#ifndef _IIC_H
#define _IIC_H


char ADC(unsigned  char c);

#endif

3.onewire

#include <STC15F2K60S2.H>

#include "onewire.h"

sbit DQ = P1^4;  //单总线接口
//单总线延时函数

void Delay_OneWire(unsigned int t)  
{
	t = t * 12;
	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(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}
//从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(5);
	}
	return dat;
}

//DS18B20设备初始化
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;
}



//读取DS18B20温度的程序
float fRead_Temperature(void)
{
	float temp_return;
	int low,high;
	init_ds18b20();
	Write_DS18B20(0xcc); 		//跳过读取ROM
	Write_DS18B20(0x44); 		//启动温度转换
				        //不加上Delay延时,等待温度转换完成,直接去读取暂存器
	init_ds18b20();
	Write_DS18B20(0xcc); 		//跳过读取ROM
	Write_DS18B20(0xbe); 		//获取暂存器数据
	low = Read_DS18B20();		//温度低8位数据
	high = Read_DS18B20();		//温度高8位数据
	temp_return = (high<<8|low)*0.0625;
	
	return temp_return;
}
#ifndef __ONEWIRE_H
#define __ONEWIRE_H


float fRead_Temperature(void);

#endif

4.mian函数

#include <STC15F2K60S2.H>
#include "iic.h"
#include "onewire.h"
#include "ds1302.h"

void Delay()		//@12.000MHz
{
	unsigned char i, j;

	i = 6;
	j = 211;
	do
	{
		while (--j);
	} while (--i);
}


void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0x18;		//设置定时初始值
	T2H = 0xFC;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
	EA=1;
	IE2  |= 0x04;
}
void Device(unsigned char p2,unsigned char p0)//配置锁存器
{
	P0=p0;
	P2=P2&0x1f|p2;	
	P2 &=0x1f;	
}

void system()//初始化
{
	Device(0xa0,0);
	Device(0x80,0xff);
}
//阴极数码管表0~9  10为U 11为 . 12为C 13为-
unsigned int smgs[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3E,0x80,0x39,0x40};

void smg(unsigned n,unsigned m)//配置数码管显示
{
	int a;
	a=0x01<<n;
	Device(0xc0,0);
	Device(0xe0,~smgs[m]);//显示内容
	Device(0xc0,a);//显示位置a+1
}

unsigned char u1,ms,u2;
void ADC_read()//读取
{	
if(ms>=10)
{	
	ms=0;
	ADC(0x41);//光敏电阻
	u1=ADC(0x41);
	ADC(0x43);
	u2=ADC(0x43);//转口
    
    u1_5=u1/51*100;//将255转换为500
    u2_5=u2/51*100;//将255转换为500
}	

}

void show_adc()//显示adc值
{
	smg(0,u1_5/100);
    smg(0,11);
	smg(1,u1_5/10%10);
	smg(2,u1_5%10);
	
	smg(4,u1/100);
	smg(5,u1/10%10);
	smg(6,u1%10);
	smg(7,10);
}

int ds;
unsigned long du;
void ds18b20()//读取温度
{
if(ds>=10)
{
	ds=0;
  du =(unsigned long)(fRead_Temperature()*10000);
}
}

void show_du()//显示温度
{
	smg(1,du/100000);
	smg(2,du/10000%10);
	smg(2,11);
	smg(3,du/1000%10);
	smg(4,du/100%10);
	smg(5,12);
}




int s,min,h,b=0;
void ds1302()//时间读取
{
s= BCDToDec(Read_Ds1302_Byte( 0x81 ));
min=BCDToDec(Read_Ds1302_Byte( 0x83 ));
h=BCDToDec(Read_Ds1302_Byte( 0x85 ));
}

void show_sj()//时间显示
{
	smg(0,h/10);
	smg(1,h%10);
    smg(2,13);
	smg(3,min/10);
	smg(4,min%10);
    smg(5,13);
	smg(6,s/10);
	smg(7,s%10);

	
}
int i;
void key()//
{
if(P33==0)
//消抖              
{Delay();if(P33==0){i++;i=i%3;while(P33==0){}}}

}


void main()
{
	system();
	Timer2Init();
	vClock_Set(00,00,00);//初始化时钟
while(1)
{
	
	key();
	ds1302();
    ADC_read();
    
	
}
}

void t2() interrupt 12  //中断入口
{
	ms++;
	ds++;
    ds18b20();
	//根据变量显示界面
    if(i==0)
    {
     show_adc();
     
    }
	if(i==1)
    {
   show_sj();
    }
	if(i==2)
    {
    show_du();
    }
	
}

请多多指教

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐