打印
[STM32F0]

stm30f051如何采集ds18b20的温度

[复制链接]
1631|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
240011814|  楼主 | 2016-7-5 18:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如题,用之前stm32f103的程序移植到f051就不行了,怀疑是延时出问题了,stm32f051如何延时1us
沙发
mmuuss586| | 2016-7-5 20:13 | 只看该作者
主频不一样吧,延时时间改短些

使用特权

评论回复
板凳
240011814|  楼主 | 2016-7-7 10:40 | 只看该作者
#ifndef  _delay_h
#define  _delay_h
#include "stm32f1xx_hal.h"
#define  SYSCLK        72   
#define  A             6           //循环耗费cpu周期
#define  B             3           // 初始化周期
void delay_us(uint32_t) ;
void delay_ms(uint32_t) ;
void delay_s(uint32_t) ;
#endif

#include "delay.h"

void wait(unsigned long n)
{
                do{
         n--;
      }while(n);
}

void delay_us(uint32_t nus)  
{
        wait(((nus)*(SYSCLK)-(B))/(A));
}       

void delay_ms(uint32_t nms)
{
         delay_us((nms)*1000);
}
void delay_s(uint32_t ns)
{
                delay_ms((ns)*1000);
}
用的这个延时

使用特权

评论回复
地板
bitofnoone| | 2016-7-7 15:27 | 只看该作者
时序上面能完全对应上吗?都是用IO模拟的吗

使用特权

评论回复
5
fly1974| | 2016-7-7 16:45 | 只看该作者
stm32F051的,试试看有用不:

#define  _NOP() asm("nop");
#define  BSRR_PB10Val  0x0400
#define  BSRR_PB11Val  0x0800
#define  BSRR_PA2Val   0x0004

#define  SetDir_PortSensorA_IN()        GPIOA->MODER &= ~(GPIO_MODER_MODER2)
#define  SetDir_PortSensorA_Out()       GPIOA->MODER |= (GPIO_MODER_MODER2_0);
#define  SA_DQ1  GPIOA->BSRR = BSRR_PA2Val
#define  SA_DQ0  GPIOA->BRR = BSRR_PA2Val
#define  Status_SensorAPort  GPIOA->IDR&BSRR_PA2Val

typedef  struct
  {
          unsigned long  CntTOK;
          unsigned long  CntTNG;
          unsigned long  CntInitNG;
    uint16_t CurT;          //读取的当前温度,形式为0xXXXX,前三个数字XXX表示当前温度,最后一个X为小于1度的部分(十进制0~9)
    uint16_t LastT;            
    uint16_t EverT;         //?           
    uchar    BoxTPol;       //温度正负判断辅助变量
    uchar    LastTPol;  
    uchar    EverTPol;
    uchar    Error;       //传感器出错次数,用来控制干扰滤除        
    uchar    Buf18B20A[9];        
  }  sSensor;
sSensor DS18B20A;

const uchar CrcTable[256]=
{0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};

//读取温度传感器信号线输入信号,1为高电平,0为低电平
static uchar GetStatus_SnrPort(void)
{
          if((Status_SensorAPort)!=0) return(1); else return(0);
}

//短延时使用,为uS量级
void delay_us(uint DlyInt32)   //近似4.74/uS
{
   DlyInt32+=(DlyInt32<<1);
     while(DlyInt32--);
}

//CRC校验,查表法
uchar CRC_OK1(uchar *p1,uchar num)
{
    uchar OutData1;
    uchar countbyte1;
                 OutData1=0;
                 num++;
         for(countbyte1=1;countbyte1<num;countbyte1++)
          {
             OutData1=CrcTable[OutData1^*p1];
                  p1++;
          }
        p1-=(num-1);
   return(OutData1);
}

/*
//8字节CRC校验,运算法
static uchar CRC_OK(uchar *p)
{
    uchar OutData,InData;
    uchar countbyte,bitlen;
         uchar crctem1,crctem2;
         OutData=0;
         for(countbyte=1;countbyte<10;countbyte++)
          {
             InData=*p;
                  for(bitlen=1;bitlen<9;bitlen++)
                  {
          crctem1=OutData;
          crctem2=crctem1^InData;
                    crctem2&=0x01;
          OutData>>=1;
                    if(crctem2)
                {
                         OutData+=0x80;
             OutData^=0x0c;
           }
                    InData>>=1;
                        }
                        p++;
          }
  return(!OutData);
}
*/
//往DS18B20中写一个字节
static void Write_18B20(unsigned char n)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;     //关systick中断
        SetDir_PortSensorA_Out();
        SA_DQ0;    delay_us(7);       //==延时0us---25us===
        if((n&0X01)==0X01)
        {
          SetDir_PortSensorA_IN();
          if(ParSeting==0) SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;    //开systick中断   
          delay_us(100);        //64us delay_us(192)
        }
        else
        {
          if(ParSeting==0) SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;    //开systick中断
          delay_us(100);         //60uS delay_us(160);
          SetDir_PortSensorA_IN();  
          delay_us(16);          //10uS delay_us(32);
        }
        n=n>>1;
    }
}

