下面是我用stm8s105c6t6开发板的程序,我的ds18b20的DQ端接着单片机的PG0,vdd和GND都是连单片机的,也接了上拉电阻,请问到底是接线的问题还是微秒级延时的问题还是时序的问题呀???求大佬拯救
#include <iostm8s105c6.h>
#include <stdio.h>
#define BAUD_RATE 9600 //波特率
#define F_MASTER 16000000 //主频率
#define DS18B20_DQ_OUT PG_DDR_DDR0 = 1 //输出
#define DS18B20_DQ_IN PG_DDR_DDR0 = 0 //输入
#define DS18B20_DQ_HIGH PG_ODR_ODR0 = 1 //拉高
#define DS18B20_DQ_LOW PG_ODR_ODR0 = 0 //拉低
#define DS18B20_DQ_PULL_UP PG_CR1_C10 = 1 //上拉
#define DS18B20_DQ_FLOATING PG_CR1_C10 = 0 //浮空
#define DS18B20_DQ_PUSH_PULL PG_CR1_C10 = 1 //推挽
#define DS18B20_DQ_OPEN_DRAIN PG_CR1_C10 = 0 //开漏
#define DS18B20_DQ_VALUE PG_IDR_IDR0 //DQ值
//串口配置
//数据位:8
//停止位:1
//校验位:None
void UART_Init(void)
{
UART2_CR2_TEN = 1;
UART2_CR2_REN = 1;
UART2_CR2_RIEN = 1;
UART2_BRR2 = ((unsigned char)((F_MASTER / BAUD_RATE) & 0x0F)) + (((unsigned char)((F_MASTER / BAUD_RATE) >> 8)) & 0xF0);
UART2_BRR1 = ((unsigned char)((F_MASTER / BAUD_RATE) >> 4));
}
void UART_TxByte(unsigned char _data)
{
while (UART2_SR_TXE == 0);
UART2_DR = _data;
}
int outchar(int c)
{
UART_TxByte(c);
return c;
}
void delay_us(unsigned int us)
{
us *= 3;
for (;us!= 0; us--);
}
void delay_ms(unsigned int i)
{
while(i--)
{
delay_us(1000);
}
}
unsigned char DS18B20_Init() //DS18B20初始化程序
{
unsigned char x;
DS18B20_DQ_OUT; //引脚切换到输出状态
DS18B20_DQ_HIGH; //拉高
delay_us(750); //延时480~900us
DS18B20_DQ_LOW; //将数据线从高拉低,要求保持480~960us
delay_us(750); //延时480~900us
DS18B20_DQ_HIGH; //释放数据线
DS18B20_DQ_IN; //引脚切换到输出状态
delay_us(40); //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
x = PG_IDR_IDR0; //保存引脚的电平状态
delay_us(500);
while(!PG_IDR_IDR0); //等待低电平结束,可用来判断是否连接正常
return x;
}
void DS18B20_WriteByte(unsigned char _data) //写字节程序
{
unsigned char mask;
DS18B20_DQ_OUT; //引脚切换到输出状态
for (mask=0x01;mask!=0;mask<<=1)
{
DS18B20_DQ_LOW; //引脚置低电平
delay_us(5); //延时1~15us
if((mask&_data))
DS18B20_DQ_HIGH;
else
DS18B20_DQ_LOW;
delay_us(75); //每个位维持约60us让温度传感器来读
DS18B20_DQ_HIGH; //释放数据线
}
}
unsigned int DS18B20_ReadByte() //读字节程序
{
unsigned char x = 0;
unsigned char mask,_data;
for (mask=0x01;mask!=0;mask<<=1)
{
DS18B20_DQ_OUT; //引脚切换到输出状态
DS18B20_DQ_LOW; //引脚置低电平
delay_us(5); //延时大于1us
DS18B20_DQ_HIGH; //引脚置高电平
DS18B20_DQ_IN; //引脚切换到输入状态
delay_us(5); //延时1~15us
x = DS18B20_DQ_VALUE; //保存引脚的电平状态
if(x)
_data |= mask;
else
_data |= ~mask;
delay_us(50);
}
return _data;
}
float DS18B20_ReadTemperature() //读温度程序
{
unsigned char temp = 0x00;
float t = 0;
DS18B20_Init(); //将DS18B20初始化
delay_us(500); //延时等待稳定
DS18B20_WriteByte(0xCC); // 跳过读序号列号的操作
DS18B20_WriteByte(0x44); // 启动温度转换
delay_us(500);
DS18B20_Init(); //将DS18B20初始化
delay_us(500);
DS18B20_WriteByte(0xCC); //跳过读序号列号的操作
DS18B20_WriteByte(0xBE); //读取温度寄存器,前两个分别是温度的低位和高位
// DS18B20_WriteByte(0xCC);
delay_us(500);
temp = DS18B20_ReadByte(); //先读低八位
t = (((temp & 0xF0) >> 4) + (temp & 0x0F) * 0.0625);
temp = DS18B20_ReadByte(); //再读高八位
t += ((temp & 0x0F) << 4);
return t;
}
int main(void)
{
CLK_SWCR_SWEN = 1;
CLK_SWR = 0xB4; //选择主时钟源
CLK_CKDIVR = 0x00; //1分频,16MHz
UART_Init();
printf("********* DS18B20 温度信号测试 *********\r\n");
printf("Build: %s %s\r\n", __DATE__, __TIME__);
asm("rim");
while(1)
{
delay_ms(1000); //每一秒打印一次数据
printf("%.4f \r\n",DS18B20_ReadTemperature());
}
}
#pragma vector = UART2_R_RXNE_vector
__interrupt void UART2_IRQHandler(void)
{
if (UART2_SR_RXNE == 1)
{
UART_TxByte(UART2_DR);
}
}