Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => ARM7 Mikrodenetleyici => Konuyu başlatan: Mucit23 - 19 Temmuz 2017, 14:31:18

Başlık: STM32F103 DS18B20 Kütüphanesi
Gönderen: Mucit23 - 19 Temmuz 2017, 14:31:18
Selamlar

STM32F103 ile DS18b20 Sıcaklık sensörünü çalıştırmak için uğraşıyorum. Adam akıllı bir onewire kütüphanesi bulamadım. Bende oturdum CCS'de kullandığım one wire protokollerini STM32F103'de çalışacak şekilde yeniden yazdım.

/******************************************************************************
*  @file    onewire.c
*  @author  Ferhat YOL
*  @version V1.0.0
*  @date    19-07-2017
*  @brief   OneWire Haberlesme kütüphanesi
******************************************************************************/     
#include <onewire.h>
#include <systick.h>

GPIO_InitTypeDef GPIO_InitStruct;

/*******************************************************************************
*   OneWire_Init                                                               *
*   Parametreler:                                                              *
*   Return:                                                                    *
*******************************************************************************/
void OneWire_Init(void)
{
RCC_APB2PeriphClockCmd(OneWireRCC, ENABLE);

   GPIO_InitStruct.GPIO_Pin = OneWirePin;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
   GPIO_Init(OneWireGpio, &GPIO_InitStruct);
}

/*******************************************************************************
*   OneWire_DIR                                                                *
*   Parametreler: dir                                                          *
*   Return:                                                                    *
*******************************************************************************/
void OneWire_DIR(uint8_t dir)
{
   GPIO_InitStruct.GPIO_Pin = OneWirePin;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

if(dir)
{
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
}
else
{
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
}

   GPIO_Init(OneWireGpio, &GPIO_InitStruct);    
}

/*******************************************************************************
*   OneWire_Reset                                                              *
*   Parametreler:                                                              *
*   Return:                                                                    *
*******************************************************************************/
void OneWire_Reset(void)
{
OneWire_DIR(OUT); 
GPIO_ResetBits(OneWireGpio,OneWirePin);
  delay_us(500);
OneWire_DIR(IN);
delay_us(500);
OneWire_DIR(OUT);

}

/*******************************************************************************
*   OneWire_Write                                                              *
*   Parametreler: data                                                             *
*   Return:                                                                    *
*******************************************************************************/
void OneWire_Write(uint8_t data)
{
    unsigned char i;
    for (i=0; i<8; i++)
    {
  OneWire_DIR(OUT);
        GPIO_ResetBits(OneWireGpio,OneWirePin);
  delay_us(2);
  if((data>>i) & 0x01)
{
   GPIO_SetBits(OneWireGpio,OneWirePin);
}
else
{
   GPIO_ResetBits(OneWireGpio,OneWirePin);    
}
delay_us(60);
OneWire_DIR(IN);
delay_us(2);
    }
}

/*******************************************************************************
*   OneWire_Read                                                               *
*   Parametreler:                                                              *
*   Return: data                                                               *
*******************************************************************************/
unsigned char OneWire_Read(void)
{
    unsigned char i;
    unsigned char data, bitshifter;
    data = 0;
    bitshifter = 1;
    for (i=0; i<8; i++)
    {
        OneWire_DIR(OUT);
        GPIO_ResetBits(OneWireGpio,OneWirePin);
        delay_us(6);
        OneWire_DIR(IN);
        delay_us(4);
        if (GPIO_ReadInputDataBit(OneWireGpio,OneWirePin))
{
            data |= bitshifter;
}
        delay_us(50);
        bitshifter = bitshifter<<1;
    }
    return data;
}


Haberleşmeyi bir türlü düzgün yapamadım. Sürekli yanlış veri alıyorum(0xFF) Arada sırada düzgün bir şekilde Sıcaklık bilgisini okuduğumda oluyor. Ama genellikle hatalı çalışıyor.

Sıcaklık okumak için Aşağıdaki rutinleri kullanıyorum
/*******************************************************************************
*   Ds18B20_Read                                                               *
*   Parametreler:                                                              *
*   Return:                                                                    *
*******************************************************************************/
float Ds18B20_Read(void)
{
    int busy;
    int sayi1;
    int sayi2;
    float result;

    OneWire_Reset();
    OneWire_Write(0xCC);
    OneWire_Write(0x44);

    while(busy==0)
    busy=OneWire_Read();

    OneWire_Reset();
    OneWire_Write(0xCC);
    OneWire_Write(0xBE);
    sayi1 = OneWire_Read();
    sayi2 = OneWire_Read();

    result=sayi2*256+sayi1;

    result=result/16.0;

    delay_ms(250);
    return result;
}