//从DS18B20读取一个字节
static unsigned char Read_18B20(void)
{
    unsigned char i;
    unsigned char temp;
    for(i=0;i<8;i++)
    {
        temp=temp>>1;
        SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;     //关systick中断   
        SetDir_PortSensorA_Out();
        SA_DQ0;    delay_us(2);  //==延时0us---4us===               
        SetDir_PortSensorA_IN();   delay_us(1);                //==延时0us---25us===
        if((Status_SensorAPort)==0)
        {
            temp=temp&0x7F;
        }else
        {
            temp=temp|0x80;
        }
        SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;      //开systick中断
        delay_us(90);          //==延时55us===
    }
    return    temp;
}

//18B20总线初始化
uchar Init(void)
{
  static uchar Step=0xff,PhaseTInit=0xff;
  switch(Step)
   {
      case 0xff:   {   SetDir_PortSensorA_Out();   SA_DQ0;   Step=0;   PhaseTInit=0;//PhaseTInit=480*SweepFreq/1000000;  
                   }   break;       // 低电平480uS
      case    0:   {   if(PhaseTInit==0)  Step=1;  else PhaseTInit--;  }          break;
      case    1:   {   
                       SetDir_PortSensorA_IN();
                       delay_us(100);                                       //==延时70us
                       if(GetStatus_SnrPort()!=0)  
                         {  if(DS18B20A.Error<16) DS18B20A.Error++;   DS18B20A.CntInitNG+=2;    }
                               else  {   if(DS18B20A.CntInitNG>0)   DS18B20A.CntInitNG/=10;   }                 //传感器恢复正常后快速恢复
                       Step=2;    PhaseTInit=0; //PhaseTInit=410*SweepFreq/1000000;                                                   //410uS
                   }    break;        
      case    2:   {  if(PhaseTInit==0) {  Step=0xff;  return(0); }  else  PhaseTInit--;   }  break;         
      default  :   break;        
   }
return(0xff);   
}

//18B20跳过内部ROM匹配
uchar Skip(void)
{
          Write_18B20(0xcc);
    return(0);
}

//启动18B20温度转换
uchar Convert (void)
{
         Write_18B20(0x44);
   return(0);
}

//发送读取18B20寄存器指令
uchar ReadDo (void)
{
         Write_18B20(0xbe);
   return(0);
}

//设置DS18B20测温分辨率和转换时间
void SetPar18B20A(void)
{  
    ParSeting=1;
    Init();
    Write_18B20(0xCC); // 跳过读序号列号的操作
    Write_18B20(0x4E); // 设置参数寄存器
    Write_18B20(0x00); // TH
    Write_18B20(0x00); // TL
    Write_18B20(0x7F); // 设置参数寄存器  0x5F 11位  0x7F12位
    ParSeting=0;  
}

