打印
[STM8]

STM 8S 读写DS18B20时序问题

[复制链接]
1461|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 木子不二 于 2016-7-19 10:12 编辑

开始读出数据总是0xFF,或者其她乱码。 改了下现在死在初始化这里 ,下面是驱动代码,16M主时钟
#include"DS18B20.h"
char Neg_flag;
void Delay_us(unsigned int us)
{
    while(--us);
}

void DQ_OUT(void)
{
  PA_DDR_bit.DDR3 = 1;
  PA_CR1_bit.C13  = 1;   //推挽
  PA_CR2_bit.C23  = 1;
}
void DQ_IN(void)
{
  PA_DDR_bit.DDR3 = 0;
  PA_CR1_bit.C13  = 1;  //上拉
  PA_CR2_bit.C23  = 0;
}
/*******************************************************************************
* Function Name  : unsigned char Init_DS18B20(void)
* Description    : IO 初始化
* Input          : void
* Output         : None
* Return         : None
*******************************************************************************/
unsigned char Init_DS18B20(void)
{
  unsigned char tp;
  DQ_OUT();
  DQ_1;
  Delay_us(10);
  DQ_0;
  Delay_us(1200);            //复位脉冲 480us~ 960us
  DQ_IN();                                                                       卡死在这里                 
  Delay_us(60);             //等待15~60us
//  while(DQ_val==0);       //等待存在脉冲消失  
  if(DQ_val==1)            //判断初始化是否成功
    tp=1;                  //初始化成功
  else
    tp=0;
  Delay_us(300);
  DQ_0;
  return tp;
}
/*******************************************************************************
* Function Name  : void Write_DS18B20(unsigned char data)
* Description    : 向18B20写数据
* Input          : void
* Output         : None
* Return         : None
*******************************************************************************/
void Write_DS18B20(unsigned char data)
{
  unsigned char i;
  DQ_OUT();
  DQ_1;
  for(i=0;i<8;i++)
  {
    DQ_0;
    Delay_us(15);
    if(data&0x01)
      DQ_1;
    else
      DQ_0;
    data>>=1;
    Delay_us(100);
    DQ_OUT();
    DQ_1;
  }
}
/*******************************************************************************
* Function Name  : unsigned char Read_DS18B20(void);
* Description    : 读18B20数据
* Input          : void
* Output         : None
* Return         : 18B20数据
*******************************************************************************/
unsigned char Read_DS18B20(void)
{
  unsigned char i,rdata;
  DQ_OUT();
  for(i=0;i<8;i++)
  {
    DQ_0;
    Delay_us(1);    //写时序开始 1us
    DQ_IN();        //释放总线
    Delay_us(10);   //15us 读取数据
    if(DQ_val==1)
    rdata&=0x80;
    Delay_us(60);   //读时序最少60us
    rdata>>=1;
    DQ_OUT();
  }
  return rdata;
}
/*******************************************************************************
* Function Name  : void Convert_18B20(void);
* Description    : 18B20转换
* Input          : void
* Output         : None
* Return         : 转换数据
*******************************************************************************/
void Convert_18B20(void)
{
  unsigned char k;
  do
  k = Init_DS18B20();
  while(k);
  Delay_us(900);
  Write_DS18B20(0xcc);   //忽略 ROM
  Write_DS18B20(0x44);   //启动转换
  do
  k = Init_DS18B20();
  while(k);
  Delay_us(900);         //等待转换完毕
  Write_DS18B20(0x33);   //读取ROM
  Write_DS18B20(0xbe);   //读取暂存器
  tem[0] = Read_DS18B20();
  tem[1] = Read_DS18B20();
  Init_DS18B20();
}
/*******************************************************************************
* Function Name  : unsigned int Compute_18B20(unsigned char data);
* Description    : 计算18B20转换后的温度值
* Input          : 16进制的温度值
* Output         : None
* Return         : 十进制的温度值
*******************************************************************************/
unsigned int Compute_18B20(void)
{
  unsigned int temp,a,b;
  float temperature;
  a = tem[0];b= tem[1];
  a>>=4;
  b<<=4;
  temp = a|b;

//  temp = b;
//  temp <<= 8;             //two byte  compose a int variable
//  temp = temp | a;
  temperature = temp * 0.0625;
  temperature = temperature * 10 + 0.5;
  return temp;
}用例程是可以的,
file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\247983663\QQ\WinTemp\RichOle\P@`GFZJ}NDY6U6AUKS2%}T8.png


沙发
kk118a| | 2016-7-19 10:06 | 只看该作者
硬件问题

使用特权

评论回复
板凳
木子不二|  楼主 | 2016-7-19 10:10 | 只看该作者

用例程可以的

使用特权

评论回复
地板
木子不二|  楼主 | 2016-7-19 11:09 | 只看该作者
刷刷到顶部

使用特权

评论回复
5
玄德| | 2016-7-19 11:45 | 只看该作者

DQ_IN只有三条设置语句,
怎么卡死的???




使用特权

评论回复
6
木子不二|  楼主 | 2016-7-19 12:02 | 只看该作者
玄德 发表于 2016-7-19 11:45
DQ_IN只有三条设置语句,
怎么卡死的???

单步就卡在哪里不动了

使用特权

评论回复
7
木子不二|  楼主 | 2016-7-19 17:29 | 只看该作者
现在改成 这样 ,读出的数据时0;
void DQ_IN(void)
{
  PA_DDR &= 0x11110111;
  PA_CR1_bit.C13  = 1;  //上拉
  PA_CR2_bit.C23  = 0;
}

使用特权

评论回复
8
mmuuss586| | 2016-7-19 19:31 | 只看该作者
用示波器记录下,和例程对比下,哪里的时序不一样

使用特权

评论回复
9
598330983| | 2016-7-19 23:52 | 只看该作者
例程为何可以,是不是你的时钟配置跟例程是不同的,导致了时序错乱

使用特权

评论回复
10
木子不二|  楼主 | 2016-7-20 10:34 | 只看该作者
598330983 发表于 2016-7-19 23:52
例程为何可以,是不是你的时钟配置跟例程是不同的,导致了时序错乱

刚示波器看了下延时,修改了下时序的延时的时间,可以读出数据了,但是好像读出数据不对, 0xF3 和0x17

使用特权

评论回复
11
木子不二|  楼主 | 2016-7-20 14:54 | 只看该作者
int main()
{
// unsigned int Temp;
  float Temp;
  asm("sim");              //关总中断
  CLK_CKDIVR = 0x00;       //内部时钟为1分频  时钟16M
  LED_Init();
  UART1_Init(9600);
//  Tim2_Init();
//  Init_DS18B20();
  asm("rim");              //开中断
  while(1)
  {
    Convert_18B20();
    Delay(500);
    Temp =Compute_18B20();

    printf("现在的温度: ");
    printf("Temp = ");
    printf(" %f\n",Temp);                       
   // printf("\n");  
    PC_ODR ^=0xC8;  //led
    Delay(60000);
    Delay(60000);
}
现在有温度数据了,为什么pringtf 打不出来float类型的数字呢

使用特权

评论回复
12
598330983| | 2016-7-22 07:11 | 只看该作者
你不如自己写个函数,因为你只能用printf打印到串口啊。

使用特权

评论回复
13
lulugl| | 2016-7-23 01:04 | 只看该作者
void Init_DS18B20(void)           //初始化DS18B20
{
    unsigned char i;
    i=DS18B20_Start();             //复位
    if(!i)                          //单总线上没有发现DS18B20则报警
    {
        Alarm_for_No_DS18B20();
        return;
    }
    DS18B20_SendU8 (SKIP_ROM);  //跳过rom匹配
    DS18B20_SendU8 (WRITE_RAM); //设置写模式
    DS18B20_SendU8 (0x64);        //设置温度上限100摄氏度
    DS18B20_SendU8 (0x8a);        //设置温度下线-10摄氏度
    DS18B20_SendU8 (0x7f);        //12bit(默认)
}

使用特权

评论回复
14
lulugl| | 2016-7-23 01:05 | 只看该作者
你看下我的初始化的函数吧
void Alarm_for_No_DS18B20(void)
{
    //单总线上没有发现DS18B20则报警,该动作据具体应用具体处理
}
//---------------------------------------------------------------------
unsigned char DS18B20_Start(void) //复位ds18b20芯片
{
    unsigned char i,succ=0xff;
    DS18B20_PIN_SET_OUT(); //置为输出口
    DS18B20_WR0() ;          //总线产生下降沿,初始化开始
    for(i=0; i<20; i++)Delay_us(25); //总线保持低电平在480 - 960微秒之间
    DS18B20_WR1();         //总线拉高
    DS18B20_PIN_SET_IN();  //置为输入,主机释放总线,准备接收DS18B20的应答脉冲
    i=0;
    while(R_DS18B20())         //等待DS18B20发出应答脉冲
    {
        Delay_us(5);
        if(++i>12)            //DS18B20检测到总线上升沿后等待15-60us
        {
            succ=0x00;           //如果等待大于约60us,报告复位失败
            break;
        }
    }
    i=0;
    while(!R_DS18B20())       //DS18B20发出存在脉冲,持续60-240us
    {
        Delay_us(5);
        if(++i>48)            //如果等带大于约240us,报告复位失败
        {
            succ=0x00;
            break;
        }
    }
    Delay_us(20);
    return succ;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

306

帖子

6

粉丝