Ben ya süreleri tutturamıyorum yada başka bir hata yapıyorum anlamış değilim. Elinde düzgün çalışan bir kütüphane olan varmı?
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Erol YILMAZ - 19 Temmuz 2017, 14:37:00
ONE WIRE'ı  bi donanım ile okumak pek mümkün görünmüyor, Bu açıdan biraz problemli...
UART ile birşeyler yapıyorlar ama iyi incelemek lazım.



Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Mucit23 - 19 Temmuz 2017, 14:45:15
Hocam donanım ile yapmaya çalışmıyorum, Gerek yok buna. Bana Software OneWire Kütüphanesi gerekiyor. Kullanan varmı daha önce?
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: M_B - 19 Temmuz 2017, 15:28:34
@Mucit23 hocam bir ara STM32F407 de test etmiş ve calıştırmıstım.
Umarım işinize yarar.

ds18b20.h

#ifndef __DS18B20_H_
#define __DS18B20_H_
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/

#define DQ_PIN                        GPIO_Pin_11  
#define DQ_GPIO_PORT                   GPIOC
#define DQ_GPIO_CLK                    RCC_AHB1Periph_GPIOC 



#define DQ_PIN_WRITE(x) ((x) ? (GPIO_SetBits(DQ_GPIO_PORT,DQ_PIN))  : (GPIO_ResetBits(DQ_GPIO_PORT,DQ_PIN)) );
#define DQ_PIN_READ ((GPIO_ReadInputDataBit(DQ_GPIO_PORT,DQ_PIN))&0x01)

extern void onewire_reset(void);
extern void onewire_write(char data);
extern unsigned char onewire_read( void );
extern float ds18b20_read(void);

#endif


ds18b20.c

#ifndef __DS18B20_C_
#define __DS18B20_C_

#include "stm32f4xx.h"
#include "ds18b20.h"
#include "stdio.h"
#include <string.h>



#define in  1
#define out 0

GPIO_InitTypeDef GPIO_InitStructure;



void DelayUs(u32 t)
{
t*=6; // 32 Mhz DelayUs
while(t--);
}



/******************************************************************************
*******************************************************************************/

/*
void init_port (void)
{


  GPIO_InitStructure.GPIO_Pin = RES_PIN | SCE_PIN | DC_PIN |SDIN_PIN |SCLK_PIN ; Ok
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
}
*/

/***********************************************************************************
***********************************************************************************/

void TRIS_PIN(char x)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    GPIO_InitStructure.GPIO_Pin = DQ_PIN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;


if(!x)
  {
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(DQ_GPIO, &GPIO_InitStructure);
}
else
  {GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IN ;}
  GPIO_Init(DQ_GPIO, &GPIO_InitStructure);
}



void onewire_reset(void)
{
    TRIS_PIN(out);
    DQ_PIN_WRITE(0)
    DelayUs(480);
    TRIS_PIN(in);
    DelayUs(400);
    TRIS_PIN(out);
}

void onewire_write(char data)
{
    unsigned char i, bitshifter;
    bitshifter = 1;
    for (i=0; i<8; i++)
    {
        if (data & bitshifter)
        {
            TRIS_PIN(out);
            DQ_PIN_WRITE(0)
            DelayUs(3);
            TRIS_PIN(in);
            DelayUs(60);
        }
        else
        {
            TRIS_PIN(out);
            DQ_PIN_WRITE(0)
            DelayUs(60);
            TRIS_PIN(in);
        }
bitshifter = bitshifter<<1;
    }
}

unsigned char onewire_read( void )
{
    unsigned char i;
    unsigned char data, bitshifter;
    data = 0; bitshifter = 1;
    for (i=0; i<8; i++)
    {
        TRIS_PIN(out);
        DQ_PIN_WRITE(0)
        DelayUs(6);
        TRIS_PIN(in);
        DelayUs(4);
        if (DQ_PIN_READ)
            data |= bitshifter;
        DelayUs(50);
        bitshifter = bitshifter<<1;
    }
    return data;
}

