新手上路
- 积分
- 29
- 金钱
- 29
- 注册时间
- 2015-1-31
- 在线时间
- 0 小时
|
5金钱
硬件我用51测试过了没有问题。时序也照做了,也参考了别人的代码,但还是失败。我感觉问题出在IO口的配置上,推挽输出、上拉输出、浮空输入、上拉输入都试过,还是不成功。下面是我的代码,麻烦帮我看一下。我的延时函数是用定时器计数的,一个_delay_us()有15us。
uchar DS18B20_Rst()
{
uchar dat=1;
GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_SLOW);//推挽输出高电平,释放单总线
_delay_us(1); //稍做延时
GPIO_WriteLow(GPIOA, GPIO_PIN_6); //拉低单总线至少480μs来产生复位脉冲
_delay_us(40); //复位脉冲 //精确延时 大于 480us 小于960u
GPIO_WriteHigh(GPIOA, GPIO_PIN_6); //释放总线并进入接收模式
_delay_us(5);//需要等待15~60us,再发出存在脉冲:拉低总线60-240us
GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT); //上拉无中断输入
if (GPIO_ReadInputPin(GPIOA, GPIO_PIN_6)== SET)
dat = 1;
else
dat = 0;
_delay_us(15);
GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_SLOW);
//如果dat=0则初始化成功, dat=1则初始化失败
return dat;
}
/*
* 函数名 : DS18B20_ReadData
* 描述 : 从DS18B20读一字节数据
* 输入 : 无
* 输出 : uchar dat 读出的数据
* 调用 : 内部调用
*/
static uchar DS18B20_ReadData()
{
uchar i = 0;
uchar dat = 0;
for (i=0; i<8; i++)
{
GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_OD_LOW_SLOW); //拉低总线,产生读信号
_delay_us(1);
dat >>= 1;
GPIO_WriteHigh(GPIOA, GPIO_PIN_6); //释放总线,准备读数据
_delay_us(1); //延时几微秒读数据
GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT);
if( GPIO_ReadInputPin(GPIOA, GPIO_PIN_6) == SET )
dat |= 0x80;//读取数据
_delay_us(4); //延时 60us
GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_SLOW) //拉高总线,准备下一位数据的读取
_delay_us(1);
}
return dat;
}
/*
* 函数名 : DS18B20_WriteData
* 描述 : 写数据到DS18B20
* 输入 : uchar dat 要写入的数据
* 输出 : 无
* 调用 : 内部调用
*/
static void DS18B20_WriteData(uchar dat)
{
uchar i = 0;
for (i=0; i<8; i++)
{
GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_SLOW); //拉低总线,产生写信号
_delay_us(1);
if (dat&0x01)
GPIO_WriteHigh(GPIOA, GPIO_PIN_6);
else
GPIO_WriteLow(GPIOA, GPIO_PIN_6);
dat >>= 1;
_delay_us(4); //至少60μs
GPIO_WriteHigh(GPIOA, GPIO_PIN_6); //释放总线
_delay_us(1);
}
}
/*
* 函数名 : Get_Temp
* 描述 : 读DS18B20获取温度
* 输入 : 无
* 输出 : uint xdata temp 温度X100
* 调用 : 内部调用
*/
uint Get_Temper()
{
uint temp;
uchar TPH; //存放温度值的高字节
uchar TPL; //存放温度值的低字节
float f_temp; //存放实际温度
uchar tiu;
DS18B20_Rst(); //设备复位
DS18B20_WriteData(0xCC); //跳过ROM命令
DS18B20_WriteData(0x44); //开始转换命令
GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT);
if( GPIO_ReadInputPin(GPIOA, GPIO_PIN_6) == SET )
tiu = 1;
else
tiu = 0;
while (!tiu); //等待转换完成
DS18B20_Rst(); //设备复位
DS18B20_WriteData(0xCC); //跳过ROM命令
DS18B20_WriteData(0xBE); //读暂存存储器命令
TPL = DS18B20_ReadData(); //读温度低字节
TPH = DS18B20_ReadData(); //读温度高字节
temp = TPH; //将高字节和低字节合成一个十六位数
temp <<= 8;
temp |= TPL;
f_temp = temp * 0.0625; //计算实际温度
temp = f_temp * 10 + 0.5; //将浮点数转成整数,保留一位小数,四舍五入
return temp;
}
|
最佳答案
查看完整内容[请看2#楼]
这是一个关于STM8奇葩bug的帖子,参考下:
http://www.openedv.com/posts/list/0/37203.htm
如楼下所言,可能是delay的问题,用逻辑分析仪测下。
|