关于stc12c5a60s2单片机无法获取ds18b20温度的相关问题

  • Post author:
  • Post category:其他


前段时间动手做了一个关于ds18b20的小型项目(学校的电子设计大赛),自以为对ds18b20这个模块比较了解了。不过前几天因为专业课,要求在学校发的

最小系统板(基于stc12c5a60s2)

上实现某些功能,所以先对ds18b20这个模块进行了调试。

学校发的最小系统板(基于stc12c5a60s2)

参考了之前做ds18b20这个模块的keil代码,感觉差别不大,修改了lcd1602和onewire总线相关定义端口并进行了编译和烧录,但是发现lcd1602的显示内容异常。

异常显示

所以对之前的代码进行了检查,发现没有问题。后来请教了交流群的大佬发现,


stc12c5a60s2是增强型单片机,它是1T的


,而我的keil代码(包括网上大部分的例程)都是针对89系列单片机而写的,

传统51单片机内核是12T的(包括89系列在内)

T指的是

指令周期

与时钟周期的比例。

例如

传统51内核是12T的,每12个时钟周期构成一个指令周期。

那么问题就可以用一句话来概述了:

STC12C5A60S2是1T的芯片,运行速度比89C52快,延时函数需要进行调整。




DS18B20是一个对时序控制极其严苛的系统,所以延时控制非常重要!!时序顺序非常重要!!


清楚认识的以上事实后,针对于上述问题,理清思路:

1. 要解决精确延时问题;

2. 要搞清楚DS18B20交互方法;

3. 要搞清楚DS18B20时序结构;

注意:以下代码是在89系列单片机代码基础上做时序调整的。

1.ds18b20初始化操作:

2.ds18b20写操作:

3. ds18b20读操作:

因为作者的ds18b20模块代码是通过调用onewire单总线模块化写法,所以下面就在onewire.h文件里面进行修改

#include <8051.h>
#include <intrins.h>
#define uchar unsigned char
#define _nop_() __asm nop __endasm
//引脚定义
#define OneWire_DQ P1_1

/**
  * @brief  单总线初始化
  * @param  无
  * @retval 从机响应位,0为响应,1为未响应
  */
uchar OneWire_Init(void)
{
    uchar i;
    uchar AckBit;
    OneWire_DQ=1;
    OneWire_DQ=0;
    i = 247;while (--i);        //Delay 500us
    OneWire_DQ=1;
    i = 32;while (--i);            //Delay 70us
    AckBit=OneWire_DQ;
    i = 247;while (--i);        //Delay 500us
    return AckBit;
}

/**
  * @brief  单总线发送一位
  * @param  Bit 要发送的位
  * @retval 无
  */
void OneWire_SendBit(unsigned char Bit)
{
    uchar i;
    OneWire_DQ=0;
    i = 4;while (--i);            //Delay 10us
    OneWire_DQ=Bit;
    i = 24;while (--i);            //Delay 50us
    OneWire_DQ=1;
}

/**
  * @brief  单总线接收一位
  * @param  无
  * @retval 读取的位
  */
uchar OneWire_ReceiveBit(void)
{
    uchar i;
    uchar Bit;
    OneWire_DQ=0;
    i = 2;while (--i);            //Delay 5us
    OneWire_DQ=1;
    i = 2;while (--i);            //Delay 5us
    Bit=OneWire_DQ;
    i = 24;while (--i);            //Delay 50us
    return Bit;
}

/**
  * @brief  单总线发送一个字节
  * @param  Byte 要发送的字节
  * @retval 无
  */
void OneWire_SendByte(unsigned char Byte)
{
    uchar i;
    for(i=0;i<8;i++)
    {
        OneWire_SendBit(Byte&(0x01<<i));
    }
}

/**
  * @brief  单总线接收一个字节
  * @param  无
  * @retval 接收的一个字节
  */
uchar OneWire_ReceiveByte(void)
{
    uchar i;
    uchar Byte=0x00;
    for(i=0;i<8;i++)
    {
        if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}
    }
    return Byte;
}

原代码

修改后的代码

ds18b20模块主要的onewire.h文件里面用到delay函数,所以修改代码部分主要在onewire.h文件里面