float ds18b20_read(void)
{
    int busy,sayi1,sayi2;
    float result;
    onewire_reset();
    onewire_write(0xCC);
    onewire_write(0x44);

    while(busy==0)
        busy=onewire_read();

    onewire_reset();
    onewire_write(0xCC);
    onewire_write(0xBE);
    sayi1 = onewire_read();
    sayi2 = onewire_read();

    result=sayi2*256+sayi1;
    result=result/16.0;   

    DelayMs(250);
    return result;
}

//----------------------------------------------------------------------------//
#endif

Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Okan AKÇA - 19 Temmuz 2017, 17:06:36
Ccs nin yada micro c ninkinler gayet guzel çalışıyor
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: MrDarK - 19 Temmuz 2017, 17:46:21
CCS'de çalıştırdığım kodu STM'ye almak için Logic Analyser ile sürelere ve gidip gelen datalara göre bir delay çevrimi yapmıştım. O şekilde çalıştırdım. Mucit hocam bence ccs'deki koddan bu şekilde yürüyün derim :)

Hatta sürelere proteus'un osilaskobunu kullanarak bakmıştım.
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: RaMu - 20 Temmuz 2017, 03:38:23
Şöyle dener misin:




void OneWire_Write(uint8_t data)
{
    unsigned char i;
    for (i=0; i<8; i++)
    {
  OneWire_DIR(OUT);
        GPIO_ResetBits(OneWireGpio,OneWirePin);
  delay_us(2);
  if((data>>i) & 0x01)
{
           delay_us(60);
OneWire_DIR(IN);
}
else
{


   delay_us(2);
OneWire_DIR(IN);    
}

    }
}


Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Mucit23 - 20 Temmuz 2017, 11:55:16
@RaMu yok o şekilde sürekli 4095 verisi geliyor. Benim ilk yaptığım kodlarda 500 msn aralıklarla okuma yapıyorum. 1 kere düzgün sonuç geliyorsa diğerinde 4095 okuyorum. Sonrasında yine düzgün sıcaklık değeri geliyor.

@M_B F4 için verdiğin kütüphanenin GPIO komutlarını F1 de çalışacak şekilde düzenledim fakat sorun aynı.

Ben F1 de gecikme işlemleri için SysTick kullanıyorum. 50uS gecikme verdiğim yerlerde yaklaşık 52US lik bir gecikme yapıyor. Değerler hemen hemen doğru.

