📄 cewen529.c
字号:
//精确0.1
//Pd4 单总线
//PD765 液晶
#include<iom16v.h>
#include<macros.h>
#include<stdio.h>
#include"1602.h"
#define uchar unsigned char
#define uint unsigned int
#define OUT DDRD|=(1<<PD4) //PA7输出
#define IN DDRD&=~0X10 //PA7输入
#define DQ_SET PORTD|=(1<<PD4) //PA7拉高
#define DQ_CLE PORTD&=~(1<<PD4) //PA7拉低
#define SKIP_ROM 0xCC //跳过ROM
#define CONVERT_TEM 0x44 //转换温度
#define READ_RAM 0xBE //读暂存器
uchar dqbit,dqdata;//读暂存器位,字节
uint Height,Low;
uint w[1];
//延时1us,晶振8M
void delay_1us(uint m)
{
while(m)
{
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
m--;
}
}
//延时1ms,晶振8M
/*void delay_1ms(uint t)
{
uint i,j;
for(i=0;i<t;i++)
{
for(j=1;j<(8*143-2);j++)
{
;
}
}
}
*/
/*读18b20的DQ位*/
uchar DS18B20_DQ_DAT(void)//读出的位放在dqbit里,该位为1返回1,该位为0返回0
{
dqbit=PIND&0x10; //读PA7,其余位为0
if(dqbit==0x10) //PA7为1返回1
return 1;
else //PA7为0返回0
return 0;
}
//---------------------------------------------
//name:Ds18b20Reset
//description:复位ds18b20芯片进行初始化
//parameter: no
//---------------------------------------------
void Ds18b20Reset(void)
{
OUT; //PD7置为输出
DQ_CLE; //主机拉低总线,产生复位脉冲
delay_1us(410);//主机复位脉冲至少为400us
DQ_SET; //主机释放总线
IN; //PD7置为输入
delay_1us(20); //1820检测到总线上升沿后等待15-60us
while(DS18B20_DQ_DAT()); //等待1820发出应答脉冲
while(!DS18B20_DQ_DAT());//1820发出存在脉冲,持续60-240us
delay_1us(20); //20us
OUT; //PD7置为输出
DQ_SET; //主机释放总线
}
//---------------------------------------------
//name:Ds18b20Write
//description: 写一个字节
//parameter: dat 要写入的数据,无符号字符型
//---------------------------------------------
void Ds18b20Write(uchar data)//
{
uchar i;
for(i=0;i<8;i++)
{
DQ_CLE; //总线拉低
//写1
if(data&0x01)
{
delay_1us(2); //2us
DQ_SET; //写1
delay_1us(60); //60us,1820采样,释放总线,延时1us后开始写第二位
}
//写0
else
{
DQ_CLE; //写0
delay_1us(65); //65us,写入0,1820采样
DQ_SET; //电阻上拉,释放总线
delay_1us(1); //延时1us后开始写第二位
}
data = data>>1;
}
}
//---------------------------------------------
//name:Ds18b20ReadBit
//description: 读一个字节
//parameter: no
//---------------------------------------------
void Ds18b20ReadByte(void)
{
uchar i;
dqdata=0;
for(i=0;i<8;i++)
{
dqdata=dqdata>>1;
OUT; //PD7置为输出
DQ_CLE; //主机拉低总线
delay_1us(2); //延时2us
DQ_SET; //主机释放总线,接下来(15-2)us内读有效
IN; //PD7置为输入
delay_1us(2); //延时2个us后进行读
DS18B20_DQ_DAT(); //读DQ的数据位存放在dqbit的最高位
delay_1us(70); //60us后读完成
DQ_SET; //主机释放总线
if(dqbit) //把读入的数存入dqdata
dqdata=(dqdata|0x80);
}
}
//---------------------------------------------
//name:Ds18b20Convert
//description: 命令Ds18b20开始转换温度
//parameter: no
//---------------------------------------------
void Ds18b20Convert(void)
{
Ds18b20Reset();
delay_1ms(1);
Ds18b20Write(SKIP_ROM); //单接点可以跳过ROM
Ds18b20Write(CONVERT_TEM);
}
//---------------------------------------------
//name:Ds18b20ReadTem
//description: 从Ds18b20读取温度
//parameter: no
//---------------------------------------------
void Ds18b20ReadTem(void)
{
uchar j;
uint Temp,i;
Ds18b20Reset(); //初始化
delay_1ms(1);
Ds18b20Write(SKIP_ROM); //单接点可以跳过ROM
Ds18b20Write(READ_RAM); //读存储器
Ds18b20ReadByte();//0
Low =dqdata;
Ds18b20ReadByte();//1
Height =dqdata;
}
//------------------------------------------
//计算要输出的温度
//------------------------------------------
uint getwendu(void)
{
uchar flag;
float t_shiji;
uint k[3];
//读取温度
Ds18b20Convert();
delay_1ms(800);
Ds18b20ReadTem();//获得Height,Low
flag=Low&0x01;//获得2(-4)
t_shiji=0.0625*flag;
Low>>=1;
flag=Low&0x01;//2(-3)
t_shiji+=0.125*flag;
Low>>=1;
flag=Low&0x01;//2(-2)
t_shiji+=0.25*flag;
Low>>=1;
flag=Low&0x01;//2(-1)
t_shiji+=0.5*flag;
Low>>=1;
Height<<=4;
t_shiji=Low+Height+t_shiji;
t_shiji*=100;
k[0]=t_shiji/10;//十位,个位,小数点
return k[0];
}
//------------------------------
//显示温度
//------------------------------
void display(void)
{
uchar s[5];
sprintf(s,"%d",w[0]);
DisplayListChar(s,0);
delay_1ms(50);
}
//-----------------------------
//液晶初始化
//-----------------------------
void init(void)
{
DDRD|=(1<<PD7)|(1<<PD6)|(1<<PD5);
DDRC=0XFF;
delay_1ms(500);
Lcd_Ini();
delay_1ms(500);
}
void main(void)
{
init(); //液晶初始化
while(1)
{
w[0]=getwendu();//获取最后温度
display(); //显示最后温度
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -