标题:
DS18B20测温程序,大侠帮忙看看
[打印本页]
作者:
flexraybeginer
时间:
2010-8-12 21:51
标题:
DS18B20测温程序,大侠帮忙看看
程序一直调不出来,调的过程中结果不是全是F,就是全是0,哪位好心帮我看看吧~先谢过了!
#include <hidef.h> /* common defines and macros */
#include <mc9s12xf512.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xf512"
#include "Fr_UNIFIED_types.h"
uint16 TempeValue,TempeValdone;
boolean TempeReady = 0;
uint32 timech;
#define DQ 1
#define DQ_H PTP_PTP0 = 0 //设置P0.0口为输出
#define DQ_L PTP_PTP0 = 1 //设置P0.0口为输入
uint8 flag=0;
uint8 Temp=0;
uint8 tempH;
uint8 tempL;
uint8 f;
uint8 tmp;
uint8 tmp_t,COUNTER = 0;
void Delay(uint32 time) //3.75us
{
for(;time>0;time--);
}
//初始化作为输入口
void GPIO_Iint()
{
DDRP_DDRP0 = 0;
}
//初始化作为输出口
void GPIO_Oint()
{
DDRP_DDRP0 = 1;
}
// 函数功能:一线总线复位及从设备应答控制程序
void TxReset(void)
{
do{
int err = 5;
flag = 0;
GPIO_Oint();
DQ_H;
Delay(2); //延时5us
DQ_L; //置低,初始化开始
Delay(480); //延时722us
GPIO_Iint();
Delay(45); //延时60us以上
/*等待18B20发出存在脉冲--低电平*/
while((PTP_PTP0 == 1)||(err == 0)) {
err--;
Delay(12);
}
if(err == 0) flag = 0;
else flag = 1;
Delay(39); //60us
GPIO_Oint();
DQ_H;
Delay(79); //120us,总480us
Delay(79);
Delay(79);
Delay(79);
} while(flag == 0) ;
}
void WrByte(uint8 b)
{
uint8 i;
for(i=0;i<8;i++)
{
if(b&0x01)
{
GPIO_Oint();
/*先置高再置低,告诉18B20 写开始*/
DQ_H; //置高
Delay(2); //5us
DQ_L; //置低
Delay(5); //延时20us
DQ_H; //P0.0置高,写 1 开始
Delay(39); //延时10us
GPIO_Iint();
Delay(5); //保证写2位数据的间隙大于 1 us
}
else
{
GPIO_Oint();
DQ_H; //置高
Delay(2); //5us
DQ_L; //置低
Delay(45); //延时70us
DQ_H;
GPIO_Iint();
Delay(5); //保证写2位数据的间隙大于 1 us
}
b=b>>1;
}
}
//读数据的一位,满足读时隙要求读取
uint8 RdBit(void)
{
uint8 read_bit;
GPIO_Oint(); /*先置高再置低,告诉18B20 读开始*/
DQ_L;
Delay(2); //延时5us
GPIO_Iint();
Delay(5); //10us
if(PTP_PTP0)
read_bit=0x80;
else
read_bit=0;
GPIO_Oint(); //输出
DQ_H; //置高,释放总线
Delay(40);
return read_bit;
}
//读取数据的一个字节
uint8 RdByte(void)
{
uint8 i,Data=0;
for(i=0;i<8;i++)
{
Data=Data>>1;
Data=Data|RdBit();
}
return Data;
}
//启动一次DS18B20测温,并读取测温结果//得到完整的温度值(整数和小数)
uint8 get_temp_t(void)
{
uint8 i,j;
TxReset();
COUNTER++;
if(flag) //如果一线总线复位及从设备应答控制 成功 则向下执行
{
WrByte(0xCC); //跳过ROM
COUNTER++;
WrByte(0x44); //开始一次温度变换
COUNTER++;
Delay(480); //700us
COUNTER++;
TxReset(); //一线总线复位及从设备应答控制
COUNTER++;
WrByte(0xCC); //跳过ROM
COUNTER++;
WrByte(0xBE); //读暂存存储器
COUNTER++;
tempL=RdByte();
COUNTER++;
tempH=RdByte();
COUNTER++;
}
COUNTER = 0;
return(f);
}
void temperaturehandler(void) {
TempeReady = 1;
get_temp_t();
TempeValue = (uint16)tempH;
TempeValue = TempeValue << 8;
TempeValue = TempeValue + (uint16)tempL;
TempeValdone = TempeValue;
TempeReady = 0;
}
void main(void) {
/* put your own code here */
//EnableInterrupts;
PLLCTL_PLLON = 0; /* Disable the PLL */
SYNR_SYNDIV = 0x04; /* Set PLL synthesizer register to 4 */
REFDV_REFDIV = 0x00; /* Set PLL divider register to 0 */
/* Fvco = 2*OSCCLK*(SYNR+1)/(REFDV+1) = 8MHz* 5/1 = 40MHz */
/* -> VCOFRQ = 00b */
SYNR_VCOFRQ1 = 0;
SYNR_VCOFRQ0 = 0;
/* Fref = OSCCLK/(REFDV+1) = 4MHz/1 = 4MHz -> REFRQ= 01b */
REFDV_REFFRQ1 = 0;
REFDV_REFFRQ0 = 1;
PLLCTL_PLLON = 1; /* PLL enabled */
while(!CRGFLG_LOCK)
; /* Wait until the PLL is within the desired frequency */
CLKSEL_PLLSEL = 1; /* Select clock source from PLL */
GPIO_Oint();
for(;;) {
temperaturehandler();
} /* wait forever */
/* please make sure that you never leave this function */
}
作者:
hxcic
时间:
2010-8-13 09:44
沙发。 顶一个
作者:
chiusir
时间:
2010-8-20 13:00
这个对时序要求相当严格,所以参照芯片数据手册,准确把握时序即可,总线频率改变,时序需要重新调整。
作者:
flexraybeginer
时间:
2010-8-20 15:01
我又重新按照数据手册来过了,还是不行。读上来的数据一直是0
作者:
flexraybeginer
时间:
2010-8-20 15:16
DS18B20加上上拉电阻后就不能正常RESET,也就是说不能收到DS18B20发出的脉冲
作者:
bluehacker
时间:
2010-8-23 22:21
这种错误大多数是时序不对,延时庶非常精确,建议用示波器 检查
另外 就是看板子焊接有没有焊错
作者:
flexraybeginer
时间:
2010-8-24 09:59
板子的引脚我已经用固定延时的方式检验过,引脚没有拆错
传感器没有焊在板子上,是用杜邦线直接连的
作者:
flexraybeginer
时间:
2010-8-25 09:39
#include <hidef.h> /* common defines and macros */
#include <mc9s12xf512.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xf512"
#include "Fr_UNIFIED_types.h"
uint16 TempeValue,TempeValdone;
boolean TempeReady = 0;
uint32 timech;
#define Skip_ROM 0xCC
#define Write 0x4E
#define DQ 1
#define DQ_H PTP_PTP0 = 0 //设置P0.0口为输出
#define DQ_L PTP_PTP0 = 1 //设置P0.0口为输入
uint8 flag=0;
uint8 Temp=0;
uint8 tempH;
uint8 tempL;
uint8 f;
uint8 tmp = 0;
uint8 tmp_t,COUNTER = 0;
void Delay(unsigned int time)
{
PITCFLMT = 0x00; //关闭计时器
PITCE = 0x01; //使能通道1
PITMUX = 0x00; //使用宏时钟0
PITMTLD0 = 19; //宏时钟为1us
PITLD0 = time-1; //timeus
PITTF = 0x01; // 清时钟标志位
PITCFLMT = 0x80; //使能计时器
while(!(PITTF&0x01));
PITTF = 0x01;
PITCFLMT = 0x00;
}
void DelayMS(unsigned int time) //100ms
{
PITCFLMT = 0x00; //关闭计时器
PITCE = 0x01; //使能通道1
PITMUX = 0x00; //使用宏时钟0
PITMTLD0 = 199; //宏时钟为10us
PITLD0 = time*10000-1; //timeus
PITTF = 0x01; // 清时钟标志位
PITCFLMT = 0x80; //使能计时器
while(!(PITTF&0x01));
PITTF = 0x01;
PITCFLMT = 0x00;
}
//初始化作为输入口
void GPIO_Iint()
{
DDRP_DDRP0 = 0; //端口pp0设为输入,并拉高
PERP_PERP0 = 1;
PPSP_PPSP0 = 0;
}
//初始化作为输出口
void GPIO_Oint()
{
DDRP_DDRP0 = 1;
}
// 函数功能:一线总线复位及从设备应答控制程序
void TxReset(void)
{
do{
int err = 10;
flag = 0;
GPIO_Oint();
DQ_H;
Delay(10);
DQ_L; //置低,初始化开始
Delay(500); //延时500us
GPIO_Iint();
//Delay(60);
/*等待18B20发出存在脉冲--低电平*/
while((PTIP_PTIP0 == 1)&&(err != 0)) {
err--;
Delay(20);
}
COUNTER++;
if(err == 0) flag = 0;
else flag = 1;
//GPIO_Oint();
//DQ_H;
Delay(480);
} while(flag == 0) ;
}
现在改用定时器做了一下,还是不能初始化,收不到低电平脉冲
作者:
flexraybeginer
时间:
2010-8-25 16:50
#define DQ_H PTP_PTP0 = 0 //设置P0.0口为输出
#define DQ_L PTP_PTP0 = 1 //设置P0.0口为输入
原来是这里拉高,拉低写反了
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0