利用温度传感器DS18B20和TM1650驱动的数码管来实现功能(完整版,0error,有位博主也有类似的,但是很多错误,这里可以直接用,包含.c和.h文件)
1、555.c(主函数在此)
//STC8H1K28
//STC8H1K28
#include <STC8H.h>
#include "TM1650.h"
#include <INTRINS.h>
typedef unsigned char uchar;
//typedef unsigned char uchar;
typedef unsigned int INT16U;
typedef unsigned int uint;
int e,DSFlag;
unsigned char tempLow; //温度低字节
unsigned char tempHigh; //温度高字节
unsigned char tempFlag = 0; //温度正负标志位
unsigned char temp[2] = {'\0'}; //存放温度整数和小数
uchar tempdata;
sbit DS = P2^2; //DS18B20单总线
void Delay1us(void) //@11.0592MHz
{
_nop_();
_nop_();
_nop_();
}
void Delay480us(void) //@11.0592MHz
{
unsigned char data i, j;
i = 6;
j = 38;
do
{
while (--j);
} while (--i);
}
void Delay240us(void) //@11.0592MHz
{
unsigned char data i, j;
_nop_();
_nop_();
i = 3;
j = 145;
do
{
while (--j);
} while (--i);
}
void Delay50us(void) //@11.0592MHz
{
unsigned char data i;
_nop_();
_nop_();
_nop_();
i = 135;
while (--i);
}
void DS_setup()//DLA,P11,DONE
{
P11=1;
DS = 1;
Delay1us();
DS = 0; //拉低电平
Delay480us();
Delay240us(); //480us-960us之间均可
DS = 1; //拉高电平
Delay50us(); //等待15us-60us
if(DS == 1) //如果未响应
{
DSFlag = 1; //DS18B20未响应 标志位置1
P10=1;
}
Delay240us();
P11=0;
}
void Delay5us(void) //@11.0592MHz
{
unsigned char data i;
_nop_();
i = 11;
while (--i);
}
void DS_WriteData(unsigned char com)//DLA,P12
{
uchar i;
P12=1;
for(i=0;i<8;i++)
{
DS=1;
Delay1us();
Delay1us();
DS= 0; //拉低电平//延时至少1us
Delay5us();
Delay1us();
Delay1us();
DS=com&0x01;
Delay50us(); //至少60us直到周期结束
Delay5us();
Delay5us();
DS= 1;
com=com>>1; //右移一位
}
P12=0;
}
/*DS18B20读数据函数*/
unsigned char DS_ReadData()//DLA,P13
{
unsigned char i,j;
unsigned char dat = 0; //接收数据
P13=1;
j=1;
for(i=0;i<8;i++)
{
bit x;
DS=1;
Delay1us();
Delay1us();
DS=0; //拉低电平至少1us
Delay1us();
Delay1us();
Delay1us();
Delay1us();
Delay1us();
Delay1us();
DS=1; //释放总线
Delay1us();
Delay1us();
Delay1us();
Delay1us();
x=DS;
Delay50us();
if(x==1) //如果是1
{
dat=dat+(j<<i);
}
}
tempdata=dat;
P13=0;
return dat;
}
void readTemperature()
{
DS_setup(); //初始化DS18B20
DS_WriteData(0xcc); //跳过ROM
DS_WriteData(0x44); //启动温度转换指令
//Delay800ms();//延时一段时间
DS_setup(); //每一次写命令都需要初始化
DS_WriteData(0xcc); //跳过ROM
DS_WriteData(0xbe); //读暂存器内容
tempLow =DS_ReadData(); //获取温度的第一个字节
tempHigh =DS_ReadData(); //获取温度的第二个字节
if(tempHigh>=128) //温度是负数
{
tempLow= ~tempLow+1;
tempHigh= ~tempHigh;
tempFlag = 1;
}
temp[0]=tempLow;
temp[1]=tempHigh;
e=temp[1]*256+temp[0];
}
void displayTemp()
{
int a,b,c,d ;
a=(int)(e*0.000625)%10;
b=(int)(e*0.00625)%10;
c=(int)(e*0.0625)%10;
d=(int)(e*0.625)%10;
TM1650_write_data(0x68,tab[a]);
TM1650_write_data(0x6a,tab[b]);
TM1650_write_data(0x6c,tab[c]|0x80);//强与0x80添加小数点
TM1650_write_data(0x6e,tab[d]);
if(a==0)
if(b==0)
if(c==0)
if(d==0)
{DSFlag=1;}
}
void Delay200ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 9;
j = 104;
k = 139;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
//void Delay200us(void) ;
P1=0x00;
P0M0=0xff;
P0M1=0Xff;
P2M0=0xff;
P2M1=0xff;
TM1650_Init();
TM1650_clear();
while(1)
{
//P00=1;
readTemperature();
// P00=0;
// P01=1
displayTemp();
Delay200ms();
P01=0;
Delay200ms();
P01=1;
}
}
2、iic通信驱动数码管的.H文件(IICHEAD.h)
#include "intrins.h" bit busy;
/***********初始化***********/
#ifndef _IICHEAD_H_
#define _IICHEAD_H_
void I2C_init()
{
P_SW2 = 0x80;//因为I2C的寄存器在扩展的SFR中(XFR外部RAM),所以使用前必须将P_SW2最高位EAXFR置1。
P1M1 = 0;
P1M0 = 0;
I2CCFG = 0xe0; //允许I2C,主机模式,等待时钟数16
I2CMSST = 0x00;//清空状态标志位
EA = 1;
}
/***********开始信号***********/
void Start()
{
busy = 1;
I2CMSCR = 0x81; //开启中断允许位,发送START命令
while (busy);
}
/***********发送一个字节数据***********/
void SendData(char dat)
{
I2CTXD = dat; //写数据到数据缓冲区
busy = 1;
I2CMSCR = 0x82; //发送SEND命令
while (busy);
}
/***********等待接收从机返回接收成功的信号***********/
void RecvACK()
{
busy = 1;
I2CMSCR = 0x83; //发送读ACK命令
while (busy);
}
/***********停止信号***********/
void Stop()
{
busy = 1;
I2CMSCR = 0x86; //发送STOP命令
while (busy);
}
/***********中断,清除标志位***********/
void I2C_Isr() interrupt 24
{
if (I2CMSST & 0x40)
{
I2CMSST &= ~0x40; //清中断标志
busy = 0;
}
}
#endif
3、获取温度计数值.H文件(TM1650.h)
#include <IICHEAD.h>
#include <stdio.h>
#include <stc8h.h>
#ifndef _TM1650_H_
#define _TM1650_H_
//typedef unsigned char uchar;
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
unsigned char tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
//================================================================
// 描述: TM1650写函数
// 参数: add:地址;dat:数据.
// 返回: none.
//================================================================
void TM1650_write_data(unsigned char add,unsigned char dat)
{
Start(); //开始信号
SendData(add); //发送显存地址(控制字)
RecvACK();
SendData(dat); //发送待显示数据(操作数)
RecvACK();
Stop(); //停止命令
}
//================================================================
// 描述: TM1650初始化
// 参数: none.
// 返回: none.
//================================================================
void TM1650_Init()
{
I2C_init();
TM1650_write_data(0x48,0x31); // 开显示、8段显示方式、3级亮度
}
//================================================================
// 描述: TM1650清除
// 参数: none.
// 返回: none.
//================================================================
void TM1650_clear()
{
unsigned char i;
for(i=0; i<4;i++)
{
TM1650_write_data(0x68+i*2,0);
}
}
#endif