Aşağıda data hattına ait lojik analyser çıktısını ekledim
(https://s22.postimg.cc/v7ca53p4x/Ekran_Al_nt_s.jpg)
1 Kere düzgün okuma yapılıyorsa diğerinde uzunca boş bir veri geliyor.
Buda düzgün okumanın yapıldığı kısım.
(https://s9.postimg.cc/76vebu6xr/Ekran_Al_nt_s_2.jpg)

Sorun nedir anlamıyorum.
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: kantirici - 20 Temmuz 2017, 12:01:30
OneWire protokolü süreye karşı oldukça hassas. Muhtemelen bundan kaynaklı bir sıkıntı mevcut. us gecikme için systick yerine for ile dummy sayaç yapıp osilaskoptan hassasiyetini ayarlamak daha iyi sonuç verecektir.



void delay_us(uint32_t us)
{
  IO1 = 1;
   for(uint32_t i = 0; i < us*CARPAN;i++);
  IO1 = 0;
}
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: skara1214 - 20 Temmuz 2017, 12:34:44
 one shot timeri da delay olarak kullanabilirsin
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Mucit23 - 20 Temmuz 2017, 12:50:36
Biraz sanayi işi oldu ama deneme yanılma ile doğru gecikmeleri buldum. Aslında okuma fonksiyonu hatalıymış. Dumy Gecikme fonksiyonu ile doğru değerleri bulmak daha zor.  Okuma ve yazma ile ilgili ince bir ayar çeksem daha stabil olacak. Logic analyser ile bakmam lazım.

Şuan çalışıyor fakat sprintf ile ilgili bir sorun var anlamadım.

     sicaklik=Ds18B20_Read();
     sprintf(text,"%f",sicaklik); Bu şekilde text'e atınca sorun yok örneğin 30.22345453 şeklinde yazıyor
Fakat
     sprintf(text,"%2.1f",sicaklik); Bu şekilde yazınca ekranda 4095.9 gibi sabit bir değer görüyorum. Sıcaklık okuma fonksiyonlarım aynı. Bu neden olur? 
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Mucit23 - 20 Temmuz 2017, 17:11:56
Şuan Oldukça saçma çalışıyor. Anlamıyorum. Gecikmeleri birebir logic analyser ile ölçüyorum. Doğru olduğunu söyleyebilirim. Fakat problem yaşanıyor.

Özellikle şu sprintf kullanımında niye sorun yaşanıyor bunu hiç anlamıyorum. Sprintf ile ne alakası var yahu!!
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: vitruvius - 20 Temmuz 2017, 17:24:32
"sicaklik" ve "text" değerlerin ne iki durumda da?
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: MC_Skywalker - 20 Temmuz 2017, 17:33:10
sprintf(lcd_buff,"Volt:%.2f", OrtalamaX ) şeklinde denermsin. I2C OLED ile ADC den gelen float veriyi gösteriken benim başıma benzeri gelmişti.
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: baran123 - 20 Temmuz 2017, 19:04:45
Embitz de sprintf ile float basmaya çalışırsan problem yaşıyorsunç Şu ayarı yapman gerekli

"sprintf ve float ı aynı anda kullanamıyoruz. sebebini araştırıyorum.
Ekleme
1. proje başlangıcında heap ve stack alanını belirle (default olarak heap 0x00 geliyor)
2.projede builtoption-compiler setting-other option a -u _printf_float ı ekle."

Yani şöyle
(https://i.hizliresim.com/G0ZlmN.png)

@muhittin_kaplan  hocadan alıntıdır. :)

Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: mehmet - 20 Temmuz 2017, 19:14:01
12-bit okuma yapıyorsak en az 750mS beklemeliyiz.

  (http://www.zimagez.com/miniature/ekrangrnts2017-07-2019-13-12.php)
(http://www.zimagez.com/zimage/ekrangrnts2017-07-2019-13-12.php)
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Mucit23 - 20 Temmuz 2017, 21:09:29
Su sprintfdeki sorun aslında psoc larda da başıma gelmişti. Orada heap degerini değiştirmiştim. Yarin keil içinde aynı düzenlemeyi araştıracağım.

Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Okan AKÇA - 20 Temmuz 2017, 21:48:12
Standart olarak 12bit ayarli istersek değiştirebiliriz. Ancak bu sensörü kesinlikle tercih etmem.
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Mucit23 - 21 Temmuz 2017, 10:38:31
Alıntı yapılan: Okan AKÇA - 20 Temmuz 2017, 21:48:12
Standart olarak 12bit ayarli istersek değiştirebiliriz. Ancak bu sensörü kesinlikle tercih etmem.

Hocam Tam olarak anlayamadım demek istediğinizi. Biraz daha açıklayabilirmisiniz? Heap değerini nasıl görüntülerim keil'de? Siz hangi sensörü tercih ederdiniz?
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: RaMu - 21 Temmuz 2017, 14:38:21
Bende 12 bit olayını söyleyecektim;


DS18B20 çözünürlük ayarı var,
8-12 bit arası seçilebiliyordu herhalde,
çözünürlük yükseldikçe
ds18b20 nin sıcaklığı ölçüp-hesaplayıp
sana gönderme süresi uzuyor.
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: Mucit23 - 21 Temmuz 2017, 14:50:49
Anladım Arkadaşlar. Fakat benim sorunum anladığım kadarıyla aynı anda Timer Kesmesi kullanmamdan kaynaklanıyor. Timer 1ms aralıklarla kesme oluşuyor ve kesme içerisinde 225uS civarı bekleme yapmam gerekiyor.


Eğerki OneWire protokolleri işletilirken herhangi bir bekleme sırasında kesme gelirse haberleşme sekteye uğruyor anladığım kadarıyla. Nasıl çözerim bilmiyorum ama kesme birinci öncelikte.
Başlık: Ynt: STM32F103 DS18B20 Kütüphanesi
Gönderen: RaMu - 21 Temmuz 2017, 15:10:14
1 wire mikrosaniye beklemeleri öncesinde
kesme geldimi biti kur,
kesme içinde bu biti işaretle,
1 wire mikrosaniye beklemesi esnasında
kesme gelmiş ve kesmede 225 us beklenmiş mi diye kontol et,
gelmişse one wire a RESET komutunu gönder,
işleri yeniden başlat,


diyeceğim ama bu durumda DS18B20 ile
konuşama fırsatın bile kalmayabilir belki.


Belki problem öyle değildir.