我用PIC24FJ64GA006作为MCU,控制ds18b20温度传感器
虽然mcu发送复位信号给ds18b20,有应答信号,即复位时成功的,但是读出来的温度都是0,不知道为什么? 我延时也调过了很多次了。
各位帮忙看下是为什么把
ds18b20先前已经测试时好的了,因为我在用51控制它是可以正常使用的,而且所有的延时我都是直接用数字示波器看的,所以延时也没有错!
代码如下:
#include <p24FJ64GA006.h>
#define DATA_CON TRISBbits.TRISB0
#define DATA_OUT LATBbits.LATB0
#define DATA_IN PORTBbits.RB0
unsigned char RESERED[100];
unsigned char temperature;
///////////////////////////////////////////////////////////////////////////
//函数功能:延时程序(毫秒级)
//入口参数:del(数值范围:16位整型)
//延时del ms
///////////////////////////////////////////////////////////////////////////
void Delay_Ms(unsigned int del)
{
unsigned int j;
while(del--)
for(j=0;j<1600;j++);
}
///////////////////////////////////////////////////////////////////////////
//函数功能:延时程序(微秒级)
//入口参数:del(数值范围:16位整型)
//延时时间最好是用示波器测试
//del=1,延时2.5us
//del=2,延时3.1us
//del=3,延时3.7us
//del=4,延时4.2us
//del=5,延时5us
//del=6,延时5.64us
///////////////////////////////////////////////////////////////////////////
void Delay_Us(unsigned int del)
{
while(del--) ;
}
void IO_Init()
{
AD1PCFGbits.PCFG0 = 1; //关闭RB0的模拟功能
}
unsigned char DS18b20_Init()
{
unsigned char temp_flag = 0x00;
DATA_CON = 0; //RB0为输出
DATA_OUT = 1; //准备复位
Delay_Us(30); //稍做延时,20.6us
Nop();
Nop();
DATA_OUT = 0; //单片机将总线拉低,产生复位信号
Delay_Us(1200); //精确延时 大于 480us,本次取750us
Nop();
Nop();
//DATA_OUT = 1; //拉高总线
DATA_CON = 1; //RB0为输入,单片机释放总线
Delay_Us(45); //30us
Nop();
Nop();
Delay_Us(45);
Nop();
Nop();
Delay_Us(45);
Nop();
Nop();
if(DATA_IN == 0)
temp_flag = 0x00;
else
temp_flag = 0x01; //稍做延时后 如果temp_flag = 0x00则初始化成功 temp_flag = 0x01则初始化失败
Delay_Us(500); //注意:ds18b20应答脉冲要持续60——240us本次取316us
Nop();
Nop();
if (temp_flag == 0x00)
{
return 1; //初始化成功
}
else
{
return 0; //初始化失败
}
}
//读一个字节
unsigned char Temp_Readbyte(void)
{
unsigned char i = 0;
unsigned char read_data = 0;
for (i = 8; i > 0; i --)
{
DATA_CON = 0; //RB0为输出
DATA_OUT = 0; // 给脉冲信号
read_data >>= 1;
//DATA_OUT = 1;
Delay_Us(18); //13.2us
DATA_CON = 1; //RB0为输入
if(DATA_IN)
read_data |= 0x80;
else
read_data &= 0x7f;
Delay_Us(75); //44us
}
return(read_data);
}
//写一个字节
void Temp_Writebyte(unsigned char write_data)
{
unsigned char i = 0;
for (i = 8; i > 0; i --)
{
DATA_CON = 0; //RB0为输出
DATA_OUT = 0; //给个脉冲
Delay_Us(12); //9.4us
if(write_data &0x01)
DATA_CON = 1; //将RB0口配置为输入,由上拉电阻使总线变为高电平
else
;
Delay_Us(22); //15.6us
Delay_Us(45); //30us
DATA_CON = 1; //由上拉电阻使总线为高电平
write_data >>= 1;
}
Delay_Us(60); //40us
}
//读取温度
unsigned char Read_Temperature(void)
{
unsigned char temp_l = 0;
unsigned char temp_h = 0;
unsigned char temp = 0;
unsigned char ds18b20_exist = 0;
unsigned char ds18b20_exist1 = 0;
ds18b20_exist = DS18b20_Init();
Nop();
Nop();
if(ds18b20_exist)
{
Temp_Writebyte(0xCC); // 跳过读序号列号的操作
Nop();
Nop();
Temp_Writebyte(0x44); // 启动温度转换
Nop();
Nop();
Delay_Ms(750);
Nop();
Nop();
ds18b20_exist1 = DS18b20_Init();
Nop();
Nop();
Temp_Writebyte(0xCC); //跳过读序号列号的操作
Nop();
Nop();
Temp_Writebyte(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
Nop();
Nop();
temp_l = Temp_Readbyte();
Nop();
Nop();
temp_h = Temp_Readbyte();
Nop();
Nop();
temp_h <<= 4;
temp_h += ((temp_l & 0xf0) >> 4);
temp = temp_h;
return(temp);
}
else
return 0;
}
int main()
{
//temperature = 0x80;
DATA_CON = 0;
IO_Init();
while(1)
{
temperature = Read_Temperature();
Nop();
Nop();
}
}
此帖出自
小平头技术问答
既然你的51的可以,你就可以拿两个时序一点一点的对别下来,怎么也能找出问题的。
一周热门 更多>