谁有DS18B20的测试程序要ATMEGA16的

2019-07-18 11:56发布

谁有DS18B20的测试程序要ATMEGA16的。最好是用ICC写的,有PROTUES仿真最好。希望大家可以分享出来,我在网上找的不能用,大家都说是延时问题。搞了几天也没成功。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
武力戡乱
1楼-- · 2019-07-18 13:28
不是,是线与的问题!确定!AVR也好,430也好,lpc21也罢,都是强输出高,这个时候需要模拟线与。
z573509357
2楼-- · 2019-07-18 16:16
 精彩回答 2  元偷偷看……
z573509357
3楼-- · 2019-07-18 18:47
#include <iom16v.h>
#include <macros.h>
#include"18B20.h"
#define uchar unsigned char
#define uint unsigned int
//开发板上是对 PA5进行操作
#define DQ_IN DDRA&=~BIT(5)
#define DQ_OUT DDRA|=BIT(5)
#define DQ_SET PORTA|=BIT(5)
#define DQ_CLR PORTA&=~BIT(5)
#define DQ_R PINA&BIT(5)
//DS18B20初始化程序
uchar ds18b20_reset()
{
unsigned char errTime=0;//用于循环计数
DQ_OUT;//先设置成输出
DQ_CLR;//总线拉低
delay_nus(500);//保持500us(最小为480us,最大为960us)
DQ_SET;
DQ_IN;//1
_NOP();
//while(DQ_R)//探测 IO 引脚上是上升沿
//{
//delay_nus(1);//5.15us
//errTime++;
//if(errTime>10)
//return(0x00); //如果等待大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等
//待15-60us)
//}
errTime=0;
while(!(DQ_R))//注意(DQ_R)与 DQ_R 不同
{
delay_nus(1);//5.15us
errTime++;
if(errTime>40)
return(0x00); //如果等待大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等
//待60-240us)
}
return(0xff);
}
void ds18b20_write_byte(uchar value)//18B20写一个字节的程序
{
uchar i;
for(i=0;i<8;i++)//1个字节有8位,1位1位的传输
{
DQ_OUT;//先设置成输出
DQ_CLR;//总线拉低
delay_nus(3);//按照写1时序,在15us 中完成所以延时10us
if(value&0x01)//判断此时写入的值是1还是0
{
DQ_SET;//如果是1,总线拉高,使得18B20能采样
}
else DQ_CLR;
delay_nus(40);//如果是0(低电平)就不用管,继续延时(15+15+30=60us,100us 足够)
DQ_SET;//释放总线
value=value>>1;//每次传输完后移位
}
}
uint ds18b20_read_byte(void)//18B20读一个字节的程序
{
uint i,value,bi;
for(i=0;i<8;i++)
{
DQ_OUT;//先设置成输出
DQ_CLR;//总线拉低
delay_nus(3);//>1us,<15us 控制器读1时序
DQ_SET;//总线释放准备采样
DQ_IN;//采样,设置成输入
bi=DQ_R;
value=(value>>1)|(bi<<7);
delay_nus(30);//>45us
}
return value;
}
//读取温度值先读取暂存器的值在进行温度转换否则会意外出错
void  Ds18b20ChangTemp()
{
ds18b20_reset();//18B20复位
delay_1ms(void);
ds18b20_write_byte(0xcc);//对 ROM 进行操作,因为只接了1个器件所以写跳过指令
ds18b20_write_byte(0x44);//启动温度转换
delay_nms(100);
}
void  Ds18b20ReadTempCom()
{
ds18b20_reset();//18B20初始化
delay_1ms(void);
ds18b20_write_byte(0xcc);//跳过 ROM
ds18b20_write_byte(0xbe);//命令读取暂存器
}
int readTempDS18B20(void)
{
unsigned char tempL,tempH;
int temp=0;
//开始读取温度
ds18b20_reset();//18B20初始化
delay_1ms(void);
Ds18b20ChangTemp();
Ds18b20ReadTempCom();
tempL=ds18b20_read_byte();//从暂存器中读取数据
tempH=ds18b20_read_byte();//从暂存器中读取数据
temp=(tempH<<8)|tempL;//总值为高位*256+低位
temp=temp//为了保留1位小数,最小单位为0.0625
return(temp);
}
z573509357
4楼-- · 2019-07-19 00:42
z573509357 发表于 2015-7-9 09:46
什么意思啊?我程序贴出来你看下,拉低释放总线我都单独操作了。

