求救啊学stm8s的萌新要被ds18b20气哭了

本文分享了一段使用STM8S105C6T6开发板与DS18B20温度传感器进行交互的代码。详细介绍了如何通过PG0引脚实现温度读取,包括初始化程序、读写字节和读取温度等关键步骤。作者遇到了接线、微秒级延时或时序问题,寻求社区帮助。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面是我用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);
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值