//传感器出错后返回100度,Error=16,传感器测得温度低于零下25度时返回100度,Error=0;
uchar ReadTemp (void)
{
    static uchar temp_low,temp_high;                     //错误设为char 类型时某些温度范围输出异常
    static uint  temperature,GetTCounter=0;
    static uchar ReadTStep=0xff;
    switch(ReadTStep)
    {
             case 0xff:  {   DS18B20A.Buf18B20A[0]=Read_18B20(); temp_low=DS18B20A.Buf18B20A[0];  ReadTStep=1; }    break;
             case    1:  {   DS18B20A.Buf18B20A[1]=Read_18B20(); temp_high=DS18B20A.Buf18B20A[1]; ReadTStep=2; }    break;
             case    2:  
             case    3:        
             case    4:
             case    5:
             case    6:                                                   
             case    7:
             case    8:  {  DS18B20A.Buf18B20A[ReadTStep]=Read_18B20();  ReadTStep++; }     break;
             case    9:  {
                        if(((uint)((uint)(temp_high*256)+temp_low)&0x8000)==0x8000)
                          { temperature=~((temp_high*256)+temp_low)+1;
                            DS18B20A.BoxTPol=1;  }
                        else
                          { temperature=(temp_high*256+temp_low);
                            DS18B20A.BoxTPol=0;  }
                                                                               
                        if(DS18B20A.Buf18B20A[4]==0xff)  temperature<<=3;      //DS18S20时测得的数据要左移三位
                        ReadTStep++;
                      }  break;
         case   10:   {
                        if((DS18B20A.Buf18B20A[5]!=0xff)||CRC_OK1(DS18B20A.Buf18B20A,9))
                        {   
                             if(DS18B20A.Error<10) DS18B20A.Error++;
                               else  {DS18B20A.CurT=0x7B0;  DS18B20A.BoxTPol=0;     } //123
                             DS18B20A.CntTNG++;
                        }
                        else
                        {
                             if(DS18B20A.Error>0)  DS18B20A.Error--;
                             DS18B20A.CntTOK++;
                             DS18B20A.CurT=temperature;
                             if(DS18B20A.CurT==1360)    //去除偶尔出现的85度(复位状态或传感器VCC脚接触不良)干扰,避免温控状态受干扰突变
                             {
                                DS18B20A.CurT=DS18B20A.LastT;
                             }
                             if(DS18B20A.BoxTPol==1)
                              {
                                if((DS18B20A.LastTPol==0)&&(DS18B20A.EverTPol==0))  { if(DS18B20A.CurT>50) { DS18B20A.CurT=DS18B20A.LastT; DS18B20A.BoxTPol=0; }   }  //去除突发干扰
                                else
                                 {
                                   if(DS18B20A.CurT<=400) {  DS18B20A.CurT=0; DS18B20A.BoxTPol=0;    }     //-25度-0度时强制读取值为0度
                                   else { DS18B20A.CurT=1952;  DS18B20A.BoxTPol=0;     }        //低于零下25度时置读取值为122度(强制关闭加热)
                                 }
                               }
                              if(DS18B20A.CurT<10)  DS18B20A.BoxTPol=0;
                              DS18B20A.EverT=DS18B20A.LastT;
                              DS18B20A.EverTPol=DS18B20A.LastTPol;
                              DS18B20A.LastT=DS18B20A.CurT;
                              DS18B20A.LastTPol=DS18B20A.BoxTPol;
                           }
                          ReadTStep=0xff;  GetTCounter++;  return(0);
                             }  break;
             default  :  break;       
    }
    return(0xff);
}

//=======================================================================================
//============获取DS18B20的温度值========================================================
//=======================================================================================
//===  MCU对DS18B20进行温度转换时,其操作必须满足以下过程:
//===  1- 每一次读写之前都要对DS18B20进行复位.
//===  2- 完成复位后发送一条ROM命令到DS18B20.
//===  3- 最后发送一条RAM命令到DS18B20.
void  GetT_SnrA(void)      //进23次完成一次温度读取
{
   static uchar GetTPhase=0xff;
   switch(GetTPhase)
    {
       case 0xff:  { if(Init()==0)          GetTPhase=0;     }  break;
       case 0:     { if(Skip()==0)          GetTPhase=1;     }  break;       
       case 1:     { if(Convert()==0)       GetTPhase=2;     }  break;
       case 2:     { if(Init()==0)          GetTPhase=3;     }  break;       
       case 3:     { if(Skip()==0)          GetTPhase=4;     }  break;       
       case 4:     { if(ReadDo()==0)        GetTPhase=5;     }  break;
       case 5:     {
                     if(ReadTemp()==0)  
                             {   
                              GetTPhase=0xff;
                         SCH_tasks_G[TaskID_ReadT].Suspended=SweepFreq/12;      //执行一次后挂起0.1秒等待唤醒
                      }
                   }  break;       
       default:      GetTPhase=0xff;    break;       
    }
}

使用特权

评论回复
6
240011814|  楼主 | 2016-7-9 14:34 | 只看该作者
放弃了,最后决定还是用内部的温度传感器

使用特权

评论回复
7
yklstudent| | 2016-7-9 18:58 | 只看该作者
用芯片内部定时器实现延时

使用特权

评论回复
8
Roderman_z| | 2016-7-9 20:40 | 只看该作者
可能在延时上面有问题,在一个,看看时序有没有问题

使用特权

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

本版积分规则

17

主题

70

帖子

3

粉丝