#include <iom16v.h>
#include <macros.h>
#include"18B20.h"
#define uchar unsigned char
#define uint unsigned int
//开发板上是对 PA5进行操作
#define DQ_IN DDRA&=~BIT(5)
#define DQ_OUT DDRA|=BIT(5)
#define DQ_SET PORTA|=BIT(5)
#define DQ_CLR PORTA&=~BIT(5)
#define DQ_R PINA&BIT(5)
//DS18B20初始化程序
uchar ds18b20_reset()
{
unsigned char errTime=0;//用于循环计数
DQ_OUT;//先设置成输出
DQ_CLR;//总线拉低
delay_nus(500);//保持500us(最小为480us,最大为960us)
DQ_SET;
DQ_IN;//1
_NOP();
//while(DQ_R)//探测 IO 引脚上是上升沿
//{
//delay_nus(1);//5.15us
//errTime++;
//if(errTime>10)
//return(0x00); //如果等待大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等
//待15-60us)
//}
errTime=0;
while(!(DQ_R))//注意(DQ_R)与 DQ_R 不同
{
delay_nus(1);//5.15us
errTime++;
if(errTime>40)
return(0x00); //如果等待大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等
//待60-240us)
}
return(0xff);
}
void ds18b20_write_byte(uchar value)//18B20写一个字节的程序
{
uchar i;
for(i=0;i<8;i++)//1个字节有8位,1位1位的传输
{
DQ_OUT;//先设置成输出
DQ_CLR;//总线拉低
delay_nus(3);//按照写1时序,在15us 中完成所以延时10us
if(value&0x01)//判断此时写入的值是1还是0
{
DQ_SET;//如果是1,总线拉高,使得18B20能采样
}
else DQ_CLR;
delay_nus(40);//如果是0(低电平)就不用管,继续延时(15+15+30=60us,100us 足够)
DQ_SET;//释放总线
value=value>>1;//每次传输完后移位
}
}
uint ds18b20_read_byte(void)//18B20读一个字节的程序
{
uint i,value,bi;
for(i=0;i<8;i++)
{
DQ_OUT;//先设置成输出
DQ_CLR;//总线拉低
delay_nus(3);//>1us,<15us 控制器读1时序
DQ_SET;//总线释放准备采样
DQ_IN;//采样,设置成输入
bi=DQ_R;
value=(value>>1)|(bi<<7);
delay_nus(30);//>45us
}
return value;
}
//读取温度值先读取暂存器的值在进行温度转换否则会意外出错
void  Ds18b20ChangTemp()
{
ds18b20_reset();//18B20复位
delay_1ms(void);
ds18b20_write_byte(0xcc);//对 ROM 进行操作,因为只接了1个器件所以写跳过指令
ds18b20_write_byte(0x44);//启动温度转换
delay_nms(100);
}
void  Ds18b20ReadTempCom()
{
ds18b20_reset();//18B20初始化
delay_1ms(void);
ds18b20_write_byte(0xcc);//跳过 ROM
ds18b20_write_byte(0xbe);//命令读取暂存器
}
int readTempDS18B20(void)
{
unsigned char tempL,tempH;
int temp=0;
//开始读取温度
ds18b20_reset();//18B20初始化
delay_1ms(void);
Ds18b20ChangTemp();
Ds18b20ReadTempCom();
tempL=ds18b20_read_byte();//从暂存器中读取数据
tempH=ds18b20_read_byte();//从暂存器中读取数据
temp=(tempH<<8)|tempL;//总值为高位*256+低位
temp=temp//为了保留1位小数,最小单位为0.0625
return(temp);
}
武力戡乱
5楼-- · 2019-07-19 01:28
低,用正常的输出低。高,用输入(不要加内部上拉哦)!

一周热门 更多>